[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 197: 5 /***/ (() => { 6 7 /* (ignored) */ 8 9 /***/ }), 10 11 /***/ 271: 12 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 13 14 "use strict"; 15 16 17 let Container = __webpack_require__(683) 18 19 let LazyResult, Processor 20 21 class Document extends Container { 22 constructor(defaults) { 23 // type needs to be passed to super, otherwise child roots won't be normalized correctly 24 super({ type: 'document', ...defaults }) 25 26 if (!this.nodes) { 27 this.nodes = [] 28 } 29 } 30 31 toResult(opts = {}) { 32 let lazy = new LazyResult(new Processor(), this, opts) 33 34 return lazy.stringify() 35 } 36 } 37 38 Document.registerLazyResult = dependant => { 39 LazyResult = dependant 40 } 41 42 Document.registerProcessor = dependant => { 43 Processor = dependant 44 } 45 46 module.exports = Document 47 Document.default = Document 48 49 50 /***/ }), 51 52 /***/ 346: 53 /***/ ((module) => { 54 55 "use strict"; 56 57 58 const DEFAULT_RAW = { 59 after: '\n', 60 beforeClose: '\n', 61 beforeComment: '\n', 62 beforeDecl: '\n', 63 beforeOpen: ' ', 64 beforeRule: '\n', 65 colon: ': ', 66 commentLeft: ' ', 67 commentRight: ' ', 68 emptyBody: '', 69 indent: ' ', 70 semicolon: false 71 } 72 73 function capitalize(str) { 74 return str[0].toUpperCase() + str.slice(1) 75 } 76 77 class Stringifier { 78 constructor(builder) { 79 this.builder = builder 80 } 81 82 atrule(node, semicolon) { 83 let name = '@' + node.name 84 let params = node.params ? this.rawValue(node, 'params') : '' 85 86 if (typeof node.raws.afterName !== 'undefined') { 87 name += node.raws.afterName 88 } else if (params) { 89 name += ' ' 90 } 91 92 if (node.nodes) { 93 this.block(node, name + params) 94 } else { 95 let end = (node.raws.between || '') + (semicolon ? ';' : '') 96 this.builder(name + params + end, node) 97 } 98 } 99 100 beforeAfter(node, detect) { 101 let value 102 if (node.type === 'decl') { 103 value = this.raw(node, null, 'beforeDecl') 104 } else if (node.type === 'comment') { 105 value = this.raw(node, null, 'beforeComment') 106 } else if (detect === 'before') { 107 value = this.raw(node, null, 'beforeRule') 108 } else { 109 value = this.raw(node, null, 'beforeClose') 110 } 111 112 let buf = node.parent 113 let depth = 0 114 while (buf && buf.type !== 'root') { 115 depth += 1 116 buf = buf.parent 117 } 118 119 if (value.includes('\n')) { 120 let indent = this.raw(node, null, 'indent') 121 if (indent.length) { 122 for (let step = 0; step < depth; step++) value += indent 123 } 124 } 125 126 return value 127 } 128 129 block(node, start) { 130 let between = this.raw(node, 'between', 'beforeOpen') 131 this.builder(start + between + '{', node, 'start') 132 133 let after 134 if (node.nodes && node.nodes.length) { 135 this.body(node) 136 after = this.raw(node, 'after') 137 } else { 138 after = this.raw(node, 'after', 'emptyBody') 139 } 140 141 if (after) this.builder(after) 142 this.builder('}', node, 'end') 143 } 144 145 body(node) { 146 let last = node.nodes.length - 1 147 while (last > 0) { 148 if (node.nodes[last].type !== 'comment') break 149 last -= 1 150 } 151 152 let semicolon = this.raw(node, 'semicolon') 153 for (let i = 0; i < node.nodes.length; i++) { 154 let child = node.nodes[i] 155 let before = this.raw(child, 'before') 156 if (before) this.builder(before) 157 this.stringify(child, last !== i || semicolon) 158 } 159 } 160 161 comment(node) { 162 let left = this.raw(node, 'left', 'commentLeft') 163 let right = this.raw(node, 'right', 'commentRight') 164 this.builder('/*' + left + node.text + right + '*/', node) 165 } 166 167 decl(node, semicolon) { 168 let between = this.raw(node, 'between', 'colon') 169 let string = node.prop + between + this.rawValue(node, 'value') 170 171 if (node.important) { 172 string += node.raws.important || ' !important' 173 } 174 175 if (semicolon) string += ';' 176 this.builder(string, node) 177 } 178 179 document(node) { 180 this.body(node) 181 } 182 183 raw(node, own, detect) { 184 let value 185 if (!detect) detect = own 186 187 // Already had 188 if (own) { 189 value = node.raws[own] 190 if (typeof value !== 'undefined') return value 191 } 192 193 let parent = node.parent 194 195 if (detect === 'before') { 196 // Hack for first rule in CSS 197 if (!parent || (parent.type === 'root' && parent.first === node)) { 198 return '' 199 } 200 201 // `root` nodes in `document` should use only their own raws 202 if (parent && parent.type === 'document') { 203 return '' 204 } 205 } 206 207 // Floating child without parent 208 if (!parent) return DEFAULT_RAW[detect] 209 210 // Detect style by other nodes 211 let root = node.root() 212 if (!root.rawCache) root.rawCache = {} 213 if (typeof root.rawCache[detect] !== 'undefined') { 214 return root.rawCache[detect] 215 } 216 217 if (detect === 'before' || detect === 'after') { 218 return this.beforeAfter(node, detect) 219 } else { 220 let method = 'raw' + capitalize(detect) 221 if (this[method]) { 222 value = this[method](root, node) 223 } else { 224 root.walk(i => { 225 value = i.raws[own] 226 if (typeof value !== 'undefined') return false 227 }) 228 } 229 } 230 231 if (typeof value === 'undefined') value = DEFAULT_RAW[detect] 232 233 root.rawCache[detect] = value 234 return value 235 } 236 237 rawBeforeClose(root) { 238 let value 239 root.walk(i => { 240 if (i.nodes && i.nodes.length > 0) { 241 if (typeof i.raws.after !== 'undefined') { 242 value = i.raws.after 243 if (value.includes('\n')) { 244 value = value.replace(/[^\n]+$/, '') 245 } 246 return false 247 } 248 } 249 }) 250 if (value) value = value.replace(/\S/g, '') 251 return value 252 } 253 254 rawBeforeComment(root, node) { 255 let value 256 root.walkComments(i => { 257 if (typeof i.raws.before !== 'undefined') { 258 value = i.raws.before 259 if (value.includes('\n')) { 260 value = value.replace(/[^\n]+$/, '') 261 } 262 return false 263 } 264 }) 265 if (typeof value === 'undefined') { 266 value = this.raw(node, null, 'beforeDecl') 267 } else if (value) { 268 value = value.replace(/\S/g, '') 269 } 270 return value 271 } 272 273 rawBeforeDecl(root, node) { 274 let value 275 root.walkDecls(i => { 276 if (typeof i.raws.before !== 'undefined') { 277 value = i.raws.before 278 if (value.includes('\n')) { 279 value = value.replace(/[^\n]+$/, '') 280 } 281 return false 282 } 283 }) 284 if (typeof value === 'undefined') { 285 value = this.raw(node, null, 'beforeRule') 286 } else if (value) { 287 value = value.replace(/\S/g, '') 288 } 289 return value 290 } 291 292 rawBeforeOpen(root) { 293 let value 294 root.walk(i => { 295 if (i.type !== 'decl') { 296 value = i.raws.between 297 if (typeof value !== 'undefined') return false 298 } 299 }) 300 return value 301 } 302 303 rawBeforeRule(root) { 304 let value 305 root.walk(i => { 306 if (i.nodes && (i.parent !== root || root.first !== i)) { 307 if (typeof i.raws.before !== 'undefined') { 308 value = i.raws.before 309 if (value.includes('\n')) { 310 value = value.replace(/[^\n]+$/, '') 311 } 312 return false 313 } 314 } 315 }) 316 if (value) value = value.replace(/\S/g, '') 317 return value 318 } 319 320 rawColon(root) { 321 let value 322 root.walkDecls(i => { 323 if (typeof i.raws.between !== 'undefined') { 324 value = i.raws.between.replace(/[^\s:]/g, '') 325 return false 326 } 327 }) 328 return value 329 } 330 331 rawEmptyBody(root) { 332 let value 333 root.walk(i => { 334 if (i.nodes && i.nodes.length === 0) { 335 value = i.raws.after 336 if (typeof value !== 'undefined') return false 337 } 338 }) 339 return value 340 } 341 342 rawIndent(root) { 343 if (root.raws.indent) return root.raws.indent 344 let value 345 root.walk(i => { 346 let p = i.parent 347 if (p && p !== root && p.parent && p.parent === root) { 348 if (typeof i.raws.before !== 'undefined') { 349 let parts = i.raws.before.split('\n') 350 value = parts[parts.length - 1] 351 value = value.replace(/\S/g, '') 352 return false 353 } 354 } 355 }) 356 return value 357 } 358 359 rawSemicolon(root) { 360 let value 361 root.walk(i => { 362 if (i.nodes && i.nodes.length && i.last.type === 'decl') { 363 value = i.raws.semicolon 364 if (typeof value !== 'undefined') return false 365 } 366 }) 367 return value 368 } 369 370 rawValue(node, prop) { 371 let value = node[prop] 372 let raw = node.raws[prop] 373 if (raw && raw.value === value) { 374 return raw.raw 375 } 376 377 return value 378 } 379 380 root(node) { 381 this.body(node) 382 if (node.raws.after) this.builder(node.raws.after) 383 } 384 385 rule(node) { 386 this.block(node, this.rawValue(node, 'selector')) 387 if (node.raws.ownSemicolon) { 388 this.builder(node.raws.ownSemicolon, node, 'end') 389 } 390 } 391 392 stringify(node, semicolon) { 393 /* c8 ignore start */ 394 if (!this[node.type]) { 395 throw new Error( 396 'Unknown AST node type ' + 397 node.type + 398 '. ' + 399 'Maybe you need to change PostCSS stringifier.' 400 ) 401 } 402 /* c8 ignore stop */ 403 this[node.type](node, semicolon) 404 } 405 } 406 407 module.exports = Stringifier 408 Stringifier.default = Stringifier 409 410 411 /***/ }), 412 413 /***/ 356: 414 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 415 416 "use strict"; 417 418 419 let pico = __webpack_require__(2775) 420 421 let terminalHighlight = __webpack_require__(9746) 422 423 class CssSyntaxError extends Error { 424 constructor(message, line, column, source, file, plugin) { 425 super(message) 426 this.name = 'CssSyntaxError' 427 this.reason = message 428 429 if (file) { 430 this.file = file 431 } 432 if (source) { 433 this.source = source 434 } 435 if (plugin) { 436 this.plugin = plugin 437 } 438 if (typeof line !== 'undefined' && typeof column !== 'undefined') { 439 if (typeof line === 'number') { 440 this.line = line 441 this.column = column 442 } else { 443 this.line = line.line 444 this.column = line.column 445 this.endLine = column.line 446 this.endColumn = column.column 447 } 448 } 449 450 this.setMessage() 451 452 if (Error.captureStackTrace) { 453 Error.captureStackTrace(this, CssSyntaxError) 454 } 455 } 456 457 setMessage() { 458 this.message = this.plugin ? this.plugin + ': ' : '' 459 this.message += this.file ? this.file : '<css input>' 460 if (typeof this.line !== 'undefined') { 461 this.message += ':' + this.line + ':' + this.column 462 } 463 this.message += ': ' + this.reason 464 } 465 466 showSourceCode(color) { 467 if (!this.source) return '' 468 469 let css = this.source 470 if (color == null) color = pico.isColorSupported 471 472 let aside = text => text 473 let mark = text => text 474 let highlight = text => text 475 if (color) { 476 let { bold, gray, red } = pico.createColors(true) 477 mark = text => bold(red(text)) 478 aside = text => gray(text) 479 if (terminalHighlight) { 480 highlight = text => terminalHighlight(text) 481 } 482 } 483 484 let lines = css.split(/\r?\n/) 485 let start = Math.max(this.line - 3, 0) 486 let end = Math.min(this.line + 2, lines.length) 487 let maxWidth = String(end).length 488 489 return lines 490 .slice(start, end) 491 .map((line, index) => { 492 let number = start + 1 + index 493 let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | ' 494 if (number === this.line) { 495 if (line.length > 160) { 496 let padding = 20 497 let subLineStart = Math.max(0, this.column - padding) 498 let subLineEnd = Math.max( 499 this.column + padding, 500 this.endColumn + padding 501 ) 502 let subLine = line.slice(subLineStart, subLineEnd) 503 504 let spacing = 505 aside(gutter.replace(/\d/g, ' ')) + 506 line 507 .slice(0, Math.min(this.column - 1, padding - 1)) 508 .replace(/[^\t]/g, ' ') 509 510 return ( 511 mark('>') + 512 aside(gutter) + 513 highlight(subLine) + 514 '\n ' + 515 spacing + 516 mark('^') 517 ) 518 } 519 520 let spacing = 521 aside(gutter.replace(/\d/g, ' ')) + 522 line.slice(0, this.column - 1).replace(/[^\t]/g, ' ') 523 524 return ( 525 mark('>') + 526 aside(gutter) + 527 highlight(line) + 528 '\n ' + 529 spacing + 530 mark('^') 531 ) 532 } 533 534 return ' ' + aside(gutter) + highlight(line) 535 }) 536 .join('\n') 537 } 538 539 toString() { 540 let code = this.showSourceCode() 541 if (code) { 542 code = '\n\n' + code + '\n' 543 } 544 return this.name + ': ' + this.message + code 545 } 546 } 547 548 module.exports = CssSyntaxError 549 CssSyntaxError.default = CssSyntaxError 550 551 552 /***/ }), 553 554 /***/ 448: 555 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 556 557 "use strict"; 558 559 560 let Container = __webpack_require__(683) 561 let Document = __webpack_require__(271) 562 let MapGenerator = __webpack_require__(1670) 563 let parse = __webpack_require__(4295) 564 let Result = __webpack_require__(9055) 565 let Root = __webpack_require__(9434) 566 let stringify = __webpack_require__(633) 567 let { isClean, my } = __webpack_require__(1381) 568 let warnOnce = __webpack_require__(3122) 569 570 const TYPE_TO_CLASS_NAME = { 571 atrule: 'AtRule', 572 comment: 'Comment', 573 decl: 'Declaration', 574 document: 'Document', 575 root: 'Root', 576 rule: 'Rule' 577 } 578 579 const PLUGIN_PROPS = { 580 AtRule: true, 581 AtRuleExit: true, 582 Comment: true, 583 CommentExit: true, 584 Declaration: true, 585 DeclarationExit: true, 586 Document: true, 587 DocumentExit: true, 588 Once: true, 589 OnceExit: true, 590 postcssPlugin: true, 591 prepare: true, 592 Root: true, 593 RootExit: true, 594 Rule: true, 595 RuleExit: true 596 } 597 598 const NOT_VISITORS = { 599 Once: true, 600 postcssPlugin: true, 601 prepare: true 602 } 603 604 const CHILDREN = 0 605 606 function isPromise(obj) { 607 return typeof obj === 'object' && typeof obj.then === 'function' 608 } 609 610 function getEvents(node) { 611 let key = false 612 let type = TYPE_TO_CLASS_NAME[node.type] 613 if (node.type === 'decl') { 614 key = node.prop.toLowerCase() 615 } else if (node.type === 'atrule') { 616 key = node.name.toLowerCase() 617 } 618 619 if (key && node.append) { 620 return [ 621 type, 622 type + '-' + key, 623 CHILDREN, 624 type + 'Exit', 625 type + 'Exit-' + key 626 ] 627 } else if (key) { 628 return [type, type + '-' + key, type + 'Exit', type + 'Exit-' + key] 629 } else if (node.append) { 630 return [type, CHILDREN, type + 'Exit'] 631 } else { 632 return [type, type + 'Exit'] 633 } 634 } 635 636 function toStack(node) { 637 let events 638 if (node.type === 'document') { 639 events = ['Document', CHILDREN, 'DocumentExit'] 640 } else if (node.type === 'root') { 641 events = ['Root', CHILDREN, 'RootExit'] 642 } else { 643 events = getEvents(node) 644 } 645 646 return { 647 eventIndex: 0, 648 events, 649 iterator: 0, 650 node, 651 visitorIndex: 0, 652 visitors: [] 653 } 654 } 655 656 function cleanMarks(node) { 657 node[isClean] = false 658 if (node.nodes) node.nodes.forEach(i => cleanMarks(i)) 659 return node 660 } 661 662 let postcss = {} 663 664 class LazyResult { 665 get content() { 666 return this.stringify().content 667 } 668 669 get css() { 670 return this.stringify().css 671 } 672 673 get map() { 674 return this.stringify().map 675 } 676 677 get messages() { 678 return this.sync().messages 679 } 680 681 get opts() { 682 return this.result.opts 683 } 684 685 get processor() { 686 return this.result.processor 687 } 688 689 get root() { 690 return this.sync().root 691 } 692 693 get [Symbol.toStringTag]() { 694 return 'LazyResult' 695 } 696 697 constructor(processor, css, opts) { 698 this.stringified = false 699 this.processed = false 700 701 let root 702 if ( 703 typeof css === 'object' && 704 css !== null && 705 (css.type === 'root' || css.type === 'document') 706 ) { 707 root = cleanMarks(css) 708 } else if (css instanceof LazyResult || css instanceof Result) { 709 root = cleanMarks(css.root) 710 if (css.map) { 711 if (typeof opts.map === 'undefined') opts.map = {} 712 if (!opts.map.inline) opts.map.inline = false 713 opts.map.prev = css.map 714 } 715 } else { 716 let parser = parse 717 if (opts.syntax) parser = opts.syntax.parse 718 if (opts.parser) parser = opts.parser 719 if (parser.parse) parser = parser.parse 720 721 try { 722 root = parser(css, opts) 723 } catch (error) { 724 this.processed = true 725 this.error = error 726 } 727 728 if (root && !root[my]) { 729 /* c8 ignore next 2 */ 730 Container.rebuild(root) 731 } 732 } 733 734 this.result = new Result(processor, root, opts) 735 this.helpers = { ...postcss, postcss, result: this.result } 736 this.plugins = this.processor.plugins.map(plugin => { 737 if (typeof plugin === 'object' && plugin.prepare) { 738 return { ...plugin, ...plugin.prepare(this.result) } 739 } else { 740 return plugin 741 } 742 }) 743 } 744 745 async() { 746 if (this.error) return Promise.reject(this.error) 747 if (this.processed) return Promise.resolve(this.result) 748 if (!this.processing) { 749 this.processing = this.runAsync() 750 } 751 return this.processing 752 } 753 754 catch(onRejected) { 755 return this.async().catch(onRejected) 756 } 757 758 finally(onFinally) { 759 return this.async().then(onFinally, onFinally) 760 } 761 762 getAsyncError() { 763 throw new Error('Use process(css).then(cb) to work with async plugins') 764 } 765 766 handleError(error, node) { 767 let plugin = this.result.lastPlugin 768 try { 769 if (node) node.addToError(error) 770 this.error = error 771 if (error.name === 'CssSyntaxError' && !error.plugin) { 772 error.plugin = plugin.postcssPlugin 773 error.setMessage() 774 } else if (plugin.postcssVersion) { 775 if (false) {} 776 } 777 } catch (err) { 778 /* c8 ignore next 3 */ 779 // eslint-disable-next-line no-console 780 if (console && console.error) console.error(err) 781 } 782 return error 783 } 784 785 prepareVisitors() { 786 this.listeners = {} 787 let add = (plugin, type, cb) => { 788 if (!this.listeners[type]) this.listeners[type] = [] 789 this.listeners[type].push([plugin, cb]) 790 } 791 for (let plugin of this.plugins) { 792 if (typeof plugin === 'object') { 793 for (let event in plugin) { 794 if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) { 795 throw new Error( 796 `Unknown event $event} in $plugin.postcssPlugin}. ` + 797 `Try to update PostCSS ($this.processor.version} now).` 798 ) 799 } 800 if (!NOT_VISITORS[event]) { 801 if (typeof plugin[event] === 'object') { 802 for (let filter in plugin[event]) { 803 if (filter === '*') { 804 add(plugin, event, plugin[event][filter]) 805 } else { 806 add( 807 plugin, 808 event + '-' + filter.toLowerCase(), 809 plugin[event][filter] 810 ) 811 } 812 } 813 } else if (typeof plugin[event] === 'function') { 814 add(plugin, event, plugin[event]) 815 } 816 } 817 } 818 } 819 } 820 this.hasListener = Object.keys(this.listeners).length > 0 821 } 822 823 async runAsync() { 824 this.plugin = 0 825 for (let i = 0; i < this.plugins.length; i++) { 826 let plugin = this.plugins[i] 827 let promise = this.runOnRoot(plugin) 828 if (isPromise(promise)) { 829 try { 830 await promise 831 } catch (error) { 832 throw this.handleError(error) 833 } 834 } 835 } 836 837 this.prepareVisitors() 838 if (this.hasListener) { 839 let root = this.result.root 840 while (!root[isClean]) { 841 root[isClean] = true 842 let stack = [toStack(root)] 843 while (stack.length > 0) { 844 let promise = this.visitTick(stack) 845 if (isPromise(promise)) { 846 try { 847 await promise 848 } catch (e) { 849 let node = stack[stack.length - 1].node 850 throw this.handleError(e, node) 851 } 852 } 853 } 854 } 855 856 if (this.listeners.OnceExit) { 857 for (let [plugin, visitor] of this.listeners.OnceExit) { 858 this.result.lastPlugin = plugin 859 try { 860 if (root.type === 'document') { 861 let roots = root.nodes.map(subRoot => 862 visitor(subRoot, this.helpers) 863 ) 864 865 await Promise.all(roots) 866 } else { 867 await visitor(root, this.helpers) 868 } 869 } catch (e) { 870 throw this.handleError(e) 871 } 872 } 873 } 874 } 875 876 this.processed = true 877 return this.stringify() 878 } 879 880 runOnRoot(plugin) { 881 this.result.lastPlugin = plugin 882 try { 883 if (typeof plugin === 'object' && plugin.Once) { 884 if (this.result.root.type === 'document') { 885 let roots = this.result.root.nodes.map(root => 886 plugin.Once(root, this.helpers) 887 ) 888 889 if (isPromise(roots[0])) { 890 return Promise.all(roots) 891 } 892 893 return roots 894 } 895 896 return plugin.Once(this.result.root, this.helpers) 897 } else if (typeof plugin === 'function') { 898 return plugin(this.result.root, this.result) 899 } 900 } catch (error) { 901 throw this.handleError(error) 902 } 903 } 904 905 stringify() { 906 if (this.error) throw this.error 907 if (this.stringified) return this.result 908 this.stringified = true 909 910 this.sync() 911 912 let opts = this.result.opts 913 let str = stringify 914 if (opts.syntax) str = opts.syntax.stringify 915 if (opts.stringifier) str = opts.stringifier 916 if (str.stringify) str = str.stringify 917 918 let map = new MapGenerator(str, this.result.root, this.result.opts) 919 let data = map.generate() 920 this.result.css = data[0] 921 this.result.map = data[1] 922 923 return this.result 924 } 925 926 sync() { 927 if (this.error) throw this.error 928 if (this.processed) return this.result 929 this.processed = true 930 931 if (this.processing) { 932 throw this.getAsyncError() 933 } 934 935 for (let plugin of this.plugins) { 936 let promise = this.runOnRoot(plugin) 937 if (isPromise(promise)) { 938 throw this.getAsyncError() 939 } 940 } 941 942 this.prepareVisitors() 943 if (this.hasListener) { 944 let root = this.result.root 945 while (!root[isClean]) { 946 root[isClean] = true 947 this.walkSync(root) 948 } 949 if (this.listeners.OnceExit) { 950 if (root.type === 'document') { 951 for (let subRoot of root.nodes) { 952 this.visitSync(this.listeners.OnceExit, subRoot) 953 } 954 } else { 955 this.visitSync(this.listeners.OnceExit, root) 956 } 957 } 958 } 959 960 return this.result 961 } 962 963 then(onFulfilled, onRejected) { 964 if (false) {} 965 return this.async().then(onFulfilled, onRejected) 966 } 967 968 toString() { 969 return this.css 970 } 971 972 visitSync(visitors, node) { 973 for (let [plugin, visitor] of visitors) { 974 this.result.lastPlugin = plugin 975 let promise 976 try { 977 promise = visitor(node, this.helpers) 978 } catch (e) { 979 throw this.handleError(e, node.proxyOf) 980 } 981 if (node.type !== 'root' && node.type !== 'document' && !node.parent) { 982 return true 983 } 984 if (isPromise(promise)) { 985 throw this.getAsyncError() 986 } 987 } 988 } 989 990 visitTick(stack) { 991 let visit = stack[stack.length - 1] 992 let { node, visitors } = visit 993 994 if (node.type !== 'root' && node.type !== 'document' && !node.parent) { 995 stack.pop() 996 return 997 } 998 999 if (visitors.length > 0 && visit.visitorIndex < visitors.length) { 1000 let [plugin, visitor] = visitors[visit.visitorIndex] 1001 visit.visitorIndex += 1 1002 if (visit.visitorIndex === visitors.length) { 1003 visit.visitors = [] 1004 visit.visitorIndex = 0 1005 } 1006 this.result.lastPlugin = plugin 1007 try { 1008 return visitor(node.toProxy(), this.helpers) 1009 } catch (e) { 1010 throw this.handleError(e, node) 1011 } 1012 } 1013 1014 if (visit.iterator !== 0) { 1015 let iterator = visit.iterator 1016 let child 1017 while ((child = node.nodes[node.indexes[iterator]])) { 1018 node.indexes[iterator] += 1 1019 if (!child[isClean]) { 1020 child[isClean] = true 1021 stack.push(toStack(child)) 1022 return 1023 } 1024 } 1025 visit.iterator = 0 1026 delete node.indexes[iterator] 1027 } 1028 1029 let events = visit.events 1030 while (visit.eventIndex < events.length) { 1031 let event = events[visit.eventIndex] 1032 visit.eventIndex += 1 1033 if (event === CHILDREN) { 1034 if (node.nodes && node.nodes.length) { 1035 node[isClean] = true 1036 visit.iterator = node.getIterator() 1037 } 1038 return 1039 } else if (this.listeners[event]) { 1040 visit.visitors = this.listeners[event] 1041 return 1042 } 1043 } 1044 stack.pop() 1045 } 1046 1047 walkSync(node) { 1048 node[isClean] = true 1049 let events = getEvents(node) 1050 for (let event of events) { 1051 if (event === CHILDREN) { 1052 if (node.nodes) { 1053 node.each(child => { 1054 if (!child[isClean]) this.walkSync(child) 1055 }) 1056 } 1057 } else { 1058 let visitors = this.listeners[event] 1059 if (visitors) { 1060 if (this.visitSync(visitors, node.toProxy())) return 1061 } 1062 } 1063 } 1064 } 1065 1066 warnings() { 1067 return this.sync().warnings() 1068 } 1069 } 1070 1071 LazyResult.registerPostcss = dependant => { 1072 postcss = dependant 1073 } 1074 1075 module.exports = LazyResult 1076 LazyResult.default = LazyResult 1077 1078 Root.registerLazyResult(LazyResult) 1079 Document.registerLazyResult(LazyResult) 1080 1081 1082 /***/ }), 1083 1084 /***/ 461: 1085 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1086 1087 // Load in dependencies 1088 var computedStyle = __webpack_require__(6109); 1089 1090 /** 1091 * Calculate the `line-height` of a given node 1092 * @param {HTMLElement} node Element to calculate line height of. Must be in the DOM. 1093 * @returns {Number} `line-height` of the element in pixels 1094 */ 1095 function lineHeight(node) { 1096 // Grab the line-height via style 1097 var lnHeightStr = computedStyle(node, 'line-height'); 1098 var lnHeight = parseFloat(lnHeightStr, 10); 1099 1100 // If the lineHeight did not contain a unit (i.e. it was numeric), convert it to ems (e.g. '2.3' === '2.3em') 1101 if (lnHeightStr === lnHeight + '') { 1102 // Save the old lineHeight style and update the em unit to the element 1103 var _lnHeightStyle = node.style.lineHeight; 1104 node.style.lineHeight = lnHeightStr + 'em'; 1105 1106 // Calculate the em based height 1107 lnHeightStr = computedStyle(node, 'line-height'); 1108 lnHeight = parseFloat(lnHeightStr, 10); 1109 1110 // Revert the lineHeight style 1111 if (_lnHeightStyle) { 1112 node.style.lineHeight = _lnHeightStyle; 1113 } else { 1114 delete node.style.lineHeight; 1115 } 1116 } 1117 1118 // If the lineHeight is in `pt`, convert it to pixels (4px for 3pt) 1119 // DEV: `em` units are converted to `pt` in IE6 1120 // Conversion ratio from https://developer.mozilla.org/en-US/docs/Web/CSS/length 1121 if (lnHeightStr.indexOf('pt') !== -1) { 1122 lnHeight *= 4; 1123 lnHeight /= 3; 1124 // Otherwise, if the lineHeight is in `mm`, convert it to pixels (96px for 25.4mm) 1125 } else if (lnHeightStr.indexOf('mm') !== -1) { 1126 lnHeight *= 96; 1127 lnHeight /= 25.4; 1128 // Otherwise, if the lineHeight is in `cm`, convert it to pixels (96px for 2.54cm) 1129 } else if (lnHeightStr.indexOf('cm') !== -1) { 1130 lnHeight *= 96; 1131 lnHeight /= 2.54; 1132 // Otherwise, if the lineHeight is in `in`, convert it to pixels (96px for 1in) 1133 } else if (lnHeightStr.indexOf('in') !== -1) { 1134 lnHeight *= 96; 1135 // Otherwise, if the lineHeight is in `pc`, convert it to pixels (12pt for 1pc) 1136 } else if (lnHeightStr.indexOf('pc') !== -1) { 1137 lnHeight *= 16; 1138 } 1139 1140 // Continue our computation 1141 lnHeight = Math.round(lnHeight); 1142 1143 // If the line-height is "normal", calculate by font-size 1144 if (lnHeightStr === 'normal') { 1145 // Create a temporary node 1146 var nodeName = node.nodeName; 1147 var _node = document.createElement(nodeName); 1148 _node.innerHTML = ' '; 1149 1150 // If we have a text area, reset it to only 1 row 1151 // https://github.com/twolfson/line-height/issues/4 1152 if (nodeName.toUpperCase() === 'TEXTAREA') { 1153 _node.setAttribute('rows', '1'); 1154 } 1155 1156 // Set the font-size of the element 1157 var fontSizeStr = computedStyle(node, 'font-size'); 1158 _node.style.fontSize = fontSizeStr; 1159 1160 // Remove default padding/border which can affect offset height 1161 // https://github.com/twolfson/line-height/issues/4 1162 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight 1163 _node.style.padding = '0px'; 1164 _node.style.border = '0px'; 1165 1166 // Append it to the body 1167 var body = document.body; 1168 body.appendChild(_node); 1169 1170 // Assume the line height of the element is the height 1171 var height = _node.offsetHeight; 1172 lnHeight = height; 1173 1174 // Remove our child from the DOM 1175 body.removeChild(_node); 1176 } 1177 1178 // Return the calculated height 1179 return lnHeight; 1180 } 1181 1182 // Export lineHeight 1183 module.exports = lineHeight; 1184 1185 1186 /***/ }), 1187 1188 /***/ 628: 1189 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1190 1191 "use strict"; 1192 /** 1193 * Copyright (c) 2013-present, Facebook, Inc. 1194 * 1195 * This source code is licensed under the MIT license found in the 1196 * LICENSE file in the root directory of this source tree. 1197 */ 1198 1199 1200 1201 var ReactPropTypesSecret = __webpack_require__(4067); 1202 1203 function emptyFunction() {} 1204 function emptyFunctionWithReset() {} 1205 emptyFunctionWithReset.resetWarningCache = emptyFunction; 1206 1207 module.exports = function() { 1208 function shim(props, propName, componentName, location, propFullName, secret) { 1209 if (secret === ReactPropTypesSecret) { 1210 // It is still safe when called from React. 1211 return; 1212 } 1213 var err = new Error( 1214 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 1215 'Use PropTypes.checkPropTypes() to call them. ' + 1216 'Read more at http://fb.me/use-check-prop-types' 1217 ); 1218 err.name = 'Invariant Violation'; 1219 throw err; 1220 }; 1221 shim.isRequired = shim; 1222 function getShim() { 1223 return shim; 1224 }; 1225 // Important! 1226 // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. 1227 var ReactPropTypes = { 1228 array: shim, 1229 bigint: shim, 1230 bool: shim, 1231 func: shim, 1232 number: shim, 1233 object: shim, 1234 string: shim, 1235 symbol: shim, 1236 1237 any: shim, 1238 arrayOf: getShim, 1239 element: shim, 1240 elementType: shim, 1241 instanceOf: getShim, 1242 node: shim, 1243 objectOf: getShim, 1244 oneOf: getShim, 1245 oneOfType: getShim, 1246 shape: getShim, 1247 exact: getShim, 1248 1249 checkPropTypes: emptyFunctionWithReset, 1250 resetWarningCache: emptyFunction 1251 }; 1252 1253 ReactPropTypes.PropTypes = ReactPropTypes; 1254 1255 return ReactPropTypes; 1256 }; 1257 1258 1259 /***/ }), 1260 1261 /***/ 633: 1262 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1263 1264 "use strict"; 1265 1266 1267 let Stringifier = __webpack_require__(346) 1268 1269 function stringify(node, builder) { 1270 let str = new Stringifier(builder) 1271 str.stringify(node) 1272 } 1273 1274 module.exports = stringify 1275 stringify.default = stringify 1276 1277 1278 /***/ }), 1279 1280 /***/ 683: 1281 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1282 1283 "use strict"; 1284 1285 1286 let Comment = __webpack_require__(6589) 1287 let Declaration = __webpack_require__(1516) 1288 let Node = __webpack_require__(7490) 1289 let { isClean, my } = __webpack_require__(1381) 1290 1291 let AtRule, parse, Root, Rule 1292 1293 function cleanSource(nodes) { 1294 return nodes.map(i => { 1295 if (i.nodes) i.nodes = cleanSource(i.nodes) 1296 delete i.source 1297 return i 1298 }) 1299 } 1300 1301 function markTreeDirty(node) { 1302 node[isClean] = false 1303 if (node.proxyOf.nodes) { 1304 for (let i of node.proxyOf.nodes) { 1305 markTreeDirty(i) 1306 } 1307 } 1308 } 1309 1310 class Container extends Node { 1311 get first() { 1312 if (!this.proxyOf.nodes) return undefined 1313 return this.proxyOf.nodes[0] 1314 } 1315 1316 get last() { 1317 if (!this.proxyOf.nodes) return undefined 1318 return this.proxyOf.nodes[this.proxyOf.nodes.length - 1] 1319 } 1320 1321 append(...children) { 1322 for (let child of children) { 1323 let nodes = this.normalize(child, this.last) 1324 for (let node of nodes) this.proxyOf.nodes.push(node) 1325 } 1326 1327 this.markDirty() 1328 1329 return this 1330 } 1331 1332 cleanRaws(keepBetween) { 1333 super.cleanRaws(keepBetween) 1334 if (this.nodes) { 1335 for (let node of this.nodes) node.cleanRaws(keepBetween) 1336 } 1337 } 1338 1339 each(callback) { 1340 if (!this.proxyOf.nodes) return undefined 1341 let iterator = this.getIterator() 1342 1343 let index, result 1344 while (this.indexes[iterator] < this.proxyOf.nodes.length) { 1345 index = this.indexes[iterator] 1346 result = callback(this.proxyOf.nodes[index], index) 1347 if (result === false) break 1348 1349 this.indexes[iterator] += 1 1350 } 1351 1352 delete this.indexes[iterator] 1353 return result 1354 } 1355 1356 every(condition) { 1357 return this.nodes.every(condition) 1358 } 1359 1360 getIterator() { 1361 if (!this.lastEach) this.lastEach = 0 1362 if (!this.indexes) this.indexes = {} 1363 1364 this.lastEach += 1 1365 let iterator = this.lastEach 1366 this.indexes[iterator] = 0 1367 1368 return iterator 1369 } 1370 1371 getProxyProcessor() { 1372 return { 1373 get(node, prop) { 1374 if (prop === 'proxyOf') { 1375 return node 1376 } else if (!node[prop]) { 1377 return node[prop] 1378 } else if ( 1379 prop === 'each' || 1380 (typeof prop === 'string' && prop.startsWith('walk')) 1381 ) { 1382 return (...args) => { 1383 return node[prop]( 1384 ...args.map(i => { 1385 if (typeof i === 'function') { 1386 return (child, index) => i(child.toProxy(), index) 1387 } else { 1388 return i 1389 } 1390 }) 1391 ) 1392 } 1393 } else if (prop === 'every' || prop === 'some') { 1394 return cb => { 1395 return node[prop]((child, ...other) => 1396 cb(child.toProxy(), ...other) 1397 ) 1398 } 1399 } else if (prop === 'root') { 1400 return () => node.root().toProxy() 1401 } else if (prop === 'nodes') { 1402 return node.nodes.map(i => i.toProxy()) 1403 } else if (prop === 'first' || prop === 'last') { 1404 return node[prop].toProxy() 1405 } else { 1406 return node[prop] 1407 } 1408 }, 1409 1410 set(node, prop, value) { 1411 if (node[prop] === value) return true 1412 node[prop] = value 1413 if (prop === 'name' || prop === 'params' || prop === 'selector') { 1414 node.markDirty() 1415 } 1416 return true 1417 } 1418 } 1419 } 1420 1421 index(child) { 1422 if (typeof child === 'number') return child 1423 if (child.proxyOf) child = child.proxyOf 1424 return this.proxyOf.nodes.indexOf(child) 1425 } 1426 1427 insertAfter(exist, add) { 1428 let existIndex = this.index(exist) 1429 let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse() 1430 existIndex = this.index(exist) 1431 for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node) 1432 1433 let index 1434 for (let id in this.indexes) { 1435 index = this.indexes[id] 1436 if (existIndex < index) { 1437 this.indexes[id] = index + nodes.length 1438 } 1439 } 1440 1441 this.markDirty() 1442 1443 return this 1444 } 1445 1446 insertBefore(exist, add) { 1447 let existIndex = this.index(exist) 1448 let type = existIndex === 0 ? 'prepend' : false 1449 let nodes = this.normalize( 1450 add, 1451 this.proxyOf.nodes[existIndex], 1452 type 1453 ).reverse() 1454 existIndex = this.index(exist) 1455 for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node) 1456 1457 let index 1458 for (let id in this.indexes) { 1459 index = this.indexes[id] 1460 if (existIndex <= index) { 1461 this.indexes[id] = index + nodes.length 1462 } 1463 } 1464 1465 this.markDirty() 1466 1467 return this 1468 } 1469 1470 normalize(nodes, sample) { 1471 if (typeof nodes === 'string') { 1472 nodes = cleanSource(parse(nodes).nodes) 1473 } else if (typeof nodes === 'undefined') { 1474 nodes = [] 1475 } else if (Array.isArray(nodes)) { 1476 nodes = nodes.slice(0) 1477 for (let i of nodes) { 1478 if (i.parent) i.parent.removeChild(i, 'ignore') 1479 } 1480 } else if (nodes.type === 'root' && this.type !== 'document') { 1481 nodes = nodes.nodes.slice(0) 1482 for (let i of nodes) { 1483 if (i.parent) i.parent.removeChild(i, 'ignore') 1484 } 1485 } else if (nodes.type) { 1486 nodes = [nodes] 1487 } else if (nodes.prop) { 1488 if (typeof nodes.value === 'undefined') { 1489 throw new Error('Value field is missed in node creation') 1490 } else if (typeof nodes.value !== 'string') { 1491 nodes.value = String(nodes.value) 1492 } 1493 nodes = [new Declaration(nodes)] 1494 } else if (nodes.selector || nodes.selectors) { 1495 nodes = [new Rule(nodes)] 1496 } else if (nodes.name) { 1497 nodes = [new AtRule(nodes)] 1498 } else if (nodes.text) { 1499 nodes = [new Comment(nodes)] 1500 } else { 1501 throw new Error('Unknown node type in node creation') 1502 } 1503 1504 let processed = nodes.map(i => { 1505 /* c8 ignore next */ 1506 if (!i[my]) Container.rebuild(i) 1507 i = i.proxyOf 1508 if (i.parent) i.parent.removeChild(i) 1509 if (i[isClean]) markTreeDirty(i) 1510 1511 if (!i.raws) i.raws = {} 1512 if (typeof i.raws.before === 'undefined') { 1513 if (sample && typeof sample.raws.before !== 'undefined') { 1514 i.raws.before = sample.raws.before.replace(/\S/g, '') 1515 } 1516 } 1517 i.parent = this.proxyOf 1518 return i 1519 }) 1520 1521 return processed 1522 } 1523 1524 prepend(...children) { 1525 children = children.reverse() 1526 for (let child of children) { 1527 let nodes = this.normalize(child, this.first, 'prepend').reverse() 1528 for (let node of nodes) this.proxyOf.nodes.unshift(node) 1529 for (let id in this.indexes) { 1530 this.indexes[id] = this.indexes[id] + nodes.length 1531 } 1532 } 1533 1534 this.markDirty() 1535 1536 return this 1537 } 1538 1539 push(child) { 1540 child.parent = this 1541 this.proxyOf.nodes.push(child) 1542 return this 1543 } 1544 1545 removeAll() { 1546 for (let node of this.proxyOf.nodes) node.parent = undefined 1547 this.proxyOf.nodes = [] 1548 1549 this.markDirty() 1550 1551 return this 1552 } 1553 1554 removeChild(child) { 1555 child = this.index(child) 1556 this.proxyOf.nodes[child].parent = undefined 1557 this.proxyOf.nodes.splice(child, 1) 1558 1559 let index 1560 for (let id in this.indexes) { 1561 index = this.indexes[id] 1562 if (index >= child) { 1563 this.indexes[id] = index - 1 1564 } 1565 } 1566 1567 this.markDirty() 1568 1569 return this 1570 } 1571 1572 replaceValues(pattern, opts, callback) { 1573 if (!callback) { 1574 callback = opts 1575 opts = {} 1576 } 1577 1578 this.walkDecls(decl => { 1579 if (opts.props && !opts.props.includes(decl.prop)) return 1580 if (opts.fast && !decl.value.includes(opts.fast)) return 1581 1582 decl.value = decl.value.replace(pattern, callback) 1583 }) 1584 1585 this.markDirty() 1586 1587 return this 1588 } 1589 1590 some(condition) { 1591 return this.nodes.some(condition) 1592 } 1593 1594 walk(callback) { 1595 return this.each((child, i) => { 1596 let result 1597 try { 1598 result = callback(child, i) 1599 } catch (e) { 1600 throw child.addToError(e) 1601 } 1602 if (result !== false && child.walk) { 1603 result = child.walk(callback) 1604 } 1605 1606 return result 1607 }) 1608 } 1609 1610 walkAtRules(name, callback) { 1611 if (!callback) { 1612 callback = name 1613 return this.walk((child, i) => { 1614 if (child.type === 'atrule') { 1615 return callback(child, i) 1616 } 1617 }) 1618 } 1619 if (name instanceof RegExp) { 1620 return this.walk((child, i) => { 1621 if (child.type === 'atrule' && name.test(child.name)) { 1622 return callback(child, i) 1623 } 1624 }) 1625 } 1626 return this.walk((child, i) => { 1627 if (child.type === 'atrule' && child.name === name) { 1628 return callback(child, i) 1629 } 1630 }) 1631 } 1632 1633 walkComments(callback) { 1634 return this.walk((child, i) => { 1635 if (child.type === 'comment') { 1636 return callback(child, i) 1637 } 1638 }) 1639 } 1640 1641 walkDecls(prop, callback) { 1642 if (!callback) { 1643 callback = prop 1644 return this.walk((child, i) => { 1645 if (child.type === 'decl') { 1646 return callback(child, i) 1647 } 1648 }) 1649 } 1650 if (prop instanceof RegExp) { 1651 return this.walk((child, i) => { 1652 if (child.type === 'decl' && prop.test(child.prop)) { 1653 return callback(child, i) 1654 } 1655 }) 1656 } 1657 return this.walk((child, i) => { 1658 if (child.type === 'decl' && child.prop === prop) { 1659 return callback(child, i) 1660 } 1661 }) 1662 } 1663 1664 walkRules(selector, callback) { 1665 if (!callback) { 1666 callback = selector 1667 1668 return this.walk((child, i) => { 1669 if (child.type === 'rule') { 1670 return callback(child, i) 1671 } 1672 }) 1673 } 1674 if (selector instanceof RegExp) { 1675 return this.walk((child, i) => { 1676 if (child.type === 'rule' && selector.test(child.selector)) { 1677 return callback(child, i) 1678 } 1679 }) 1680 } 1681 return this.walk((child, i) => { 1682 if (child.type === 'rule' && child.selector === selector) { 1683 return callback(child, i) 1684 } 1685 }) 1686 } 1687 } 1688 1689 Container.registerParse = dependant => { 1690 parse = dependant 1691 } 1692 1693 Container.registerRule = dependant => { 1694 Rule = dependant 1695 } 1696 1697 Container.registerAtRule = dependant => { 1698 AtRule = dependant 1699 } 1700 1701 Container.registerRoot = dependant => { 1702 Root = dependant 1703 } 1704 1705 module.exports = Container 1706 Container.default = Container 1707 1708 /* c8 ignore start */ 1709 Container.rebuild = node => { 1710 if (node.type === 'atrule') { 1711 Object.setPrototypeOf(node, AtRule.prototype) 1712 } else if (node.type === 'rule') { 1713 Object.setPrototypeOf(node, Rule.prototype) 1714 } else if (node.type === 'decl') { 1715 Object.setPrototypeOf(node, Declaration.prototype) 1716 } else if (node.type === 'comment') { 1717 Object.setPrototypeOf(node, Comment.prototype) 1718 } else if (node.type === 'root') { 1719 Object.setPrototypeOf(node, Root.prototype) 1720 } 1721 1722 node[my] = true 1723 1724 if (node.nodes) { 1725 node.nodes.forEach(child => { 1726 Container.rebuild(child) 1727 }) 1728 } 1729 } 1730 /* c8 ignore stop */ 1731 1732 1733 /***/ }), 1734 1735 /***/ 1087: 1736 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1737 1738 "use strict"; 1739 /** 1740 * Copyright 2013-2015, Facebook, Inc. 1741 * All rights reserved. 1742 * 1743 * This source code is licensed under the BSD-style license found in the 1744 * LICENSE file in the root directory of this source tree. An additional grant 1745 * of patent rights can be found in the PATENTS file in the same directory. 1746 * 1747 * @providesModule isEventSupported 1748 */ 1749 1750 1751 1752 var ExecutionEnvironment = __webpack_require__(8202); 1753 1754 var useHasFeature; 1755 if (ExecutionEnvironment.canUseDOM) { 1756 useHasFeature = 1757 document.implementation && 1758 document.implementation.hasFeature && 1759 // always returns true in newer browsers as per the standard. 1760 // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature 1761 document.implementation.hasFeature('', '') !== true; 1762 } 1763 1764 /** 1765 * Checks if an event is supported in the current execution environment. 1766 * 1767 * NOTE: This will not work correctly for non-generic events such as `change`, 1768 * `reset`, `load`, `error`, and `select`. 1769 * 1770 * Borrows from Modernizr. 1771 * 1772 * @param {string} eventNameSuffix Event name, e.g. "click". 1773 * @param {?boolean} capture Check if the capture phase is supported. 1774 * @return {boolean} True if the event is supported. 1775 * @internal 1776 * @license Modernizr 3.0.0pre (Custom Build) | MIT 1777 */ 1778 function isEventSupported(eventNameSuffix, capture) { 1779 if (!ExecutionEnvironment.canUseDOM || 1780 capture && !('addEventListener' in document)) { 1781 return false; 1782 } 1783 1784 var eventName = 'on' + eventNameSuffix; 1785 var isSupported = eventName in document; 1786 1787 if (!isSupported) { 1788 var element = document.createElement('div'); 1789 element.setAttribute(eventName, 'return;'); 1790 isSupported = typeof element[eventName] === 'function'; 1791 } 1792 1793 if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { 1794 // This is the only way to test support for the `wheel` event in IE9+. 1795 isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); 1796 } 1797 1798 return isSupported; 1799 } 1800 1801 module.exports = isEventSupported; 1802 1803 1804 /***/ }), 1805 1806 /***/ 1326: 1807 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1808 1809 "use strict"; 1810 1811 1812 let Container = __webpack_require__(683) 1813 1814 class AtRule extends Container { 1815 constructor(defaults) { 1816 super(defaults) 1817 this.type = 'atrule' 1818 } 1819 1820 append(...children) { 1821 if (!this.proxyOf.nodes) this.nodes = [] 1822 return super.append(...children) 1823 } 1824 1825 prepend(...children) { 1826 if (!this.proxyOf.nodes) this.nodes = [] 1827 return super.prepend(...children) 1828 } 1829 } 1830 1831 module.exports = AtRule 1832 AtRule.default = AtRule 1833 1834 Container.registerAtRule(AtRule) 1835 1836 1837 /***/ }), 1838 1839 /***/ 1381: 1840 /***/ ((module) => { 1841 1842 "use strict"; 1843 1844 1845 module.exports.isClean = Symbol('isClean') 1846 1847 module.exports.my = Symbol('my') 1848 1849 1850 /***/ }), 1851 1852 /***/ 1443: 1853 /***/ ((module) => { 1854 1855 module.exports = function postcssPrefixSelector(options) { 1856 const prefix = options.prefix; 1857 const prefixWithSpace = /\s+$/.test(prefix) ? prefix : `$prefix} `; 1858 const ignoreFiles = options.ignoreFiles ? [].concat(options.ignoreFiles) : []; 1859 const includeFiles = options.includeFiles 1860 ? [].concat(options.includeFiles) 1861 : []; 1862 1863 return function (root) { 1864 if ( 1865 ignoreFiles.length && 1866 root.source.input.file && 1867 isFileInArray(root.source.input.file, ignoreFiles) 1868 ) { 1869 return; 1870 } 1871 if ( 1872 includeFiles.length && 1873 root.source.input.file && 1874 !isFileInArray(root.source.input.file, includeFiles) 1875 ) { 1876 return; 1877 } 1878 1879 root.walkRules((rule) => { 1880 const keyframeRules = [ 1881 'keyframes', 1882 '-webkit-keyframes', 1883 '-moz-keyframes', 1884 '-o-keyframes', 1885 '-ms-keyframes', 1886 ]; 1887 1888 if (rule.parent && keyframeRules.includes(rule.parent.name)) { 1889 return; 1890 } 1891 1892 rule.selectors = rule.selectors.map((selector) => { 1893 if (options.exclude && excludeSelector(selector, options.exclude)) { 1894 return selector; 1895 } 1896 1897 if (options.transform) { 1898 return options.transform( 1899 prefix, 1900 selector, 1901 prefixWithSpace + selector, 1902 root.source.input.file, 1903 rule 1904 ); 1905 } 1906 1907 return prefixWithSpace + selector; 1908 }); 1909 }); 1910 }; 1911 }; 1912 1913 function isFileInArray(file, arr) { 1914 return arr.some((ruleOrString) => { 1915 if (ruleOrString instanceof RegExp) { 1916 return ruleOrString.test(file); 1917 } 1918 1919 return file.includes(ruleOrString); 1920 }); 1921 } 1922 1923 function excludeSelector(selector, excludeArr) { 1924 return excludeArr.some((excludeRule) => { 1925 if (excludeRule instanceof RegExp) { 1926 return excludeRule.test(selector); 1927 } 1928 1929 return selector === excludeRule; 1930 }); 1931 } 1932 1933 1934 /***/ }), 1935 1936 /***/ 1516: 1937 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 1938 1939 "use strict"; 1940 1941 1942 let Node = __webpack_require__(7490) 1943 1944 class Declaration extends Node { 1945 get variable() { 1946 return this.prop.startsWith('--') || this.prop[0] === '$' 1947 } 1948 1949 constructor(defaults) { 1950 if ( 1951 defaults && 1952 typeof defaults.value !== 'undefined' && 1953 typeof defaults.value !== 'string' 1954 ) { 1955 defaults = { ...defaults, value: String(defaults.value) } 1956 } 1957 super(defaults) 1958 this.type = 'decl' 1959 } 1960 } 1961 1962 module.exports = Declaration 1963 Declaration.default = Declaration 1964 1965 1966 /***/ }), 1967 1968 /***/ 1524: 1969 /***/ ((module) => { 1970 1971 var minus = "-".charCodeAt(0); 1972 var plus = "+".charCodeAt(0); 1973 var dot = ".".charCodeAt(0); 1974 var exp = "e".charCodeAt(0); 1975 var EXP = "E".charCodeAt(0); 1976 1977 // Check if three code points would start a number 1978 // https://www.w3.org/TR/css-syntax-3/#starts-with-a-number 1979 function likeNumber(value) { 1980 var code = value.charCodeAt(0); 1981 var nextCode; 1982 1983 if (code === plus || code === minus) { 1984 nextCode = value.charCodeAt(1); 1985 1986 if (nextCode >= 48 && nextCode <= 57) { 1987 return true; 1988 } 1989 1990 var nextNextCode = value.charCodeAt(2); 1991 1992 if (nextCode === dot && nextNextCode >= 48 && nextNextCode <= 57) { 1993 return true; 1994 } 1995 1996 return false; 1997 } 1998 1999 if (code === dot) { 2000 nextCode = value.charCodeAt(1); 2001 2002 if (nextCode >= 48 && nextCode <= 57) { 2003 return true; 2004 } 2005 2006 return false; 2007 } 2008 2009 if (code >= 48 && code <= 57) { 2010 return true; 2011 } 2012 2013 return false; 2014 } 2015 2016 // Consume a number 2017 // https://www.w3.org/TR/css-syntax-3/#consume-number 2018 module.exports = function(value) { 2019 var pos = 0; 2020 var length = value.length; 2021 var code; 2022 var nextCode; 2023 var nextNextCode; 2024 2025 if (length === 0 || !likeNumber(value)) { 2026 return false; 2027 } 2028 2029 code = value.charCodeAt(pos); 2030 2031 if (code === plus || code === minus) { 2032 pos++; 2033 } 2034 2035 while (pos < length) { 2036 code = value.charCodeAt(pos); 2037 2038 if (code < 48 || code > 57) { 2039 break; 2040 } 2041 2042 pos += 1; 2043 } 2044 2045 code = value.charCodeAt(pos); 2046 nextCode = value.charCodeAt(pos + 1); 2047 2048 if (code === dot && nextCode >= 48 && nextCode <= 57) { 2049 pos += 2; 2050 2051 while (pos < length) { 2052 code = value.charCodeAt(pos); 2053 2054 if (code < 48 || code > 57) { 2055 break; 2056 } 2057 2058 pos += 1; 2059 } 2060 } 2061 2062 code = value.charCodeAt(pos); 2063 nextCode = value.charCodeAt(pos + 1); 2064 nextNextCode = value.charCodeAt(pos + 2); 2065 2066 if ( 2067 (code === exp || code === EXP) && 2068 ((nextCode >= 48 && nextCode <= 57) || 2069 ((nextCode === plus || nextCode === minus) && 2070 nextNextCode >= 48 && 2071 nextNextCode <= 57)) 2072 ) { 2073 pos += nextCode === plus || nextCode === minus ? 3 : 2; 2074 2075 while (pos < length) { 2076 code = value.charCodeAt(pos); 2077 2078 if (code < 48 || code > 57) { 2079 break; 2080 } 2081 2082 pos += 1; 2083 } 2084 } 2085 2086 return { 2087 number: value.slice(0, pos), 2088 unit: value.slice(pos) 2089 }; 2090 }; 2091 2092 2093 /***/ }), 2094 2095 /***/ 1544: 2096 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 2097 2098 var parse = __webpack_require__(8491); 2099 var walk = __webpack_require__(3815); 2100 var stringify = __webpack_require__(4725); 2101 2102 function ValueParser(value) { 2103 if (this instanceof ValueParser) { 2104 this.nodes = parse(value); 2105 return this; 2106 } 2107 return new ValueParser(value); 2108 } 2109 2110 ValueParser.prototype.toString = function() { 2111 return Array.isArray(this.nodes) ? stringify(this.nodes) : ""; 2112 }; 2113 2114 ValueParser.prototype.walk = function(cb, bubble) { 2115 walk(this.nodes, cb, bubble); 2116 return this; 2117 }; 2118 2119 ValueParser.unit = __webpack_require__(1524); 2120 2121 ValueParser.walk = walk; 2122 2123 ValueParser.stringify = stringify; 2124 2125 module.exports = ValueParser; 2126 2127 2128 /***/ }), 2129 2130 /***/ 1609: 2131 /***/ ((module) => { 2132 2133 "use strict"; 2134 module.exports = window["React"]; 2135 2136 /***/ }), 2137 2138 /***/ 1670: 2139 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 2140 2141 "use strict"; 2142 2143 2144 let { dirname, relative, resolve, sep } = __webpack_require__(197) 2145 let { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(1866) 2146 let { pathToFileURL } = __webpack_require__(2739) 2147 2148 let Input = __webpack_require__(5380) 2149 2150 let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) 2151 let pathAvailable = Boolean(dirname && resolve && relative && sep) 2152 2153 class MapGenerator { 2154 constructor(stringify, root, opts, cssString) { 2155 this.stringify = stringify 2156 this.mapOpts = opts.map || {} 2157 this.root = root 2158 this.opts = opts 2159 this.css = cssString 2160 this.originalCSS = cssString 2161 this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute 2162 2163 this.memoizedFileURLs = new Map() 2164 this.memoizedPaths = new Map() 2165 this.memoizedURLs = new Map() 2166 } 2167 2168 addAnnotation() { 2169 let content 2170 2171 if (this.isInline()) { 2172 content = 2173 'data:application/json;base64,' + this.toBase64(this.map.toString()) 2174 } else if (typeof this.mapOpts.annotation === 'string') { 2175 content = this.mapOpts.annotation 2176 } else if (typeof this.mapOpts.annotation === 'function') { 2177 content = this.mapOpts.annotation(this.opts.to, this.root) 2178 } else { 2179 content = this.outputFile() + '.map' 2180 } 2181 let eol = '\n' 2182 if (this.css.includes('\r\n')) eol = '\r\n' 2183 2184 this.css += eol + '/*# sourceMappingURL=' + content + ' */' 2185 } 2186 2187 applyPrevMaps() { 2188 for (let prev of this.previous()) { 2189 let from = this.toUrl(this.path(prev.file)) 2190 let root = prev.root || dirname(prev.file) 2191 let map 2192 2193 if (this.mapOpts.sourcesContent === false) { 2194 map = new SourceMapConsumer(prev.text) 2195 if (map.sourcesContent) { 2196 map.sourcesContent = null 2197 } 2198 } else { 2199 map = prev.consumer() 2200 } 2201 2202 this.map.applySourceMap(map, from, this.toUrl(this.path(root))) 2203 } 2204 } 2205 2206 clearAnnotation() { 2207 if (this.mapOpts.annotation === false) return 2208 2209 if (this.root) { 2210 let node 2211 for (let i = this.root.nodes.length - 1; i >= 0; i--) { 2212 node = this.root.nodes[i] 2213 if (node.type !== 'comment') continue 2214 if (node.text.startsWith('# sourceMappingURL=')) { 2215 this.root.removeChild(i) 2216 } 2217 } 2218 } else if (this.css) { 2219 this.css = this.css.replace(/\n*\/\*#[\S\s]*?\*\/$/gm, '') 2220 } 2221 } 2222 2223 generate() { 2224 this.clearAnnotation() 2225 if (pathAvailable && sourceMapAvailable && this.isMap()) { 2226 return this.generateMap() 2227 } else { 2228 let result = '' 2229 this.stringify(this.root, i => { 2230 result += i 2231 }) 2232 return [result] 2233 } 2234 } 2235 2236 generateMap() { 2237 if (this.root) { 2238 this.generateString() 2239 } else if (this.previous().length === 1) { 2240 let prev = this.previous()[0].consumer() 2241 prev.file = this.outputFile() 2242 this.map = SourceMapGenerator.fromSourceMap(prev, { 2243 ignoreInvalidMapping: true 2244 }) 2245 } else { 2246 this.map = new SourceMapGenerator({ 2247 file: this.outputFile(), 2248 ignoreInvalidMapping: true 2249 }) 2250 this.map.addMapping({ 2251 generated: { column: 0, line: 1 }, 2252 original: { column: 0, line: 1 }, 2253 source: this.opts.from 2254 ? this.toUrl(this.path(this.opts.from)) 2255 : '<no source>' 2256 }) 2257 } 2258 2259 if (this.isSourcesContent()) this.setSourcesContent() 2260 if (this.root && this.previous().length > 0) this.applyPrevMaps() 2261 if (this.isAnnotation()) this.addAnnotation() 2262 2263 if (this.isInline()) { 2264 return [this.css] 2265 } else { 2266 return [this.css, this.map] 2267 } 2268 } 2269 2270 generateString() { 2271 this.css = '' 2272 this.map = new SourceMapGenerator({ 2273 file: this.outputFile(), 2274 ignoreInvalidMapping: true 2275 }) 2276 2277 let line = 1 2278 let column = 1 2279 2280 let noSource = '<no source>' 2281 let mapping = { 2282 generated: { column: 0, line: 0 }, 2283 original: { column: 0, line: 0 }, 2284 source: '' 2285 } 2286 2287 let last, lines 2288 this.stringify(this.root, (str, node, type) => { 2289 this.css += str 2290 2291 if (node && type !== 'end') { 2292 mapping.generated.line = line 2293 mapping.generated.column = column - 1 2294 if (node.source && node.source.start) { 2295 mapping.source = this.sourcePath(node) 2296 mapping.original.line = node.source.start.line 2297 mapping.original.column = node.source.start.column - 1 2298 this.map.addMapping(mapping) 2299 } else { 2300 mapping.source = noSource 2301 mapping.original.line = 1 2302 mapping.original.column = 0 2303 this.map.addMapping(mapping) 2304 } 2305 } 2306 2307 lines = str.match(/\n/g) 2308 if (lines) { 2309 line += lines.length 2310 last = str.lastIndexOf('\n') 2311 column = str.length - last 2312 } else { 2313 column += str.length 2314 } 2315 2316 if (node && type !== 'start') { 2317 let p = node.parent || { raws: {} } 2318 let childless = 2319 node.type === 'decl' || (node.type === 'atrule' && !node.nodes) 2320 if (!childless || node !== p.last || p.raws.semicolon) { 2321 if (node.source && node.source.end) { 2322 mapping.source = this.sourcePath(node) 2323 mapping.original.line = node.source.end.line 2324 mapping.original.column = node.source.end.column - 1 2325 mapping.generated.line = line 2326 mapping.generated.column = column - 2 2327 this.map.addMapping(mapping) 2328 } else { 2329 mapping.source = noSource 2330 mapping.original.line = 1 2331 mapping.original.column = 0 2332 mapping.generated.line = line 2333 mapping.generated.column = column - 1 2334 this.map.addMapping(mapping) 2335 } 2336 } 2337 } 2338 }) 2339 } 2340 2341 isAnnotation() { 2342 if (this.isInline()) { 2343 return true 2344 } 2345 if (typeof this.mapOpts.annotation !== 'undefined') { 2346 return this.mapOpts.annotation 2347 } 2348 if (this.previous().length) { 2349 return this.previous().some(i => i.annotation) 2350 } 2351 return true 2352 } 2353 2354 isInline() { 2355 if (typeof this.mapOpts.inline !== 'undefined') { 2356 return this.mapOpts.inline 2357 } 2358 2359 let annotation = this.mapOpts.annotation 2360 if (typeof annotation !== 'undefined' && annotation !== true) { 2361 return false 2362 } 2363 2364 if (this.previous().length) { 2365 return this.previous().some(i => i.inline) 2366 } 2367 return true 2368 } 2369 2370 isMap() { 2371 if (typeof this.opts.map !== 'undefined') { 2372 return !!this.opts.map 2373 } 2374 return this.previous().length > 0 2375 } 2376 2377 isSourcesContent() { 2378 if (typeof this.mapOpts.sourcesContent !== 'undefined') { 2379 return this.mapOpts.sourcesContent 2380 } 2381 if (this.previous().length) { 2382 return this.previous().some(i => i.withContent()) 2383 } 2384 return true 2385 } 2386 2387 outputFile() { 2388 if (this.opts.to) { 2389 return this.path(this.opts.to) 2390 } else if (this.opts.from) { 2391 return this.path(this.opts.from) 2392 } else { 2393 return 'to.css' 2394 } 2395 } 2396 2397 path(file) { 2398 if (this.mapOpts.absolute) return file 2399 if (file.charCodeAt(0) === 60 /* `<` */) return file 2400 if (/^\w+:\/\//.test(file)) return file 2401 let cached = this.memoizedPaths.get(file) 2402 if (cached) return cached 2403 2404 let from = this.opts.to ? dirname(this.opts.to) : '.' 2405 2406 if (typeof this.mapOpts.annotation === 'string') { 2407 from = dirname(resolve(from, this.mapOpts.annotation)) 2408 } 2409 2410 let path = relative(from, file) 2411 this.memoizedPaths.set(file, path) 2412 2413 return path 2414 } 2415 2416 previous() { 2417 if (!this.previousMaps) { 2418 this.previousMaps = [] 2419 if (this.root) { 2420 this.root.walk(node => { 2421 if (node.source && node.source.input.map) { 2422 let map = node.source.input.map 2423 if (!this.previousMaps.includes(map)) { 2424 this.previousMaps.push(map) 2425 } 2426 } 2427 }) 2428 } else { 2429 let input = new Input(this.originalCSS, this.opts) 2430 if (input.map) this.previousMaps.push(input.map) 2431 } 2432 } 2433 2434 return this.previousMaps 2435 } 2436 2437 setSourcesContent() { 2438 let already = {} 2439 if (this.root) { 2440 this.root.walk(node => { 2441 if (node.source) { 2442 let from = node.source.input.from 2443 if (from && !already[from]) { 2444 already[from] = true 2445 let fromUrl = this.usesFileUrls 2446 ? this.toFileUrl(from) 2447 : this.toUrl(this.path(from)) 2448 this.map.setSourceContent(fromUrl, node.source.input.css) 2449 } 2450 } 2451 }) 2452 } else if (this.css) { 2453 let from = this.opts.from 2454 ? this.toUrl(this.path(this.opts.from)) 2455 : '<no source>' 2456 this.map.setSourceContent(from, this.css) 2457 } 2458 } 2459 2460 sourcePath(node) { 2461 if (this.mapOpts.from) { 2462 return this.toUrl(this.mapOpts.from) 2463 } else if (this.usesFileUrls) { 2464 return this.toFileUrl(node.source.input.from) 2465 } else { 2466 return this.toUrl(this.path(node.source.input.from)) 2467 } 2468 } 2469 2470 toBase64(str) { 2471 if (Buffer) { 2472 return Buffer.from(str).toString('base64') 2473 } else { 2474 return window.btoa(unescape(encodeURIComponent(str))) 2475 } 2476 } 2477 2478 toFileUrl(path) { 2479 let cached = this.memoizedFileURLs.get(path) 2480 if (cached) return cached 2481 2482 if (pathToFileURL) { 2483 let fileURL = pathToFileURL(path).toString() 2484 this.memoizedFileURLs.set(path, fileURL) 2485 2486 return fileURL 2487 } else { 2488 throw new Error( 2489 '`map.absolute` option is not available in this PostCSS build' 2490 ) 2491 } 2492 } 2493 2494 toUrl(path) { 2495 let cached = this.memoizedURLs.get(path) 2496 if (cached) return cached 2497 2498 if (sep === '\\') { 2499 path = path.replace(/\\/g, '/') 2500 } 2501 2502 let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent) 2503 this.memoizedURLs.set(path, url) 2504 2505 return url 2506 } 2507 } 2508 2509 module.exports = MapGenerator 2510 2511 2512 /***/ }), 2513 2514 /***/ 1866: 2515 /***/ (() => { 2516 2517 /* (ignored) */ 2518 2519 /***/ }), 2520 2521 /***/ 2213: 2522 /***/ ((module) => { 2523 2524 /** 2525 * Copyright 2004-present Facebook. All Rights Reserved. 2526 * 2527 * @providesModule UserAgent_DEPRECATED 2528 */ 2529 2530 /** 2531 * Provides entirely client-side User Agent and OS detection. You should prefer 2532 * the non-deprecated UserAgent module when possible, which exposes our 2533 * authoritative server-side PHP-based detection to the client. 2534 * 2535 * Usage is straightforward: 2536 * 2537 * if (UserAgent_DEPRECATED.ie()) { 2538 * // IE 2539 * } 2540 * 2541 * You can also do version checks: 2542 * 2543 * if (UserAgent_DEPRECATED.ie() >= 7) { 2544 * // IE7 or better 2545 * } 2546 * 2547 * The browser functions will return NaN if the browser does not match, so 2548 * you can also do version compares the other way: 2549 * 2550 * if (UserAgent_DEPRECATED.ie() < 7) { 2551 * // IE6 or worse 2552 * } 2553 * 2554 * Note that the version is a float and may include a minor version number, 2555 * so you should always use range operators to perform comparisons, not 2556 * strict equality. 2557 * 2558 * **Note:** You should **strongly** prefer capability detection to browser 2559 * version detection where it's reasonable: 2560 * 2561 * http://www.quirksmode.org/js/support.html 2562 * 2563 * Further, we have a large number of mature wrapper functions and classes 2564 * which abstract away many browser irregularities. Check the documentation, 2565 * grep for things, or ask on javascript@lists.facebook.com before writing yet 2566 * another copy of "event || window.event". 2567 * 2568 */ 2569 2570 var _populated = false; 2571 2572 // Browsers 2573 var _ie, _firefox, _opera, _webkit, _chrome; 2574 2575 // Actual IE browser for compatibility mode 2576 var _ie_real_version; 2577 2578 // Platforms 2579 var _osx, _windows, _linux, _android; 2580 2581 // Architectures 2582 var _win64; 2583 2584 // Devices 2585 var _iphone, _ipad, _native; 2586 2587 var _mobile; 2588 2589 function _populate() { 2590 if (_populated) { 2591 return; 2592 } 2593 2594 _populated = true; 2595 2596 // To work around buggy JS libraries that can't handle multi-digit 2597 // version numbers, Opera 10's user agent string claims it's Opera 2598 // 9, then later includes a Version/X.Y field: 2599 // 2600 // Opera/9.80 (foo) Presto/2.2.15 Version/10.10 2601 var uas = navigator.userAgent; 2602 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); 2603 var os = /(Mac OS X)|(Windows)|(Linux)/.exec(uas); 2604 2605 _iphone = /\b(iPhone|iP[ao]d)/.exec(uas); 2606 _ipad = /\b(iP[ao]d)/.exec(uas); 2607 _android = /Android/i.exec(uas); 2608 _native = /FBAN\/\w+;/i.exec(uas); 2609 _mobile = /Mobile/i.exec(uas); 2610 2611 // Note that the IE team blog would have you believe you should be checking 2612 // for 'Win64; x64'. But MSDN then reveals that you can actually be coming 2613 // from either x64 or ia64; so ultimately, you should just check for Win64 2614 // as in indicator of whether you're in 64-bit IE. 32-bit IE on 64-bit 2615 // Windows will send 'WOW64' instead. 2616 _win64 = !!(/Win64/.exec(uas)); 2617 2618 if (agent) { 2619 _ie = agent[1] ? parseFloat(agent[1]) : ( 2620 agent[5] ? parseFloat(agent[5]) : NaN); 2621 // IE compatibility mode 2622 if (_ie && document && document.documentMode) { 2623 _ie = document.documentMode; 2624 } 2625 // grab the "true" ie version from the trident token if available 2626 var trident = /(?:Trident\/(\d+.\d+))/.exec(uas); 2627 _ie_real_version = trident ? parseFloat(trident[1]) + 4 : _ie; 2628 2629 _firefox = agent[2] ? parseFloat(agent[2]) : NaN; 2630 _opera = agent[3] ? parseFloat(agent[3]) : NaN; 2631 _webkit = agent[4] ? parseFloat(agent[4]) : NaN; 2632 if (_webkit) { 2633 // We do not add the regexp to the above test, because it will always 2634 // match 'safari' only since 'AppleWebKit' appears before 'Chrome' in 2635 // the userAgent string. 2636 agent = /(?:Chrome\/(\d+\.\d+))/.exec(uas); 2637 _chrome = agent && agent[1] ? parseFloat(agent[1]) : NaN; 2638 } else { 2639 _chrome = NaN; 2640 } 2641 } else { 2642 _ie = _firefox = _opera = _chrome = _webkit = NaN; 2643 } 2644 2645 if (os) { 2646 if (os[1]) { 2647 // Detect OS X version. If no version number matches, set _osx to true. 2648 // Version examples: 10, 10_6_1, 10.7 2649 // Parses version number as a float, taking only first two sets of 2650 // digits. If only one set of digits is found, returns just the major 2651 // version number. 2652 var ver = /(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(uas); 2653 2654 _osx = ver ? parseFloat(ver[1].replace('_', '.')) : true; 2655 } else { 2656 _osx = false; 2657 } 2658 _windows = !!os[2]; 2659 _linux = !!os[3]; 2660 } else { 2661 _osx = _windows = _linux = false; 2662 } 2663 } 2664 2665 var UserAgent_DEPRECATED = { 2666 2667 /** 2668 * Check if the UA is Internet Explorer. 2669 * 2670 * 2671 * @return float|NaN Version number (if match) or NaN. 2672 */ 2673 ie: function() { 2674 return _populate() || _ie; 2675 }, 2676 2677 /** 2678 * Check if we're in Internet Explorer compatibility mode. 2679 * 2680 * @return bool true if in compatibility mode, false if 2681 * not compatibility mode or not ie 2682 */ 2683 ieCompatibilityMode: function() { 2684 return _populate() || (_ie_real_version > _ie); 2685 }, 2686 2687 2688 /** 2689 * Whether the browser is 64-bit IE. Really, this is kind of weak sauce; we 2690 * only need this because Skype can't handle 64-bit IE yet. We need to remove 2691 * this when we don't need it -- tracked by #601957. 2692 */ 2693 ie64: function() { 2694 return UserAgent_DEPRECATED.ie() && _win64; 2695 }, 2696 2697 /** 2698 * Check if the UA is Firefox. 2699 * 2700 * 2701 * @return float|NaN Version number (if match) or NaN. 2702 */ 2703 firefox: function() { 2704 return _populate() || _firefox; 2705 }, 2706 2707 2708 /** 2709 * Check if the UA is Opera. 2710 * 2711 * 2712 * @return float|NaN Version number (if match) or NaN. 2713 */ 2714 opera: function() { 2715 return _populate() || _opera; 2716 }, 2717 2718 2719 /** 2720 * Check if the UA is WebKit. 2721 * 2722 * 2723 * @return float|NaN Version number (if match) or NaN. 2724 */ 2725 webkit: function() { 2726 return _populate() || _webkit; 2727 }, 2728 2729 /** 2730 * For Push 2731 * WILL BE REMOVED VERY SOON. Use UserAgent_DEPRECATED.webkit 2732 */ 2733 safari: function() { 2734 return UserAgent_DEPRECATED.webkit(); 2735 }, 2736 2737 /** 2738 * Check if the UA is a Chrome browser. 2739 * 2740 * 2741 * @return float|NaN Version number (if match) or NaN. 2742 */ 2743 chrome : function() { 2744 return _populate() || _chrome; 2745 }, 2746 2747 2748 /** 2749 * Check if the user is running Windows. 2750 * 2751 * @return bool `true' if the user's OS is Windows. 2752 */ 2753 windows: function() { 2754 return _populate() || _windows; 2755 }, 2756 2757 2758 /** 2759 * Check if the user is running Mac OS X. 2760 * 2761 * @return float|bool Returns a float if a version number is detected, 2762 * otherwise true/false. 2763 */ 2764 osx: function() { 2765 return _populate() || _osx; 2766 }, 2767 2768 /** 2769 * Check if the user is running Linux. 2770 * 2771 * @return bool `true' if the user's OS is some flavor of Linux. 2772 */ 2773 linux: function() { 2774 return _populate() || _linux; 2775 }, 2776 2777 /** 2778 * Check if the user is running on an iPhone or iPod platform. 2779 * 2780 * @return bool `true' if the user is running some flavor of the 2781 * iPhone OS. 2782 */ 2783 iphone: function() { 2784 return _populate() || _iphone; 2785 }, 2786 2787 mobile: function() { 2788 return _populate() || (_iphone || _ipad || _android || _mobile); 2789 }, 2790 2791 nativeApp: function() { 2792 // webviews inside of the native apps 2793 return _populate() || _native; 2794 }, 2795 2796 android: function() { 2797 return _populate() || _android; 2798 }, 2799 2800 ipad: function() { 2801 return _populate() || _ipad; 2802 } 2803 }; 2804 2805 module.exports = UserAgent_DEPRECATED; 2806 2807 2808 /***/ }), 2809 2810 /***/ 2327: 2811 /***/ ((module) => { 2812 2813 "use strict"; 2814 2815 2816 const SINGLE_QUOTE = "'".charCodeAt(0) 2817 const DOUBLE_QUOTE = '"'.charCodeAt(0) 2818 const BACKSLASH = '\\'.charCodeAt(0) 2819 const SLASH = '/'.charCodeAt(0) 2820 const NEWLINE = '\n'.charCodeAt(0) 2821 const SPACE = ' '.charCodeAt(0) 2822 const FEED = '\f'.charCodeAt(0) 2823 const TAB = '\t'.charCodeAt(0) 2824 const CR = '\r'.charCodeAt(0) 2825 const OPEN_SQUARE = '['.charCodeAt(0) 2826 const CLOSE_SQUARE = ']'.charCodeAt(0) 2827 const OPEN_PARENTHESES = '('.charCodeAt(0) 2828 const CLOSE_PARENTHESES = ')'.charCodeAt(0) 2829 const OPEN_CURLY = '{'.charCodeAt(0) 2830 const CLOSE_CURLY = '}'.charCodeAt(0) 2831 const SEMICOLON = ';'.charCodeAt(0) 2832 const ASTERISK = '*'.charCodeAt(0) 2833 const COLON = ':'.charCodeAt(0) 2834 const AT = '@'.charCodeAt(0) 2835 2836 const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g 2837 const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g 2838 const RE_BAD_BRACKET = /.[\r\n"'(/\\]/ 2839 const RE_HEX_ESCAPE = /[\da-f]/i 2840 2841 module.exports = function tokenizer(input, options = {}) { 2842 let css = input.css.valueOf() 2843 let ignore = options.ignoreErrors 2844 2845 let code, content, escape, next, quote 2846 let currentToken, escaped, escapePos, n, prev 2847 2848 let length = css.length 2849 let pos = 0 2850 let buffer = [] 2851 let returned = [] 2852 2853 function position() { 2854 return pos 2855 } 2856 2857 function unclosed(what) { 2858 throw input.error('Unclosed ' + what, pos) 2859 } 2860 2861 function endOfFile() { 2862 return returned.length === 0 && pos >= length 2863 } 2864 2865 function nextToken(opts) { 2866 if (returned.length) return returned.pop() 2867 if (pos >= length) return 2868 2869 let ignoreUnclosed = opts ? opts.ignoreUnclosed : false 2870 2871 code = css.charCodeAt(pos) 2872 2873 switch (code) { 2874 case NEWLINE: 2875 case SPACE: 2876 case TAB: 2877 case CR: 2878 case FEED: { 2879 next = pos 2880 do { 2881 next += 1 2882 code = css.charCodeAt(next) 2883 } while ( 2884 code === SPACE || 2885 code === NEWLINE || 2886 code === TAB || 2887 code === CR || 2888 code === FEED 2889 ) 2890 2891 currentToken = ['space', css.slice(pos, next)] 2892 pos = next - 1 2893 break 2894 } 2895 2896 case OPEN_SQUARE: 2897 case CLOSE_SQUARE: 2898 case OPEN_CURLY: 2899 case CLOSE_CURLY: 2900 case COLON: 2901 case SEMICOLON: 2902 case CLOSE_PARENTHESES: { 2903 let controlChar = String.fromCharCode(code) 2904 currentToken = [controlChar, controlChar, pos] 2905 break 2906 } 2907 2908 case OPEN_PARENTHESES: { 2909 prev = buffer.length ? buffer.pop()[1] : '' 2910 n = css.charCodeAt(pos + 1) 2911 if ( 2912 prev === 'url' && 2913 n !== SINGLE_QUOTE && 2914 n !== DOUBLE_QUOTE && 2915 n !== SPACE && 2916 n !== NEWLINE && 2917 n !== TAB && 2918 n !== FEED && 2919 n !== CR 2920 ) { 2921 next = pos 2922 do { 2923 escaped = false 2924 next = css.indexOf(')', next + 1) 2925 if (next === -1) { 2926 if (ignore || ignoreUnclosed) { 2927 next = pos 2928 break 2929 } else { 2930 unclosed('bracket') 2931 } 2932 } 2933 escapePos = next 2934 while (css.charCodeAt(escapePos - 1) === BACKSLASH) { 2935 escapePos -= 1 2936 escaped = !escaped 2937 } 2938 } while (escaped) 2939 2940 currentToken = ['brackets', css.slice(pos, next + 1), pos, next] 2941 2942 pos = next 2943 } else { 2944 next = css.indexOf(')', pos + 1) 2945 content = css.slice(pos, next + 1) 2946 2947 if (next === -1 || RE_BAD_BRACKET.test(content)) { 2948 currentToken = ['(', '(', pos] 2949 } else { 2950 currentToken = ['brackets', content, pos, next] 2951 pos = next 2952 } 2953 } 2954 2955 break 2956 } 2957 2958 case SINGLE_QUOTE: 2959 case DOUBLE_QUOTE: { 2960 quote = code === SINGLE_QUOTE ? "'" : '"' 2961 next = pos 2962 do { 2963 escaped = false 2964 next = css.indexOf(quote, next + 1) 2965 if (next === -1) { 2966 if (ignore || ignoreUnclosed) { 2967 next = pos + 1 2968 break 2969 } else { 2970 unclosed('string') 2971 } 2972 } 2973 escapePos = next 2974 while (css.charCodeAt(escapePos - 1) === BACKSLASH) { 2975 escapePos -= 1 2976 escaped = !escaped 2977 } 2978 } while (escaped) 2979 2980 currentToken = ['string', css.slice(pos, next + 1), pos, next] 2981 pos = next 2982 break 2983 } 2984 2985 case AT: { 2986 RE_AT_END.lastIndex = pos + 1 2987 RE_AT_END.test(css) 2988 if (RE_AT_END.lastIndex === 0) { 2989 next = css.length - 1 2990 } else { 2991 next = RE_AT_END.lastIndex - 2 2992 } 2993 2994 currentToken = ['at-word', css.slice(pos, next + 1), pos, next] 2995 2996 pos = next 2997 break 2998 } 2999 3000 case BACKSLASH: { 3001 next = pos 3002 escape = true 3003 while (css.charCodeAt(next + 1) === BACKSLASH) { 3004 next += 1 3005 escape = !escape 3006 } 3007 code = css.charCodeAt(next + 1) 3008 if ( 3009 escape && 3010 code !== SLASH && 3011 code !== SPACE && 3012 code !== NEWLINE && 3013 code !== TAB && 3014 code !== CR && 3015 code !== FEED 3016 ) { 3017 next += 1 3018 if (RE_HEX_ESCAPE.test(css.charAt(next))) { 3019 while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) { 3020 next += 1 3021 } 3022 if (css.charCodeAt(next + 1) === SPACE) { 3023 next += 1 3024 } 3025 } 3026 } 3027 3028 currentToken = ['word', css.slice(pos, next + 1), pos, next] 3029 3030 pos = next 3031 break 3032 } 3033 3034 default: { 3035 if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) { 3036 next = css.indexOf('*/', pos + 2) + 1 3037 if (next === 0) { 3038 if (ignore || ignoreUnclosed) { 3039 next = css.length 3040 } else { 3041 unclosed('comment') 3042 } 3043 } 3044 3045 currentToken = ['comment', css.slice(pos, next + 1), pos, next] 3046 pos = next 3047 } else { 3048 RE_WORD_END.lastIndex = pos + 1 3049 RE_WORD_END.test(css) 3050 if (RE_WORD_END.lastIndex === 0) { 3051 next = css.length - 1 3052 } else { 3053 next = RE_WORD_END.lastIndex - 2 3054 } 3055 3056 currentToken = ['word', css.slice(pos, next + 1), pos, next] 3057 buffer.push(currentToken) 3058 pos = next 3059 } 3060 3061 break 3062 } 3063 } 3064 3065 pos++ 3066 return currentToken 3067 } 3068 3069 function back(token) { 3070 returned.push(token) 3071 } 3072 3073 return { 3074 back, 3075 endOfFile, 3076 nextToken, 3077 position 3078 } 3079 } 3080 3081 3082 /***/ }), 3083 3084 /***/ 2739: 3085 /***/ (() => { 3086 3087 /* (ignored) */ 3088 3089 /***/ }), 3090 3091 /***/ 2775: 3092 /***/ ((module) => { 3093 3094 var x=String; 3095 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,blackBright:x,redBright:x,greenBright:x,yellowBright:x,blueBright:x,magentaBright:x,cyanBright:x,whiteBright:x,bgBlackBright:x,bgRedBright:x,bgGreenBright:x,bgYellowBright:x,bgBlueBright:x,bgMagentaBright:x,bgCyanBright:x,bgWhiteBright:x}}; 3096 module.exports=create(); 3097 module.exports.createColors = create; 3098 3099 3100 /***/ }), 3101 3102 /***/ 3122: 3103 /***/ ((module) => { 3104 3105 "use strict"; 3106 /* eslint-disable no-console */ 3107 3108 3109 let printed = {} 3110 3111 module.exports = function warnOnce(message) { 3112 if (printed[message]) return 3113 printed[message] = true 3114 3115 if (typeof console !== 'undefined' && console.warn) { 3116 console.warn(message) 3117 } 3118 } 3119 3120 3121 /***/ }), 3122 3123 /***/ 3815: 3124 /***/ ((module) => { 3125 3126 module.exports = function walk(nodes, cb, bubble) { 3127 var i, max, node, result; 3128 3129 for (i = 0, max = nodes.length; i < max; i += 1) { 3130 node = nodes[i]; 3131 if (!bubble) { 3132 result = cb(node, i, nodes); 3133 } 3134 3135 if ( 3136 result !== false && 3137 node.type === "function" && 3138 Array.isArray(node.nodes) 3139 ) { 3140 walk(node.nodes, cb, bubble); 3141 } 3142 3143 if (bubble) { 3144 cb(node, i, nodes); 3145 } 3146 } 3147 }; 3148 3149 3150 /***/ }), 3151 3152 /***/ 3937: 3153 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3154 3155 "use strict"; 3156 3157 3158 let AtRule = __webpack_require__(1326) 3159 let Comment = __webpack_require__(6589) 3160 let Declaration = __webpack_require__(1516) 3161 let Root = __webpack_require__(9434) 3162 let Rule = __webpack_require__(4092) 3163 let tokenizer = __webpack_require__(2327) 3164 3165 const SAFE_COMMENT_NEIGHBOR = { 3166 empty: true, 3167 space: true 3168 } 3169 3170 function findLastWithPosition(tokens) { 3171 for (let i = tokens.length - 1; i >= 0; i--) { 3172 let token = tokens[i] 3173 let pos = token[3] || token[2] 3174 if (pos) return pos 3175 } 3176 } 3177 3178 class Parser { 3179 constructor(input) { 3180 this.input = input 3181 3182 this.root = new Root() 3183 this.current = this.root 3184 this.spaces = '' 3185 this.semicolon = false 3186 3187 this.createTokenizer() 3188 this.root.source = { input, start: { column: 1, line: 1, offset: 0 } } 3189 } 3190 3191 atrule(token) { 3192 let node = new AtRule() 3193 node.name = token[1].slice(1) 3194 if (node.name === '') { 3195 this.unnamedAtrule(node, token) 3196 } 3197 this.init(node, token[2]) 3198 3199 let type 3200 let prev 3201 let shift 3202 let last = false 3203 let open = false 3204 let params = [] 3205 let brackets = [] 3206 3207 while (!this.tokenizer.endOfFile()) { 3208 token = this.tokenizer.nextToken() 3209 type = token[0] 3210 3211 if (type === '(' || type === '[') { 3212 brackets.push(type === '(' ? ')' : ']') 3213 } else if (type === '{' && brackets.length > 0) { 3214 brackets.push('}') 3215 } else if (type === brackets[brackets.length - 1]) { 3216 brackets.pop() 3217 } 3218 3219 if (brackets.length === 0) { 3220 if (type === ';') { 3221 node.source.end = this.getPosition(token[2]) 3222 node.source.end.offset++ 3223 this.semicolon = true 3224 break 3225 } else if (type === '{') { 3226 open = true 3227 break 3228 } else if (type === '}') { 3229 if (params.length > 0) { 3230 shift = params.length - 1 3231 prev = params[shift] 3232 while (prev && prev[0] === 'space') { 3233 prev = params[--shift] 3234 } 3235 if (prev) { 3236 node.source.end = this.getPosition(prev[3] || prev[2]) 3237 node.source.end.offset++ 3238 } 3239 } 3240 this.end(token) 3241 break 3242 } else { 3243 params.push(token) 3244 } 3245 } else { 3246 params.push(token) 3247 } 3248 3249 if (this.tokenizer.endOfFile()) { 3250 last = true 3251 break 3252 } 3253 } 3254 3255 node.raws.between = this.spacesAndCommentsFromEnd(params) 3256 if (params.length) { 3257 node.raws.afterName = this.spacesAndCommentsFromStart(params) 3258 this.raw(node, 'params', params) 3259 if (last) { 3260 token = params[params.length - 1] 3261 node.source.end = this.getPosition(token[3] || token[2]) 3262 node.source.end.offset++ 3263 this.spaces = node.raws.between 3264 node.raws.between = '' 3265 } 3266 } else { 3267 node.raws.afterName = '' 3268 node.params = '' 3269 } 3270 3271 if (open) { 3272 node.nodes = [] 3273 this.current = node 3274 } 3275 } 3276 3277 checkMissedSemicolon(tokens) { 3278 let colon = this.colon(tokens) 3279 if (colon === false) return 3280 3281 let founded = 0 3282 let token 3283 for (let j = colon - 1; j >= 0; j--) { 3284 token = tokens[j] 3285 if (token[0] !== 'space') { 3286 founded += 1 3287 if (founded === 2) break 3288 } 3289 } 3290 // If the token is a word, e.g. `!important`, `red` or any other valid property's value. 3291 // Then we need to return the colon after that word token. [3] is the "end" colon of that word. 3292 // And because we need it after that one we do +1 to get the next one. 3293 throw this.input.error( 3294 'Missed semicolon', 3295 token[0] === 'word' ? token[3] + 1 : token[2] 3296 ) 3297 } 3298 3299 colon(tokens) { 3300 let brackets = 0 3301 let prev, token, type 3302 for (let [i, element] of tokens.entries()) { 3303 token = element 3304 type = token[0] 3305 3306 if (type === '(') { 3307 brackets += 1 3308 } 3309 if (type === ')') { 3310 brackets -= 1 3311 } 3312 if (brackets === 0 && type === ':') { 3313 if (!prev) { 3314 this.doubleColon(token) 3315 } else if (prev[0] === 'word' && prev[1] === 'progid') { 3316 continue 3317 } else { 3318 return i 3319 } 3320 } 3321 3322 prev = token 3323 } 3324 return false 3325 } 3326 3327 comment(token) { 3328 let node = new Comment() 3329 this.init(node, token[2]) 3330 node.source.end = this.getPosition(token[3] || token[2]) 3331 node.source.end.offset++ 3332 3333 let text = token[1].slice(2, -2) 3334 if (/^\s*$/.test(text)) { 3335 node.text = '' 3336 node.raws.left = text 3337 node.raws.right = '' 3338 } else { 3339 let match = text.match(/^(\s*)([^]*\S)(\s*)$/) 3340 node.text = match[2] 3341 node.raws.left = match[1] 3342 node.raws.right = match[3] 3343 } 3344 } 3345 3346 createTokenizer() { 3347 this.tokenizer = tokenizer(this.input) 3348 } 3349 3350 decl(tokens, customProperty) { 3351 let node = new Declaration() 3352 this.init(node, tokens[0][2]) 3353 3354 let last = tokens[tokens.length - 1] 3355 if (last[0] === ';') { 3356 this.semicolon = true 3357 tokens.pop() 3358 } 3359 3360 node.source.end = this.getPosition( 3361 last[3] || last[2] || findLastWithPosition(tokens) 3362 ) 3363 node.source.end.offset++ 3364 3365 while (tokens[0][0] !== 'word') { 3366 if (tokens.length === 1) this.unknownWord(tokens) 3367 node.raws.before += tokens.shift()[1] 3368 } 3369 node.source.start = this.getPosition(tokens[0][2]) 3370 3371 node.prop = '' 3372 while (tokens.length) { 3373 let type = tokens[0][0] 3374 if (type === ':' || type === 'space' || type === 'comment') { 3375 break 3376 } 3377 node.prop += tokens.shift()[1] 3378 } 3379 3380 node.raws.between = '' 3381 3382 let token 3383 while (tokens.length) { 3384 token = tokens.shift() 3385 3386 if (token[0] === ':') { 3387 node.raws.between += token[1] 3388 break 3389 } else { 3390 if (token[0] === 'word' && /\w/.test(token[1])) { 3391 this.unknownWord([token]) 3392 } 3393 node.raws.between += token[1] 3394 } 3395 } 3396 3397 if (node.prop[0] === '_' || node.prop[0] === '*') { 3398 node.raws.before += node.prop[0] 3399 node.prop = node.prop.slice(1) 3400 } 3401 3402 let firstSpaces = [] 3403 let next 3404 while (tokens.length) { 3405 next = tokens[0][0] 3406 if (next !== 'space' && next !== 'comment') break 3407 firstSpaces.push(tokens.shift()) 3408 } 3409 3410 this.precheckMissedSemicolon(tokens) 3411 3412 for (let i = tokens.length - 1; i >= 0; i--) { 3413 token = tokens[i] 3414 if (token[1].toLowerCase() === '!important') { 3415 node.important = true 3416 let string = this.stringFrom(tokens, i) 3417 string = this.spacesFromEnd(tokens) + string 3418 if (string !== ' !important') node.raws.important = string 3419 break 3420 } else if (token[1].toLowerCase() === 'important') { 3421 let cache = tokens.slice(0) 3422 let str = '' 3423 for (let j = i; j > 0; j--) { 3424 let type = cache[j][0] 3425 if (str.trim().startsWith('!') && type !== 'space') { 3426 break 3427 } 3428 str = cache.pop()[1] + str 3429 } 3430 if (str.trim().startsWith('!')) { 3431 node.important = true 3432 node.raws.important = str 3433 tokens = cache 3434 } 3435 } 3436 3437 if (token[0] !== 'space' && token[0] !== 'comment') { 3438 break 3439 } 3440 } 3441 3442 let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment') 3443 3444 if (hasWord) { 3445 node.raws.between += firstSpaces.map(i => i[1]).join('') 3446 firstSpaces = [] 3447 } 3448 this.raw(node, 'value', firstSpaces.concat(tokens), customProperty) 3449 3450 if (node.value.includes(':') && !customProperty) { 3451 this.checkMissedSemicolon(tokens) 3452 } 3453 } 3454 3455 doubleColon(token) { 3456 throw this.input.error( 3457 'Double colon', 3458 { offset: token[2] }, 3459 { offset: token[2] + token[1].length } 3460 ) 3461 } 3462 3463 emptyRule(token) { 3464 let node = new Rule() 3465 this.init(node, token[2]) 3466 node.selector = '' 3467 node.raws.between = '' 3468 this.current = node 3469 } 3470 3471 end(token) { 3472 if (this.current.nodes && this.current.nodes.length) { 3473 this.current.raws.semicolon = this.semicolon 3474 } 3475 this.semicolon = false 3476 3477 this.current.raws.after = (this.current.raws.after || '') + this.spaces 3478 this.spaces = '' 3479 3480 if (this.current.parent) { 3481 this.current.source.end = this.getPosition(token[2]) 3482 this.current.source.end.offset++ 3483 this.current = this.current.parent 3484 } else { 3485 this.unexpectedClose(token) 3486 } 3487 } 3488 3489 endFile() { 3490 if (this.current.parent) this.unclosedBlock() 3491 if (this.current.nodes && this.current.nodes.length) { 3492 this.current.raws.semicolon = this.semicolon 3493 } 3494 this.current.raws.after = (this.current.raws.after || '') + this.spaces 3495 this.root.source.end = this.getPosition(this.tokenizer.position()) 3496 } 3497 3498 freeSemicolon(token) { 3499 this.spaces += token[1] 3500 if (this.current.nodes) { 3501 let prev = this.current.nodes[this.current.nodes.length - 1] 3502 if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) { 3503 prev.raws.ownSemicolon = this.spaces 3504 this.spaces = '' 3505 prev.source.end = this.getPosition(token[2]) 3506 prev.source.end.offset += prev.raws.ownSemicolon.length 3507 } 3508 } 3509 } 3510 3511 // Helpers 3512 3513 getPosition(offset) { 3514 let pos = this.input.fromOffset(offset) 3515 return { 3516 column: pos.col, 3517 line: pos.line, 3518 offset 3519 } 3520 } 3521 3522 init(node, offset) { 3523 this.current.push(node) 3524 node.source = { 3525 input: this.input, 3526 start: this.getPosition(offset) 3527 } 3528 node.raws.before = this.spaces 3529 this.spaces = '' 3530 if (node.type !== 'comment') this.semicolon = false 3531 } 3532 3533 other(start) { 3534 let end = false 3535 let type = null 3536 let colon = false 3537 let bracket = null 3538 let brackets = [] 3539 let customProperty = start[1].startsWith('--') 3540 3541 let tokens = [] 3542 let token = start 3543 while (token) { 3544 type = token[0] 3545 tokens.push(token) 3546 3547 if (type === '(' || type === '[') { 3548 if (!bracket) bracket = token 3549 brackets.push(type === '(' ? ')' : ']') 3550 } else if (customProperty && colon && type === '{') { 3551 if (!bracket) bracket = token 3552 brackets.push('}') 3553 } else if (brackets.length === 0) { 3554 if (type === ';') { 3555 if (colon) { 3556 this.decl(tokens, customProperty) 3557 return 3558 } else { 3559 break 3560 } 3561 } else if (type === '{') { 3562 this.rule(tokens) 3563 return 3564 } else if (type === '}') { 3565 this.tokenizer.back(tokens.pop()) 3566 end = true 3567 break 3568 } else if (type === ':') { 3569 colon = true 3570 } 3571 } else if (type === brackets[brackets.length - 1]) { 3572 brackets.pop() 3573 if (brackets.length === 0) bracket = null 3574 } 3575 3576 token = this.tokenizer.nextToken() 3577 } 3578 3579 if (this.tokenizer.endOfFile()) end = true 3580 if (brackets.length > 0) this.unclosedBracket(bracket) 3581 3582 if (end && colon) { 3583 if (!customProperty) { 3584 while (tokens.length) { 3585 token = tokens[tokens.length - 1][0] 3586 if (token !== 'space' && token !== 'comment') break 3587 this.tokenizer.back(tokens.pop()) 3588 } 3589 } 3590 this.decl(tokens, customProperty) 3591 } else { 3592 this.unknownWord(tokens) 3593 } 3594 } 3595 3596 parse() { 3597 let token 3598 while (!this.tokenizer.endOfFile()) { 3599 token = this.tokenizer.nextToken() 3600 3601 switch (token[0]) { 3602 case 'space': 3603 this.spaces += token[1] 3604 break 3605 3606 case ';': 3607 this.freeSemicolon(token) 3608 break 3609 3610 case '}': 3611 this.end(token) 3612 break 3613 3614 case 'comment': 3615 this.comment(token) 3616 break 3617 3618 case 'at-word': 3619 this.atrule(token) 3620 break 3621 3622 case '{': 3623 this.emptyRule(token) 3624 break 3625 3626 default: 3627 this.other(token) 3628 break 3629 } 3630 } 3631 this.endFile() 3632 } 3633 3634 precheckMissedSemicolon(/* tokens */) { 3635 // Hook for Safe Parser 3636 } 3637 3638 raw(node, prop, tokens, customProperty) { 3639 let token, type 3640 let length = tokens.length 3641 let value = '' 3642 let clean = true 3643 let next, prev 3644 3645 for (let i = 0; i < length; i += 1) { 3646 token = tokens[i] 3647 type = token[0] 3648 if (type === 'space' && i === length - 1 && !customProperty) { 3649 clean = false 3650 } else if (type === 'comment') { 3651 prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty' 3652 next = tokens[i + 1] ? tokens[i + 1][0] : 'empty' 3653 if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) { 3654 if (value.slice(-1) === ',') { 3655 clean = false 3656 } else { 3657 value += token[1] 3658 } 3659 } else { 3660 clean = false 3661 } 3662 } else { 3663 value += token[1] 3664 } 3665 } 3666 if (!clean) { 3667 let raw = tokens.reduce((all, i) => all + i[1], '') 3668 node.raws[prop] = { raw, value } 3669 } 3670 node[prop] = value 3671 } 3672 3673 rule(tokens) { 3674 tokens.pop() 3675 3676 let node = new Rule() 3677 this.init(node, tokens[0][2]) 3678 3679 node.raws.between = this.spacesAndCommentsFromEnd(tokens) 3680 this.raw(node, 'selector', tokens) 3681 this.current = node 3682 } 3683 3684 spacesAndCommentsFromEnd(tokens) { 3685 let lastTokenType 3686 let spaces = '' 3687 while (tokens.length) { 3688 lastTokenType = tokens[tokens.length - 1][0] 3689 if (lastTokenType !== 'space' && lastTokenType !== 'comment') break 3690 spaces = tokens.pop()[1] + spaces 3691 } 3692 return spaces 3693 } 3694 3695 // Errors 3696 3697 spacesAndCommentsFromStart(tokens) { 3698 let next 3699 let spaces = '' 3700 while (tokens.length) { 3701 next = tokens[0][0] 3702 if (next !== 'space' && next !== 'comment') break 3703 spaces += tokens.shift()[1] 3704 } 3705 return spaces 3706 } 3707 3708 spacesFromEnd(tokens) { 3709 let lastTokenType 3710 let spaces = '' 3711 while (tokens.length) { 3712 lastTokenType = tokens[tokens.length - 1][0] 3713 if (lastTokenType !== 'space') break 3714 spaces = tokens.pop()[1] + spaces 3715 } 3716 return spaces 3717 } 3718 3719 stringFrom(tokens, from) { 3720 let result = '' 3721 for (let i = from; i < tokens.length; i++) { 3722 result += tokens[i][1] 3723 } 3724 tokens.splice(from, tokens.length - from) 3725 return result 3726 } 3727 3728 unclosedBlock() { 3729 let pos = this.current.source.start 3730 throw this.input.error('Unclosed block', pos.line, pos.column) 3731 } 3732 3733 unclosedBracket(bracket) { 3734 throw this.input.error( 3735 'Unclosed bracket', 3736 { offset: bracket[2] }, 3737 { offset: bracket[2] + 1 } 3738 ) 3739 } 3740 3741 unexpectedClose(token) { 3742 throw this.input.error( 3743 'Unexpected }', 3744 { offset: token[2] }, 3745 { offset: token[2] + 1 } 3746 ) 3747 } 3748 3749 unknownWord(tokens) { 3750 throw this.input.error( 3751 'Unknown word ' + tokens[0][1], 3752 { offset: tokens[0][2] }, 3753 { offset: tokens[0][2] + tokens[0][1].length } 3754 ) 3755 } 3756 3757 unnamedAtrule(node, token) { 3758 throw this.input.error( 3759 'At-rule without name', 3760 { offset: token[2] }, 3761 { offset: token[2] + token[1].length } 3762 ) 3763 } 3764 } 3765 3766 module.exports = Parser 3767 3768 3769 /***/ }), 3770 3771 /***/ 4067: 3772 /***/ ((module) => { 3773 3774 "use strict"; 3775 /** 3776 * Copyright (c) 2013-present, Facebook, Inc. 3777 * 3778 * This source code is licensed under the MIT license found in the 3779 * LICENSE file in the root directory of this source tree. 3780 */ 3781 3782 3783 3784 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; 3785 3786 module.exports = ReactPropTypesSecret; 3787 3788 3789 /***/ }), 3790 3791 /***/ 4092: 3792 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3793 3794 "use strict"; 3795 3796 3797 let Container = __webpack_require__(683) 3798 let list = __webpack_require__(7374) 3799 3800 class Rule extends Container { 3801 get selectors() { 3802 return list.comma(this.selector) 3803 } 3804 3805 set selectors(values) { 3806 let match = this.selector ? this.selector.match(/,\s*/) : null 3807 let sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen') 3808 this.selector = values.join(sep) 3809 } 3810 3811 constructor(defaults) { 3812 super(defaults) 3813 this.type = 'rule' 3814 if (!this.nodes) this.nodes = [] 3815 } 3816 } 3817 3818 module.exports = Rule 3819 Rule.default = Rule 3820 3821 Container.registerRule(Rule) 3822 3823 3824 /***/ }), 3825 3826 /***/ 4132: 3827 /***/ ((__unused_webpack_module, exports, __webpack_require__) => { 3828 3829 "use strict"; 3830 var __webpack_unused_export__; 3831 3832 __webpack_unused_export__ = true; 3833 var TextareaAutosize_1 = __webpack_require__(4462); 3834 exports.A = TextareaAutosize_1.TextareaAutosize; 3835 3836 3837 /***/ }), 3838 3839 /***/ 4295: 3840 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 3841 3842 "use strict"; 3843 3844 3845 let Container = __webpack_require__(683) 3846 let Input = __webpack_require__(5380) 3847 let Parser = __webpack_require__(3937) 3848 3849 function parse(css, opts) { 3850 let input = new Input(css, opts) 3851 let parser = new Parser(input) 3852 try { 3853 parser.parse() 3854 } catch (e) { 3855 if (false) {} 3856 throw e 3857 } 3858 3859 return parser.root 3860 } 3861 3862 module.exports = parse 3863 parse.default = parse 3864 3865 Container.registerParse(parse) 3866 3867 3868 /***/ }), 3869 3870 /***/ 4306: 3871 /***/ (function(module, exports) { 3872 3873 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 3874 autosize 4.0.4 3875 license: MIT 3876 http://www.jacklmoore.com/autosize 3877 */ 3878 (function (global, factory) { 3879 if (true) { 3880 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 3881 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 3882 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 3883 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 3884 } else { var mod; } 3885 })(this, function (module, exports) { 3886 'use strict'; 3887 3888 var map = typeof Map === "function" ? new Map() : function () { 3889 var keys = []; 3890 var values = []; 3891 3892 return { 3893 has: function has(key) { 3894 return keys.indexOf(key) > -1; 3895 }, 3896 get: function get(key) { 3897 return values[keys.indexOf(key)]; 3898 }, 3899 set: function set(key, value) { 3900 if (keys.indexOf(key) === -1) { 3901 keys.push(key); 3902 values.push(value); 3903 } 3904 }, 3905 delete: function _delete(key) { 3906 var index = keys.indexOf(key); 3907 if (index > -1) { 3908 keys.splice(index, 1); 3909 values.splice(index, 1); 3910 } 3911 } 3912 }; 3913 }(); 3914 3915 var createEvent = function createEvent(name) { 3916 return new Event(name, { bubbles: true }); 3917 }; 3918 try { 3919 new Event('test'); 3920 } catch (e) { 3921 // IE does not support `new Event()` 3922 createEvent = function createEvent(name) { 3923 var evt = document.createEvent('Event'); 3924 evt.initEvent(name, true, false); 3925 return evt; 3926 }; 3927 } 3928 3929 function assign(ta) { 3930 if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return; 3931 3932 var heightOffset = null; 3933 var clientWidth = null; 3934 var cachedHeight = null; 3935 3936 function init() { 3937 var style = window.getComputedStyle(ta, null); 3938 3939 if (style.resize === 'vertical') { 3940 ta.style.resize = 'none'; 3941 } else if (style.resize === 'both') { 3942 ta.style.resize = 'horizontal'; 3943 } 3944 3945 if (style.boxSizing === 'content-box') { 3946 heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); 3947 } else { 3948 heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); 3949 } 3950 // Fix when a textarea is not on document body and heightOffset is Not a Number 3951 if (isNaN(heightOffset)) { 3952 heightOffset = 0; 3953 } 3954 3955 update(); 3956 } 3957 3958 function changeOverflow(value) { 3959 { 3960 // Chrome/Safari-specific fix: 3961 // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space 3962 // made available by removing the scrollbar. The following forces the necessary text reflow. 3963 var width = ta.style.width; 3964 ta.style.width = '0px'; 3965 // Force reflow: 3966 /* jshint ignore:start */ 3967 ta.offsetWidth; 3968 /* jshint ignore:end */ 3969 ta.style.width = width; 3970 } 3971 3972 ta.style.overflowY = value; 3973 } 3974 3975 function getParentOverflows(el) { 3976 var arr = []; 3977 3978 while (el && el.parentNode && el.parentNode instanceof Element) { 3979 if (el.parentNode.scrollTop) { 3980 arr.push({ 3981 node: el.parentNode, 3982 scrollTop: el.parentNode.scrollTop 3983 }); 3984 } 3985 el = el.parentNode; 3986 } 3987 3988 return arr; 3989 } 3990 3991 function resize() { 3992 if (ta.scrollHeight === 0) { 3993 // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. 3994 return; 3995 } 3996 3997 var overflows = getParentOverflows(ta); 3998 var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240) 3999 4000 ta.style.height = ''; 4001 ta.style.height = ta.scrollHeight + heightOffset + 'px'; 4002 4003 // used to check if an update is actually necessary on window.resize 4004 clientWidth = ta.clientWidth; 4005 4006 // prevents scroll-position jumping 4007 overflows.forEach(function (el) { 4008 el.node.scrollTop = el.scrollTop; 4009 }); 4010 4011 if (docTop) { 4012 document.documentElement.scrollTop = docTop; 4013 } 4014 } 4015 4016 function update() { 4017 resize(); 4018 4019 var styleHeight = Math.round(parseFloat(ta.style.height)); 4020 var computed = window.getComputedStyle(ta, null); 4021 4022 // Using offsetHeight as a replacement for computed.height in IE, because IE does not account use of border-box 4023 var actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(computed.height)) : ta.offsetHeight; 4024 4025 // The actual height not matching the style height (set via the resize method) indicates that 4026 // the max-height has been exceeded, in which case the overflow should be allowed. 4027 if (actualHeight < styleHeight) { 4028 if (computed.overflowY === 'hidden') { 4029 changeOverflow('scroll'); 4030 resize(); 4031 actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(window.getComputedStyle(ta, null).height)) : ta.offsetHeight; 4032 } 4033 } else { 4034 // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. 4035 if (computed.overflowY !== 'hidden') { 4036 changeOverflow('hidden'); 4037 resize(); 4038 actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(window.getComputedStyle(ta, null).height)) : ta.offsetHeight; 4039 } 4040 } 4041 4042 if (cachedHeight !== actualHeight) { 4043 cachedHeight = actualHeight; 4044 var evt = createEvent('autosize:resized'); 4045 try { 4046 ta.dispatchEvent(evt); 4047 } catch (err) { 4048 // Firefox will throw an error on dispatchEvent for a detached element 4049 // https://bugzilla.mozilla.org/show_bug.cgi?id=889376 4050 } 4051 } 4052 } 4053 4054 var pageResize = function pageResize() { 4055 if (ta.clientWidth !== clientWidth) { 4056 update(); 4057 } 4058 }; 4059 4060 var destroy = function (style) { 4061 window.removeEventListener('resize', pageResize, false); 4062 ta.removeEventListener('input', update, false); 4063 ta.removeEventListener('keyup', update, false); 4064 ta.removeEventListener('autosize:destroy', destroy, false); 4065 ta.removeEventListener('autosize:update', update, false); 4066 4067 Object.keys(style).forEach(function (key) { 4068 ta.style[key] = style[key]; 4069 }); 4070 4071 map.delete(ta); 4072 }.bind(ta, { 4073 height: ta.style.height, 4074 resize: ta.style.resize, 4075 overflowY: ta.style.overflowY, 4076 overflowX: ta.style.overflowX, 4077 wordWrap: ta.style.wordWrap 4078 }); 4079 4080 ta.addEventListener('autosize:destroy', destroy, false); 4081 4082 // IE9 does not fire onpropertychange or oninput for deletions, 4083 // so binding to onkeyup to catch most of those events. 4084 // There is no way that I know of to detect something like 'cut' in IE9. 4085 if ('onpropertychange' in ta && 'oninput' in ta) { 4086 ta.addEventListener('keyup', update, false); 4087 } 4088 4089 window.addEventListener('resize', pageResize, false); 4090 ta.addEventListener('input', update, false); 4091 ta.addEventListener('autosize:update', update, false); 4092 ta.style.overflowX = 'hidden'; 4093 ta.style.wordWrap = 'break-word'; 4094 4095 map.set(ta, { 4096 destroy: destroy, 4097 update: update 4098 }); 4099 4100 init(); 4101 } 4102 4103 function destroy(ta) { 4104 var methods = map.get(ta); 4105 if (methods) { 4106 methods.destroy(); 4107 } 4108 } 4109 4110 function update(ta) { 4111 var methods = map.get(ta); 4112 if (methods) { 4113 methods.update(); 4114 } 4115 } 4116 4117 var autosize = null; 4118 4119 // Do nothing in Node.js environment and IE8 (or lower) 4120 if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { 4121 autosize = function autosize(el) { 4122 return el; 4123 }; 4124 autosize.destroy = function (el) { 4125 return el; 4126 }; 4127 autosize.update = function (el) { 4128 return el; 4129 }; 4130 } else { 4131 autosize = function autosize(el, options) { 4132 if (el) { 4133 Array.prototype.forEach.call(el.length ? el : [el], function (x) { 4134 return assign(x, options); 4135 }); 4136 } 4137 return el; 4138 }; 4139 autosize.destroy = function (el) { 4140 if (el) { 4141 Array.prototype.forEach.call(el.length ? el : [el], destroy); 4142 } 4143 return el; 4144 }; 4145 autosize.update = function (el) { 4146 if (el) { 4147 Array.prototype.forEach.call(el.length ? el : [el], update); 4148 } 4149 return el; 4150 }; 4151 } 4152 4153 exports.default = autosize; 4154 module.exports = exports['default']; 4155 }); 4156 4157 /***/ }), 4158 4159 /***/ 4462: 4160 /***/ (function(__unused_webpack_module, exports, __webpack_require__) { 4161 4162 "use strict"; 4163 4164 var __extends = (this && this.__extends) || (function () { 4165 var extendStatics = Object.setPrototypeOf || 4166 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 4167 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 4168 return function (d, b) { 4169 extendStatics(d, b); 4170 function __() { this.constructor = d; } 4171 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 4172 }; 4173 })(); 4174 var __assign = (this && this.__assign) || Object.assign || function(t) { 4175 for (var s, i = 1, n = arguments.length; i < n; i++) { 4176 s = arguments[i]; 4177 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) 4178 t[p] = s[p]; 4179 } 4180 return t; 4181 }; 4182 var __rest = (this && this.__rest) || function (s, e) { 4183 var t = {}; 4184 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 4185 t[p] = s[p]; 4186 if (s != null && typeof Object.getOwnPropertySymbols === "function") 4187 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) 4188 t[p[i]] = s[p[i]]; 4189 return t; 4190 }; 4191 exports.__esModule = true; 4192 var React = __webpack_require__(1609); 4193 var PropTypes = __webpack_require__(5826); 4194 var autosize = __webpack_require__(4306); 4195 var _getLineHeight = __webpack_require__(461); 4196 var getLineHeight = _getLineHeight; 4197 var RESIZED = "autosize:resized"; 4198 /** 4199 * A light replacement for built-in textarea component 4200 * which automaticaly adjusts its height to match the content 4201 */ 4202 var TextareaAutosizeClass = /** @class */ (function (_super) { 4203 __extends(TextareaAutosizeClass, _super); 4204 function TextareaAutosizeClass() { 4205 var _this = _super !== null && _super.apply(this, arguments) || this; 4206 _this.state = { 4207 lineHeight: null 4208 }; 4209 _this.textarea = null; 4210 _this.onResize = function (e) { 4211 if (_this.props.onResize) { 4212 _this.props.onResize(e); 4213 } 4214 }; 4215 _this.updateLineHeight = function () { 4216 if (_this.textarea) { 4217 _this.setState({ 4218 lineHeight: getLineHeight(_this.textarea) 4219 }); 4220 } 4221 }; 4222 _this.onChange = function (e) { 4223 var onChange = _this.props.onChange; 4224 _this.currentValue = e.currentTarget.value; 4225 onChange && onChange(e); 4226 }; 4227 return _this; 4228 } 4229 TextareaAutosizeClass.prototype.componentDidMount = function () { 4230 var _this = this; 4231 var _a = this.props, maxRows = _a.maxRows, async = _a.async; 4232 if (typeof maxRows === "number") { 4233 this.updateLineHeight(); 4234 } 4235 if (typeof maxRows === "number" || async) { 4236 /* 4237 the defer is needed to: 4238 - force "autosize" to activate the scrollbar when this.props.maxRows is passed 4239 - support StyledComponents (see #71) 4240 */ 4241 setTimeout(function () { return _this.textarea && autosize(_this.textarea); }); 4242 } 4243 else { 4244 this.textarea && autosize(this.textarea); 4245 } 4246 if (this.textarea) { 4247 this.textarea.addEventListener(RESIZED, this.onResize); 4248 } 4249 }; 4250 TextareaAutosizeClass.prototype.componentWillUnmount = function () { 4251 if (this.textarea) { 4252 this.textarea.removeEventListener(RESIZED, this.onResize); 4253 autosize.destroy(this.textarea); 4254 } 4255 }; 4256 TextareaAutosizeClass.prototype.render = function () { 4257 var _this = this; 4258 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; 4259 var maxHeight = maxRows && lineHeight ? lineHeight * maxRows : null; 4260 return (React.createElement("textarea", __assign({}, props, { onChange: this.onChange, style: maxHeight ? __assign({}, style, { maxHeight: maxHeight }) : style, ref: function (element) { 4261 _this.textarea = element; 4262 if (typeof _this.props.innerRef === 'function') { 4263 _this.props.innerRef(element); 4264 } 4265 else if (_this.props.innerRef) { 4266 _this.props.innerRef.current = element; 4267 } 4268 } }), children)); 4269 }; 4270 TextareaAutosizeClass.prototype.componentDidUpdate = function () { 4271 this.textarea && autosize.update(this.textarea); 4272 }; 4273 TextareaAutosizeClass.defaultProps = { 4274 rows: 1, 4275 async: false 4276 }; 4277 TextareaAutosizeClass.propTypes = { 4278 rows: PropTypes.number, 4279 maxRows: PropTypes.number, 4280 onResize: PropTypes.func, 4281 innerRef: PropTypes.any, 4282 async: PropTypes.bool 4283 }; 4284 return TextareaAutosizeClass; 4285 }(React.Component)); 4286 exports.TextareaAutosize = React.forwardRef(function (props, ref) { 4287 return React.createElement(TextareaAutosizeClass, __assign({}, props, { innerRef: ref })); 4288 }); 4289 4290 4291 /***/ }), 4292 4293 /***/ 4725: 4294 /***/ ((module) => { 4295 4296 function stringifyNode(node, custom) { 4297 var type = node.type; 4298 var value = node.value; 4299 var buf; 4300 var customResult; 4301 4302 if (custom && (customResult = custom(node)) !== undefined) { 4303 return customResult; 4304 } else if (type === "word" || type === "space") { 4305 return value; 4306 } else if (type === "string") { 4307 buf = node.quote || ""; 4308 return buf + value + (node.unclosed ? "" : buf); 4309 } else if (type === "comment") { 4310 return "/*" + value + (node.unclosed ? "" : "*/"); 4311 } else if (type === "div") { 4312 return (node.before || "") + value + (node.after || ""); 4313 } else if (Array.isArray(node.nodes)) { 4314 buf = stringify(node.nodes, custom); 4315 if (type !== "function") { 4316 return buf; 4317 } 4318 return ( 4319 value + 4320 "(" + 4321 (node.before || "") + 4322 buf + 4323 (node.after || "") + 4324 (node.unclosed ? "" : ")") 4325 ); 4326 } 4327 return value; 4328 } 4329 4330 function stringify(nodes, custom) { 4331 var result, i; 4332 4333 if (Array.isArray(nodes)) { 4334 result = ""; 4335 for (i = nodes.length - 1; ~i; i -= 1) { 4336 result = stringifyNode(nodes[i], custom) + result; 4337 } 4338 return result; 4339 } 4340 return stringifyNode(nodes, custom); 4341 } 4342 4343 module.exports = stringify; 4344 4345 4346 /***/ }), 4347 4348 /***/ 5042: 4349 /***/ ((module) => { 4350 4351 // This alphabet uses `A-Za-z0-9_-` symbols. 4352 // The order of characters is optimized for better gzip and brotli compression. 4353 // References to the same file (works both for gzip and brotli): 4354 // `'use`, `andom`, and `rict'` 4355 // References to the brotli default dictionary: 4356 // `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf` 4357 let urlAlphabet = 4358 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict' 4359 4360 let customAlphabet = (alphabet, defaultSize = 21) => { 4361 return (size = defaultSize) => { 4362 let id = '' 4363 // A compact alternative for `for (var i = 0; i < step; i++)`. 4364 let i = size | 0 4365 while (i--) { 4366 // `| 0` is more compact and faster than `Math.floor()`. 4367 id += alphabet[(Math.random() * alphabet.length) | 0] 4368 } 4369 return id 4370 } 4371 } 4372 4373 let nanoid = (size = 21) => { 4374 let id = '' 4375 // A compact alternative for `for (var i = 0; i < step; i++)`. 4376 let i = size | 0 4377 while (i--) { 4378 // `| 0` is more compact and faster than `Math.floor()`. 4379 id += urlAlphabet[(Math.random() * 64) | 0] 4380 } 4381 return id 4382 } 4383 4384 module.exports = { nanoid, customAlphabet } 4385 4386 4387 /***/ }), 4388 4389 /***/ 5215: 4390 /***/ ((module) => { 4391 4392 "use strict"; 4393 4394 4395 // do not edit .js files directly - edit src/index.jst 4396 4397 4398 4399 module.exports = function equal(a, b) { 4400 if (a === b) return true; 4401 4402 if (a && b && typeof a == 'object' && typeof b == 'object') { 4403 if (a.constructor !== b.constructor) return false; 4404 4405 var length, i, keys; 4406 if (Array.isArray(a)) { 4407 length = a.length; 4408 if (length != b.length) return false; 4409 for (i = length; i-- !== 0;) 4410 if (!equal(a[i], b[i])) return false; 4411 return true; 4412 } 4413 4414 4415 4416 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 4417 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 4418 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 4419 4420 keys = Object.keys(a); 4421 length = keys.length; 4422 if (length !== Object.keys(b).length) return false; 4423 4424 for (i = length; i-- !== 0;) 4425 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 4426 4427 for (i = length; i-- !== 0;) { 4428 var key = keys[i]; 4429 4430 if (!equal(a[key], b[key])) return false; 4431 } 4432 4433 return true; 4434 } 4435 4436 // true if both NaN, false otherwise 4437 return a!==a && b!==b; 4438 }; 4439 4440 4441 /***/ }), 4442 4443 /***/ 5380: 4444 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 4445 4446 "use strict"; 4447 4448 4449 let { nanoid } = __webpack_require__(5042) 4450 let { isAbsolute, resolve } = __webpack_require__(197) 4451 let { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(1866) 4452 let { fileURLToPath, pathToFileURL } = __webpack_require__(2739) 4453 4454 let CssSyntaxError = __webpack_require__(356) 4455 let PreviousMap = __webpack_require__(5696) 4456 let terminalHighlight = __webpack_require__(9746) 4457 4458 let fromOffsetCache = Symbol('fromOffsetCache') 4459 4460 let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) 4461 let pathAvailable = Boolean(resolve && isAbsolute) 4462 4463 class Input { 4464 get from() { 4465 return this.file || this.id 4466 } 4467 4468 constructor(css, opts = {}) { 4469 if ( 4470 css === null || 4471 typeof css === 'undefined' || 4472 (typeof css === 'object' && !css.toString) 4473 ) { 4474 throw new Error(`PostCSS received $css} instead of CSS string`) 4475 } 4476 4477 this.css = css.toString() 4478 4479 if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { 4480 this.hasBOM = true 4481 this.css = this.css.slice(1) 4482 } else { 4483 this.hasBOM = false 4484 } 4485 4486 this.document = this.css 4487 if (opts.document) this.document = opts.document.toString() 4488 4489 if (opts.from) { 4490 if ( 4491 !pathAvailable || 4492 /^\w+:\/\//.test(opts.from) || 4493 isAbsolute(opts.from) 4494 ) { 4495 this.file = opts.from 4496 } else { 4497 this.file = resolve(opts.from) 4498 } 4499 } 4500 4501 if (pathAvailable && sourceMapAvailable) { 4502 let map = new PreviousMap(this.css, opts) 4503 if (map.text) { 4504 this.map = map 4505 let file = map.consumer().file 4506 if (!this.file && file) this.file = this.mapResolve(file) 4507 } 4508 } 4509 4510 if (!this.file) { 4511 this.id = '<input css ' + nanoid(6) + '>' 4512 } 4513 if (this.map) this.map.file = this.from 4514 } 4515 4516 error(message, line, column, opts = {}) { 4517 let endColumn, endLine, result 4518 4519 if (line && typeof line === 'object') { 4520 let start = line 4521 let end = column 4522 if (typeof start.offset === 'number') { 4523 let pos = this.fromOffset(start.offset) 4524 line = pos.line 4525 column = pos.col 4526 } else { 4527 line = start.line 4528 column = start.column 4529 } 4530 if (typeof end.offset === 'number') { 4531 let pos = this.fromOffset(end.offset) 4532 endLine = pos.line 4533 endColumn = pos.col 4534 } else { 4535 endLine = end.line 4536 endColumn = end.column 4537 } 4538 } else if (!column) { 4539 let pos = this.fromOffset(line) 4540 line = pos.line 4541 column = pos.col 4542 } 4543 4544 let origin = this.origin(line, column, endLine, endColumn) 4545 if (origin) { 4546 result = new CssSyntaxError( 4547 message, 4548 origin.endLine === undefined 4549 ? origin.line 4550 : { column: origin.column, line: origin.line }, 4551 origin.endLine === undefined 4552 ? origin.column 4553 : { column: origin.endColumn, line: origin.endLine }, 4554 origin.source, 4555 origin.file, 4556 opts.plugin 4557 ) 4558 } else { 4559 result = new CssSyntaxError( 4560 message, 4561 endLine === undefined ? line : { column, line }, 4562 endLine === undefined ? column : { column: endColumn, line: endLine }, 4563 this.css, 4564 this.file, 4565 opts.plugin 4566 ) 4567 } 4568 4569 result.input = { column, endColumn, endLine, line, source: this.css } 4570 if (this.file) { 4571 if (pathToFileURL) { 4572 result.input.url = pathToFileURL(this.file).toString() 4573 } 4574 result.input.file = this.file 4575 } 4576 4577 return result 4578 } 4579 4580 fromOffset(offset) { 4581 let lastLine, lineToIndex 4582 if (!this[fromOffsetCache]) { 4583 let lines = this.css.split('\n') 4584 lineToIndex = new Array(lines.length) 4585 let prevIndex = 0 4586 4587 for (let i = 0, l = lines.length; i < l; i++) { 4588 lineToIndex[i] = prevIndex 4589 prevIndex += lines[i].length + 1 4590 } 4591 4592 this[fromOffsetCache] = lineToIndex 4593 } else { 4594 lineToIndex = this[fromOffsetCache] 4595 } 4596 lastLine = lineToIndex[lineToIndex.length - 1] 4597 4598 let min = 0 4599 if (offset >= lastLine) { 4600 min = lineToIndex.length - 1 4601 } else { 4602 let max = lineToIndex.length - 2 4603 let mid 4604 while (min < max) { 4605 mid = min + ((max - min) >> 1) 4606 if (offset < lineToIndex[mid]) { 4607 max = mid - 1 4608 } else if (offset >= lineToIndex[mid + 1]) { 4609 min = mid + 1 4610 } else { 4611 min = mid 4612 break 4613 } 4614 } 4615 } 4616 return { 4617 col: offset - lineToIndex[min] + 1, 4618 line: min + 1 4619 } 4620 } 4621 4622 mapResolve(file) { 4623 if (/^\w+:\/\//.test(file)) { 4624 return file 4625 } 4626 return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file) 4627 } 4628 4629 origin(line, column, endLine, endColumn) { 4630 if (!this.map) return false 4631 let consumer = this.map.consumer() 4632 4633 let from = consumer.originalPositionFor({ column, line }) 4634 if (!from.source) return false 4635 4636 let to 4637 if (typeof endLine === 'number') { 4638 to = consumer.originalPositionFor({ column: endColumn, line: endLine }) 4639 } 4640 4641 let fromUrl 4642 4643 if (isAbsolute(from.source)) { 4644 fromUrl = pathToFileURL(from.source) 4645 } else { 4646 fromUrl = new URL( 4647 from.source, 4648 this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile) 4649 ) 4650 } 4651 4652 let result = { 4653 column: from.column, 4654 endColumn: to && to.column, 4655 endLine: to && to.line, 4656 line: from.line, 4657 url: fromUrl.toString() 4658 } 4659 4660 if (fromUrl.protocol === 'file:') { 4661 if (fileURLToPath) { 4662 result.file = fileURLToPath(fromUrl) 4663 } else { 4664 /* c8 ignore next 2 */ 4665 throw new Error(`file: protocol is not available in this PostCSS build`) 4666 } 4667 } 4668 4669 let source = consumer.sourceContentFor(from.source) 4670 if (source) result.source = source 4671 4672 return result 4673 } 4674 4675 toJSON() { 4676 let json = {} 4677 for (let name of ['hasBOM', 'css', 'file', 'id']) { 4678 if (this[name] != null) { 4679 json[name] = this[name] 4680 } 4681 } 4682 if (this.map) { 4683 json.map = { ...this.map } 4684 if (json.map.consumerCache) { 4685 json.map.consumerCache = undefined 4686 } 4687 } 4688 return json 4689 } 4690 } 4691 4692 module.exports = Input 4693 Input.default = Input 4694 4695 if (terminalHighlight && terminalHighlight.registerInput) { 4696 terminalHighlight.registerInput(Input) 4697 } 4698 4699 4700 /***/ }), 4701 4702 /***/ 5404: 4703 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 4704 4705 const CSSValueParser = __webpack_require__(1544) 4706 4707 /** 4708 * @type {import('postcss').PluginCreator} 4709 */ 4710 module.exports = (opts) => { 4711 4712 const DEFAULTS = { 4713 skipHostRelativeUrls: true, 4714 } 4715 const config = Object.assign(DEFAULTS, opts) 4716 4717 return { 4718 postcssPlugin: 'rebaseUrl', 4719 4720 Declaration(decl) { 4721 // The faster way to find Declaration node 4722 const parsedValue = CSSValueParser(decl.value) 4723 4724 let valueChanged = false 4725 parsedValue.walk(node => { 4726 if (node.type !== 'function' || node.value !== 'url') { 4727 return 4728 } 4729 4730 const urlVal = node.nodes[0].value 4731 4732 // bases relative URLs with rootUrl 4733 const basedUrl = new URL(urlVal, opts.rootUrl) 4734 4735 // skip host-relative, already normalized URLs (e.g. `/images/image.jpg`, without `..`s) 4736 if ((basedUrl.pathname === urlVal) && config.skipHostRelativeUrls) { 4737 return false // skip this value 4738 } 4739 4740 node.nodes[0].value = basedUrl.toString() 4741 valueChanged = true 4742 4743 return false // do not walk deeper 4744 }) 4745 4746 if (valueChanged) { 4747 decl.value = CSSValueParser.stringify(parsedValue) 4748 } 4749 4750 } 4751 } 4752 } 4753 4754 module.exports.postcss = true 4755 4756 4757 /***/ }), 4758 4759 /***/ 5417: 4760 /***/ ((__unused_webpack_module, exports) => { 4761 4762 "use strict"; 4763 /*istanbul ignore start*/ 4764 4765 4766 Object.defineProperty(exports, "__esModule", ({ 4767 value: true 4768 })); 4769 exports["default"] = Diff; 4770 4771 /*istanbul ignore end*/ 4772 function Diff() {} 4773 4774 Diff.prototype = { 4775 /*istanbul ignore start*/ 4776 4777 /*istanbul ignore end*/ 4778 diff: function diff(oldString, newString) { 4779 /*istanbul ignore start*/ 4780 var 4781 /*istanbul ignore end*/ 4782 options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 4783 var callback = options.callback; 4784 4785 if (typeof options === 'function') { 4786 callback = options; 4787 options = {}; 4788 } 4789 4790 this.options = options; 4791 var self = this; 4792 4793 function done(value) { 4794 if (callback) { 4795 setTimeout(function () { 4796 callback(undefined, value); 4797 }, 0); 4798 return true; 4799 } else { 4800 return value; 4801 } 4802 } // Allow subclasses to massage the input prior to running 4803 4804 4805 oldString = this.castInput(oldString); 4806 newString = this.castInput(newString); 4807 oldString = this.removeEmpty(this.tokenize(oldString)); 4808 newString = this.removeEmpty(this.tokenize(newString)); 4809 var newLen = newString.length, 4810 oldLen = oldString.length; 4811 var editLength = 1; 4812 var maxEditLength = newLen + oldLen; 4813 var bestPath = [{ 4814 newPos: -1, 4815 components: [] 4816 }]; // Seed editLength = 0, i.e. the content starts with the same values 4817 4818 var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); 4819 4820 if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { 4821 // Identity per the equality and tokenizer 4822 return done([{ 4823 value: this.join(newString), 4824 count: newString.length 4825 }]); 4826 } // Main worker method. checks all permutations of a given edit length for acceptance. 4827 4828 4829 function execEditLength() { 4830 for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { 4831 var basePath = 4832 /*istanbul ignore start*/ 4833 void 0 4834 /*istanbul ignore end*/ 4835 ; 4836 4837 var addPath = bestPath[diagonalPath - 1], 4838 removePath = bestPath[diagonalPath + 1], 4839 _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; 4840 4841 if (addPath) { 4842 // No one else is going to attempt to use this value, clear it 4843 bestPath[diagonalPath - 1] = undefined; 4844 } 4845 4846 var canAdd = addPath && addPath.newPos + 1 < newLen, 4847 canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; 4848 4849 if (!canAdd && !canRemove) { 4850 // If this path is a terminal then prune 4851 bestPath[diagonalPath] = undefined; 4852 continue; 4853 } // Select the diagonal that we want to branch from. We select the prior 4854 // path whose position in the new string is the farthest from the origin 4855 // and does not pass the bounds of the diff graph 4856 4857 4858 if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { 4859 basePath = clonePath(removePath); 4860 self.pushComponent(basePath.components, undefined, true); 4861 } else { 4862 basePath = addPath; // No need to clone, we've pulled it from the list 4863 4864 basePath.newPos++; 4865 self.pushComponent(basePath.components, true, undefined); 4866 } 4867 4868 _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done 4869 4870 if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { 4871 return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); 4872 } else { 4873 // Otherwise track this path as a potential candidate and continue. 4874 bestPath[diagonalPath] = basePath; 4875 } 4876 } 4877 4878 editLength++; 4879 } // Performs the length of edit iteration. Is a bit fugly as this has to support the 4880 // sync and async mode which is never fun. Loops over execEditLength until a value 4881 // is produced. 4882 4883 4884 if (callback) { 4885 (function exec() { 4886 setTimeout(function () { 4887 // This should not happen, but we want to be safe. 4888 4889 /* istanbul ignore next */ 4890 if (editLength > maxEditLength) { 4891 return callback(); 4892 } 4893 4894 if (!execEditLength()) { 4895 exec(); 4896 } 4897 }, 0); 4898 })(); 4899 } else { 4900 while (editLength <= maxEditLength) { 4901 var ret = execEditLength(); 4902 4903 if (ret) { 4904 return ret; 4905 } 4906 } 4907 } 4908 }, 4909 4910 /*istanbul ignore start*/ 4911 4912 /*istanbul ignore end*/ 4913 pushComponent: function pushComponent(components, added, removed) { 4914 var last = components[components.length - 1]; 4915 4916 if (last && last.added === added && last.removed === removed) { 4917 // We need to clone here as the component clone operation is just 4918 // as shallow array clone 4919 components[components.length - 1] = { 4920 count: last.count + 1, 4921 added: added, 4922 removed: removed 4923 }; 4924 } else { 4925 components.push({ 4926 count: 1, 4927 added: added, 4928 removed: removed 4929 }); 4930 } 4931 }, 4932 4933 /*istanbul ignore start*/ 4934 4935 /*istanbul ignore end*/ 4936 extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { 4937 var newLen = newString.length, 4938 oldLen = oldString.length, 4939 newPos = basePath.newPos, 4940 oldPos = newPos - diagonalPath, 4941 commonCount = 0; 4942 4943 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { 4944 newPos++; 4945 oldPos++; 4946 commonCount++; 4947 } 4948 4949 if (commonCount) { 4950 basePath.components.push({ 4951 count: commonCount 4952 }); 4953 } 4954 4955 basePath.newPos = newPos; 4956 return oldPos; 4957 }, 4958 4959 /*istanbul ignore start*/ 4960 4961 /*istanbul ignore end*/ 4962 equals: function equals(left, right) { 4963 if (this.options.comparator) { 4964 return this.options.comparator(left, right); 4965 } else { 4966 return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 4967 } 4968 }, 4969 4970 /*istanbul ignore start*/ 4971 4972 /*istanbul ignore end*/ 4973 removeEmpty: function removeEmpty(array) { 4974 var ret = []; 4975 4976 for (var i = 0; i < array.length; i++) { 4977 if (array[i]) { 4978 ret.push(array[i]); 4979 } 4980 } 4981 4982 return ret; 4983 }, 4984 4985 /*istanbul ignore start*/ 4986 4987 /*istanbul ignore end*/ 4988 castInput: function castInput(value) { 4989 return value; 4990 }, 4991 4992 /*istanbul ignore start*/ 4993 4994 /*istanbul ignore end*/ 4995 tokenize: function tokenize(value) { 4996 return value.split(''); 4997 }, 4998 4999 /*istanbul ignore start*/ 5000 5001 /*istanbul ignore end*/ 5002 join: function join(chars) { 5003 return chars.join(''); 5004 } 5005 }; 5006 5007 function buildValues(diff, components, newString, oldString, useLongestToken) { 5008 var componentPos = 0, 5009 componentLen = components.length, 5010 newPos = 0, 5011 oldPos = 0; 5012 5013 for (; componentPos < componentLen; componentPos++) { 5014 var component = components[componentPos]; 5015 5016 if (!component.removed) { 5017 if (!component.added && useLongestToken) { 5018 var value = newString.slice(newPos, newPos + component.count); 5019 value = value.map(function (value, i) { 5020 var oldValue = oldString[oldPos + i]; 5021 return oldValue.length > value.length ? oldValue : value; 5022 }); 5023 component.value = diff.join(value); 5024 } else { 5025 component.value = diff.join(newString.slice(newPos, newPos + component.count)); 5026 } 5027 5028 newPos += component.count; // Common case 5029 5030 if (!component.added) { 5031 oldPos += component.count; 5032 } 5033 } else { 5034 component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); 5035 oldPos += component.count; // Reverse add and remove so removes are output first to match common convention 5036 // The diffing algorithm is tied to add then remove output and this is the simplest 5037 // route to get the desired output with minimal overhead. 5038 5039 if (componentPos && components[componentPos - 1].added) { 5040 var tmp = components[componentPos - 1]; 5041 components[componentPos - 1] = components[componentPos]; 5042 components[componentPos] = tmp; 5043 } 5044 } 5045 } // Special case handle for when one terminal is ignored (i.e. whitespace). 5046 // For this case we merge the terminal into the prior string and drop the change. 5047 // This is only available for string mode. 5048 5049 5050 var lastComponent = components[componentLen - 1]; 5051 5052 if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { 5053 components[componentLen - 2].value += lastComponent.value; 5054 components.pop(); 5055 } 5056 5057 return components; 5058 } 5059 5060 function clonePath(path) { 5061 return { 5062 newPos: path.newPos, 5063 components: path.components.slice(0) 5064 }; 5065 } 5066 5067 5068 /***/ }), 5069 5070 /***/ 5696: 5071 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5072 5073 "use strict"; 5074 5075 5076 let { existsSync, readFileSync } = __webpack_require__(9977) 5077 let { dirname, join } = __webpack_require__(197) 5078 let { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(1866) 5079 5080 function fromBase64(str) { 5081 if (Buffer) { 5082 return Buffer.from(str, 'base64').toString() 5083 } else { 5084 /* c8 ignore next 2 */ 5085 return window.atob(str) 5086 } 5087 } 5088 5089 class PreviousMap { 5090 constructor(css, opts) { 5091 if (opts.map === false) return 5092 this.loadAnnotation(css) 5093 this.inline = this.startWith(this.annotation, 'data:') 5094 5095 let prev = opts.map ? opts.map.prev : undefined 5096 let text = this.loadMap(opts.from, prev) 5097 if (!this.mapFile && opts.from) { 5098 this.mapFile = opts.from 5099 } 5100 if (this.mapFile) this.root = dirname(this.mapFile) 5101 if (text) this.text = text 5102 } 5103 5104 consumer() { 5105 if (!this.consumerCache) { 5106 this.consumerCache = new SourceMapConsumer(this.text) 5107 } 5108 return this.consumerCache 5109 } 5110 5111 decodeInline(text) { 5112 let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/ 5113 let baseUri = /^data:application\/json;base64,/ 5114 let charsetUri = /^data:application\/json;charset=utf-?8,/ 5115 let uri = /^data:application\/json,/ 5116 5117 let uriMatch = text.match(charsetUri) || text.match(uri) 5118 if (uriMatch) { 5119 return decodeURIComponent(text.substr(uriMatch[0].length)) 5120 } 5121 5122 let baseUriMatch = text.match(baseCharsetUri) || text.match(baseUri) 5123 if (baseUriMatch) { 5124 return fromBase64(text.substr(baseUriMatch[0].length)) 5125 } 5126 5127 let encoding = text.match(/data:application\/json;([^,]+),/)[1] 5128 throw new Error('Unsupported source map encoding ' + encoding) 5129 } 5130 5131 getAnnotationURL(sourceMapString) { 5132 return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, '').trim() 5133 } 5134 5135 isMap(map) { 5136 if (typeof map !== 'object') return false 5137 return ( 5138 typeof map.mappings === 'string' || 5139 typeof map._mappings === 'string' || 5140 Array.isArray(map.sections) 5141 ) 5142 } 5143 5144 loadAnnotation(css) { 5145 let comments = css.match(/\/\*\s*# sourceMappingURL=/g) 5146 if (!comments) return 5147 5148 // sourceMappingURLs from comments, strings, etc. 5149 let start = css.lastIndexOf(comments.pop()) 5150 let end = css.indexOf('*/', start) 5151 5152 if (start > -1 && end > -1) { 5153 // Locate the last sourceMappingURL to avoid pickin 5154 this.annotation = this.getAnnotationURL(css.substring(start, end)) 5155 } 5156 } 5157 5158 loadFile(path) { 5159 this.root = dirname(path) 5160 if (existsSync(path)) { 5161 this.mapFile = path 5162 return readFileSync(path, 'utf-8').toString().trim() 5163 } 5164 } 5165 5166 loadMap(file, prev) { 5167 if (prev === false) return false 5168 5169 if (prev) { 5170 if (typeof prev === 'string') { 5171 return prev 5172 } else if (typeof prev === 'function') { 5173 let prevPath = prev(file) 5174 if (prevPath) { 5175 let map = this.loadFile(prevPath) 5176 if (!map) { 5177 throw new Error( 5178 'Unable to load previous source map: ' + prevPath.toString() 5179 ) 5180 } 5181 return map 5182 } 5183 } else if (prev instanceof SourceMapConsumer) { 5184 return SourceMapGenerator.fromSourceMap(prev).toString() 5185 } else if (prev instanceof SourceMapGenerator) { 5186 return prev.toString() 5187 } else if (this.isMap(prev)) { 5188 return JSON.stringify(prev) 5189 } else { 5190 throw new Error( 5191 'Unsupported previous source map format: ' + prev.toString() 5192 ) 5193 } 5194 } else if (this.inline) { 5195 return this.decodeInline(this.annotation) 5196 } else if (this.annotation) { 5197 let map = this.annotation 5198 if (file) map = join(dirname(file), map) 5199 return this.loadFile(map) 5200 } 5201 } 5202 5203 startWith(string, start) { 5204 if (!string) return false 5205 return string.substr(0, start.length) === start 5206 } 5207 5208 withContent() { 5209 return !!( 5210 this.consumer().sourcesContent && 5211 this.consumer().sourcesContent.length > 0 5212 ) 5213 } 5214 } 5215 5216 module.exports = PreviousMap 5217 PreviousMap.default = PreviousMap 5218 5219 5220 /***/ }), 5221 5222 /***/ 5776: 5223 /***/ ((module) => { 5224 5225 "use strict"; 5226 5227 5228 class Warning { 5229 constructor(text, opts = {}) { 5230 this.type = 'warning' 5231 this.text = text 5232 5233 if (opts.node && opts.node.source) { 5234 let range = opts.node.rangeBy(opts) 5235 this.line = range.start.line 5236 this.column = range.start.column 5237 this.endLine = range.end.line 5238 this.endColumn = range.end.column 5239 } 5240 5241 for (let opt in opts) this[opt] = opts[opt] 5242 } 5243 5244 toString() { 5245 if (this.node) { 5246 return this.node.error(this.text, { 5247 index: this.index, 5248 plugin: this.plugin, 5249 word: this.word 5250 }).message 5251 } 5252 5253 if (this.plugin) { 5254 return this.plugin + ': ' + this.text 5255 } 5256 5257 return this.text 5258 } 5259 } 5260 5261 module.exports = Warning 5262 Warning.default = Warning 5263 5264 5265 /***/ }), 5266 5267 /***/ 5826: 5268 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5269 5270 /** 5271 * Copyright (c) 2013-present, Facebook, Inc. 5272 * 5273 * This source code is licensed under the MIT license found in the 5274 * LICENSE file in the root directory of this source tree. 5275 */ 5276 5277 if (false) { var throwOnDirectAccess, ReactIs; } else { 5278 // By explicitly using `prop-types` you are opting into new production behavior. 5279 // http://fb.me/prop-types-in-prod 5280 module.exports = __webpack_require__(628)(); 5281 } 5282 5283 5284 /***/ }), 5285 5286 /***/ 6109: 5287 /***/ ((module) => { 5288 5289 // This code has been refactored for 140 bytes 5290 // You can see the original here: https://github.com/twolfson/computedStyle/blob/04cd1da2e30fa45844f95f5cb1ac898e9b9ef050/lib/computedStyle.js 5291 var computedStyle = function (el, prop, getComputedStyle) { 5292 getComputedStyle = window.getComputedStyle; 5293 5294 // In one fell swoop 5295 return ( 5296 // If we have getComputedStyle 5297 getComputedStyle ? 5298 // Query it 5299 // TODO: From CSS-Query notes, we might need (node, null) for FF 5300 getComputedStyle(el) : 5301 5302 // Otherwise, we are in IE and use currentStyle 5303 el.currentStyle 5304 )[ 5305 // Switch to camelCase for CSSOM 5306 // DEV: Grabbed from jQuery 5307 // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 5308 // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 5309 prop.replace(/-(\w)/gi, function (word, letter) { 5310 return letter.toUpperCase(); 5311 }) 5312 ]; 5313 }; 5314 5315 module.exports = computedStyle; 5316 5317 5318 /***/ }), 5319 5320 /***/ 6589: 5321 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5322 5323 "use strict"; 5324 5325 5326 let Node = __webpack_require__(7490) 5327 5328 class Comment extends Node { 5329 constructor(defaults) { 5330 super(defaults) 5331 this.type = 'comment' 5332 } 5333 } 5334 5335 module.exports = Comment 5336 Comment.default = Comment 5337 5338 5339 /***/ }), 5340 5341 /***/ 7191: 5342 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5343 5344 "use strict"; 5345 /** 5346 * Copyright (c) 2015, Facebook, Inc. 5347 * All rights reserved. 5348 * 5349 * This source code is licensed under the BSD-style license found in the 5350 * LICENSE file in the root directory of this source tree. An additional grant 5351 * of patent rights can be found in the PATENTS file in the same directory. 5352 * 5353 * @providesModule normalizeWheel 5354 * @typechecks 5355 */ 5356 5357 5358 5359 var UserAgent_DEPRECATED = __webpack_require__(2213); 5360 5361 var isEventSupported = __webpack_require__(1087); 5362 5363 5364 // Reasonable defaults 5365 var PIXEL_STEP = 10; 5366 var LINE_HEIGHT = 40; 5367 var PAGE_HEIGHT = 800; 5368 5369 /** 5370 * Mouse wheel (and 2-finger trackpad) support on the web sucks. It is 5371 * complicated, thus this doc is long and (hopefully) detailed enough to answer 5372 * your questions. 5373 * 5374 * If you need to react to the mouse wheel in a predictable way, this code is 5375 * like your bestest friend. * hugs * 5376 * 5377 * As of today, there are 4 DOM event types you can listen to: 5378 * 5379 * 'wheel' -- Chrome(31+), FF(17+), IE(9+) 5380 * 'mousewheel' -- Chrome, IE(6+), Opera, Safari 5381 * 'MozMousePixelScroll' -- FF(3.5 only!) (2010-2013) -- don't bother! 5382 * 'DOMMouseScroll' -- FF(0.9.7+) since 2003 5383 * 5384 * So what to do? The is the best: 5385 * 5386 * normalizeWheel.getEventType(); 5387 * 5388 * In your event callback, use this code to get sane interpretation of the 5389 * deltas. This code will return an object with properties: 5390 * 5391 * spinX -- normalized spin speed (use for zoom) - x plane 5392 * spinY -- " - y plane 5393 * pixelX -- normalized distance (to pixels) - x plane 5394 * pixelY -- " - y plane 5395 * 5396 * Wheel values are provided by the browser assuming you are using the wheel to 5397 * scroll a web page by a number of lines or pixels (or pages). Values can vary 5398 * significantly on different platforms and browsers, forgetting that you can 5399 * scroll at different speeds. Some devices (like trackpads) emit more events 5400 * at smaller increments with fine granularity, and some emit massive jumps with 5401 * linear speed or acceleration. 5402 * 5403 * This code does its best to normalize the deltas for you: 5404 * 5405 * - spin is trying to normalize how far the wheel was spun (or trackpad 5406 * dragged). This is super useful for zoom support where you want to 5407 * throw away the chunky scroll steps on the PC and make those equal to 5408 * the slow and smooth tiny steps on the Mac. Key data: This code tries to 5409 * resolve a single slow step on a wheel to 1. 5410 * 5411 * - pixel is normalizing the desired scroll delta in pixel units. You'll 5412 * get the crazy differences between browsers, but at least it'll be in 5413 * pixels! 5414 * 5415 * - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT. This 5416 * should translate to positive value zooming IN, negative zooming OUT. 5417 * This matches the newer 'wheel' event. 5418 * 5419 * Why are there spinX, spinY (or pixels)? 5420 * 5421 * - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn 5422 * with a mouse. It results in side-scrolling in the browser by default. 5423 * 5424 * - spinY is what you expect -- it's the classic axis of a mouse wheel. 5425 * 5426 * - I dropped spinZ/pixelZ. It is supported by the DOM 3 'wheel' event and 5427 * probably is by browsers in conjunction with fancy 3D controllers .. but 5428 * you know. 5429 * 5430 * Implementation info: 5431 * 5432 * Examples of 'wheel' event if you scroll slowly (down) by one step with an 5433 * average mouse: 5434 * 5435 * OS X + Chrome (mouse) - 4 pixel delta (wheelDelta -120) 5436 * OS X + Safari (mouse) - N/A pixel delta (wheelDelta -12) 5437 * OS X + Firefox (mouse) - 0.1 line delta (wheelDelta N/A) 5438 * Win8 + Chrome (mouse) - 100 pixel delta (wheelDelta -120) 5439 * Win8 + Firefox (mouse) - 3 line delta (wheelDelta -120) 5440 * 5441 * On the trackpad: 5442 * 5443 * OS X + Chrome (trackpad) - 2 pixel delta (wheelDelta -6) 5444 * OS X + Firefox (trackpad) - 1 pixel delta (wheelDelta N/A) 5445 * 5446 * On other/older browsers.. it's more complicated as there can be multiple and 5447 * also missing delta values. 5448 * 5449 * The 'wheel' event is more standard: 5450 * 5451 * http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents 5452 * 5453 * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and 5454 * deltaX, deltaY and deltaZ. Some browsers provide other values to maintain 5455 * backward compatibility with older events. Those other values help us 5456 * better normalize spin speed. Example of what the browsers provide: 5457 * 5458 * | event.wheelDelta | event.detail 5459 * ------------------+------------------+-------------- 5460 * Safari v5/OS X | -120 | 0 5461 * Safari v5/Win7 | -120 | 0 5462 * Chrome v17/OS X | -120 | 0 5463 * Chrome v17/Win7 | -120 | 0 5464 * IE9/Win7 | -120 | undefined 5465 * Firefox v4/OS X | undefined | 1 5466 * Firefox v4/Win7 | undefined | 3 5467 * 5468 */ 5469 function normalizeWheel(/*object*/ event) /*object*/ { 5470 var sX = 0, sY = 0, // spinX, spinY 5471 pX = 0, pY = 0; // pixelX, pixelY 5472 5473 // Legacy 5474 if ('detail' in event) { sY = event.detail; } 5475 if ('wheelDelta' in event) { sY = -event.wheelDelta / 120; } 5476 if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120; } 5477 if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120; } 5478 5479 // side scrolling on FF with DOMMouseScroll 5480 if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) { 5481 sX = sY; 5482 sY = 0; 5483 } 5484 5485 pX = sX * PIXEL_STEP; 5486 pY = sY * PIXEL_STEP; 5487 5488 if ('deltaY' in event) { pY = event.deltaY; } 5489 if ('deltaX' in event) { pX = event.deltaX; } 5490 5491 if ((pX || pY) && event.deltaMode) { 5492 if (event.deltaMode == 1) { // delta in LINE units 5493 pX *= LINE_HEIGHT; 5494 pY *= LINE_HEIGHT; 5495 } else { // delta in PAGE units 5496 pX *= PAGE_HEIGHT; 5497 pY *= PAGE_HEIGHT; 5498 } 5499 } 5500 5501 // Fall-back if spin cannot be determined 5502 if (pX && !sX) { sX = (pX < 1) ? -1 : 1; } 5503 if (pY && !sY) { sY = (pY < 1) ? -1 : 1; } 5504 5505 return { spinX : sX, 5506 spinY : sY, 5507 pixelX : pX, 5508 pixelY : pY }; 5509 } 5510 5511 5512 /** 5513 * The best combination if you prefer spinX + spinY normalization. It favors 5514 * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with 5515 * 'wheel' event, making spin speed determination impossible. 5516 */ 5517 normalizeWheel.getEventType = function() /*string*/ { 5518 return (UserAgent_DEPRECATED.firefox()) 5519 ? 'DOMMouseScroll' 5520 : (isEventSupported('wheel')) 5521 ? 'wheel' 5522 : 'mousewheel'; 5523 }; 5524 5525 module.exports = normalizeWheel; 5526 5527 5528 /***/ }), 5529 5530 /***/ 7374: 5531 /***/ ((module) => { 5532 5533 "use strict"; 5534 5535 5536 let list = { 5537 comma(string) { 5538 return list.split(string, [','], true) 5539 }, 5540 5541 space(string) { 5542 let spaces = [' ', '\n', '\t'] 5543 return list.split(string, spaces) 5544 }, 5545 5546 split(string, separators, last) { 5547 let array = [] 5548 let current = '' 5549 let split = false 5550 5551 let func = 0 5552 let inQuote = false 5553 let prevQuote = '' 5554 let escape = false 5555 5556 for (let letter of string) { 5557 if (escape) { 5558 escape = false 5559 } else if (letter === '\\') { 5560 escape = true 5561 } else if (inQuote) { 5562 if (letter === prevQuote) { 5563 inQuote = false 5564 } 5565 } else if (letter === '"' || letter === "'") { 5566 inQuote = true 5567 prevQuote = letter 5568 } else if (letter === '(') { 5569 func += 1 5570 } else if (letter === ')') { 5571 if (func > 0) func -= 1 5572 } else if (func === 0) { 5573 if (separators.includes(letter)) split = true 5574 } 5575 5576 if (split) { 5577 if (current !== '') array.push(current.trim()) 5578 current = '' 5579 split = false 5580 } else { 5581 current += letter 5582 } 5583 } 5584 5585 if (last || current !== '') array.push(current.trim()) 5586 return array 5587 } 5588 } 5589 5590 module.exports = list 5591 list.default = list 5592 5593 5594 /***/ }), 5595 5596 /***/ 7490: 5597 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5598 5599 "use strict"; 5600 5601 5602 let CssSyntaxError = __webpack_require__(356) 5603 let Stringifier = __webpack_require__(346) 5604 let stringify = __webpack_require__(633) 5605 let { isClean, my } = __webpack_require__(1381) 5606 5607 function cloneNode(obj, parent) { 5608 let cloned = new obj.constructor() 5609 5610 for (let i in obj) { 5611 if (!Object.prototype.hasOwnProperty.call(obj, i)) { 5612 /* c8 ignore next 2 */ 5613 continue 5614 } 5615 if (i === 'proxyCache') continue 5616 let value = obj[i] 5617 let type = typeof value 5618 5619 if (i === 'parent' && type === 'object') { 5620 if (parent) cloned[i] = parent 5621 } else if (i === 'source') { 5622 cloned[i] = value 5623 } else if (Array.isArray(value)) { 5624 cloned[i] = value.map(j => cloneNode(j, cloned)) 5625 } else { 5626 if (type === 'object' && value !== null) value = cloneNode(value) 5627 cloned[i] = value 5628 } 5629 } 5630 5631 return cloned 5632 } 5633 5634 function sourceOffset(inputCSS, position) { 5635 // Not all custom syntaxes support `offset` in `source.start` and `source.end` 5636 if ( 5637 position && 5638 typeof position.offset !== 'undefined' 5639 ) { 5640 return position.offset; 5641 } 5642 5643 let column = 1 5644 let line = 1 5645 let offset = 0 5646 5647 for (let i = 0; i < inputCSS.length; i++) { 5648 if (line === position.line && column === position.column) { 5649 offset = i 5650 break 5651 } 5652 5653 if (inputCSS[i] === '\n') { 5654 column = 1 5655 line += 1 5656 } else { 5657 column += 1 5658 } 5659 } 5660 5661 return offset 5662 } 5663 5664 class Node { 5665 get proxyOf() { 5666 return this 5667 } 5668 5669 constructor(defaults = {}) { 5670 this.raws = {} 5671 this[isClean] = false 5672 this[my] = true 5673 5674 for (let name in defaults) { 5675 if (name === 'nodes') { 5676 this.nodes = [] 5677 for (let node of defaults[name]) { 5678 if (typeof node.clone === 'function') { 5679 this.append(node.clone()) 5680 } else { 5681 this.append(node) 5682 } 5683 } 5684 } else { 5685 this[name] = defaults[name] 5686 } 5687 } 5688 } 5689 5690 addToError(error) { 5691 error.postcssNode = this 5692 if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) { 5693 let s = this.source 5694 error.stack = error.stack.replace( 5695 /\n\s{4}at /, 5696 `$&$s.input.from}:$s.start.line}:$s.start.column}$&` 5697 ) 5698 } 5699 return error 5700 } 5701 5702 after(add) { 5703 this.parent.insertAfter(this, add) 5704 return this 5705 } 5706 5707 assign(overrides = {}) { 5708 for (let name in overrides) { 5709 this[name] = overrides[name] 5710 } 5711 return this 5712 } 5713 5714 before(add) { 5715 this.parent.insertBefore(this, add) 5716 return this 5717 } 5718 5719 cleanRaws(keepBetween) { 5720 delete this.raws.before 5721 delete this.raws.after 5722 if (!keepBetween) delete this.raws.between 5723 } 5724 5725 clone(overrides = {}) { 5726 let cloned = cloneNode(this) 5727 for (let name in overrides) { 5728 cloned[name] = overrides[name] 5729 } 5730 return cloned 5731 } 5732 5733 cloneAfter(overrides = {}) { 5734 let cloned = this.clone(overrides) 5735 this.parent.insertAfter(this, cloned) 5736 return cloned 5737 } 5738 5739 cloneBefore(overrides = {}) { 5740 let cloned = this.clone(overrides) 5741 this.parent.insertBefore(this, cloned) 5742 return cloned 5743 } 5744 5745 error(message, opts = {}) { 5746 if (this.source) { 5747 let { end, start } = this.rangeBy(opts) 5748 return this.source.input.error( 5749 message, 5750 { column: start.column, line: start.line }, 5751 { column: end.column, line: end.line }, 5752 opts 5753 ) 5754 } 5755 return new CssSyntaxError(message) 5756 } 5757 5758 getProxyProcessor() { 5759 return { 5760 get(node, prop) { 5761 if (prop === 'proxyOf') { 5762 return node 5763 } else if (prop === 'root') { 5764 return () => node.root().toProxy() 5765 } else { 5766 return node[prop] 5767 } 5768 }, 5769 5770 set(node, prop, value) { 5771 if (node[prop] === value) return true 5772 node[prop] = value 5773 if ( 5774 prop === 'prop' || 5775 prop === 'value' || 5776 prop === 'name' || 5777 prop === 'params' || 5778 prop === 'important' || 5779 /* c8 ignore next */ 5780 prop === 'text' 5781 ) { 5782 node.markDirty() 5783 } 5784 return true 5785 } 5786 } 5787 } 5788 5789 /* c8 ignore next 3 */ 5790 markClean() { 5791 this[isClean] = true 5792 } 5793 5794 markDirty() { 5795 if (this[isClean]) { 5796 this[isClean] = false 5797 let next = this 5798 while ((next = next.parent)) { 5799 next[isClean] = false 5800 } 5801 } 5802 } 5803 5804 next() { 5805 if (!this.parent) return undefined 5806 let index = this.parent.index(this) 5807 return this.parent.nodes[index + 1] 5808 } 5809 5810 positionBy(opts) { 5811 let pos = this.source.start 5812 if (opts.index) { 5813 pos = this.positionInside(opts.index) 5814 } else if (opts.word) { 5815 let inputString = ('document' in this.source.input) 5816 ? this.source.input.document 5817 : this.source.input.css 5818 let stringRepresentation = inputString.slice( 5819 sourceOffset(inputString, this.source.start), 5820 sourceOffset(inputString, this.source.end) 5821 ) 5822 let index = stringRepresentation.indexOf(opts.word) 5823 if (index !== -1) pos = this.positionInside(index) 5824 } 5825 return pos 5826 } 5827 5828 positionInside(index) { 5829 let column = this.source.start.column 5830 let line = this.source.start.line 5831 let inputString = ('document' in this.source.input) 5832 ? this.source.input.document 5833 : this.source.input.css 5834 let offset = sourceOffset(inputString, this.source.start) 5835 let end = offset + index 5836 5837 for (let i = offset; i < end; i++) { 5838 if (inputString[i] === '\n') { 5839 column = 1 5840 line += 1 5841 } else { 5842 column += 1 5843 } 5844 } 5845 5846 return { column, line } 5847 } 5848 5849 prev() { 5850 if (!this.parent) return undefined 5851 let index = this.parent.index(this) 5852 return this.parent.nodes[index - 1] 5853 } 5854 5855 rangeBy(opts) { 5856 let start = { 5857 column: this.source.start.column, 5858 line: this.source.start.line 5859 } 5860 let end = this.source.end 5861 ? { 5862 column: this.source.end.column + 1, 5863 line: this.source.end.line 5864 } 5865 : { 5866 column: start.column + 1, 5867 line: start.line 5868 } 5869 5870 if (opts.word) { 5871 let inputString = ('document' in this.source.input) 5872 ? this.source.input.document 5873 : this.source.input.css 5874 let stringRepresentation = inputString.slice( 5875 sourceOffset(inputString, this.source.start), 5876 sourceOffset(inputString, this.source.end) 5877 ) 5878 let index = stringRepresentation.indexOf(opts.word) 5879 if (index !== -1) { 5880 start = this.positionInside(index) 5881 end = this.positionInside( 5882 index + opts.word.length, 5883 ) 5884 } 5885 } else { 5886 if (opts.start) { 5887 start = { 5888 column: opts.start.column, 5889 line: opts.start.line 5890 } 5891 } else if (opts.index) { 5892 start = this.positionInside(opts.index) 5893 } 5894 5895 if (opts.end) { 5896 end = { 5897 column: opts.end.column, 5898 line: opts.end.line 5899 } 5900 } else if (typeof opts.endIndex === 'number') { 5901 end = this.positionInside(opts.endIndex) 5902 } else if (opts.index) { 5903 end = this.positionInside(opts.index + 1) 5904 } 5905 } 5906 5907 if ( 5908 end.line < start.line || 5909 (end.line === start.line && end.column <= start.column) 5910 ) { 5911 end = { column: start.column + 1, line: start.line } 5912 } 5913 5914 return { end, start } 5915 } 5916 5917 raw(prop, defaultType) { 5918 let str = new Stringifier() 5919 return str.raw(this, prop, defaultType) 5920 } 5921 5922 remove() { 5923 if (this.parent) { 5924 this.parent.removeChild(this) 5925 } 5926 this.parent = undefined 5927 return this 5928 } 5929 5930 replaceWith(...nodes) { 5931 if (this.parent) { 5932 let bookmark = this 5933 let foundSelf = false 5934 for (let node of nodes) { 5935 if (node === this) { 5936 foundSelf = true 5937 } else if (foundSelf) { 5938 this.parent.insertAfter(bookmark, node) 5939 bookmark = node 5940 } else { 5941 this.parent.insertBefore(bookmark, node) 5942 } 5943 } 5944 5945 if (!foundSelf) { 5946 this.remove() 5947 } 5948 } 5949 5950 return this 5951 } 5952 5953 root() { 5954 let result = this 5955 while (result.parent && result.parent.type !== 'document') { 5956 result = result.parent 5957 } 5958 return result 5959 } 5960 5961 toJSON(_, inputs) { 5962 let fixed = {} 5963 let emitInputs = inputs == null 5964 inputs = inputs || new Map() 5965 let inputsNextIndex = 0 5966 5967 for (let name in this) { 5968 if (!Object.prototype.hasOwnProperty.call(this, name)) { 5969 /* c8 ignore next 2 */ 5970 continue 5971 } 5972 if (name === 'parent' || name === 'proxyCache') continue 5973 let value = this[name] 5974 5975 if (Array.isArray(value)) { 5976 fixed[name] = value.map(i => { 5977 if (typeof i === 'object' && i.toJSON) { 5978 return i.toJSON(null, inputs) 5979 } else { 5980 return i 5981 } 5982 }) 5983 } else if (typeof value === 'object' && value.toJSON) { 5984 fixed[name] = value.toJSON(null, inputs) 5985 } else if (name === 'source') { 5986 let inputId = inputs.get(value.input) 5987 if (inputId == null) { 5988 inputId = inputsNextIndex 5989 inputs.set(value.input, inputsNextIndex) 5990 inputsNextIndex++ 5991 } 5992 fixed[name] = { 5993 end: value.end, 5994 inputId, 5995 start: value.start 5996 } 5997 } else { 5998 fixed[name] = value 5999 } 6000 } 6001 6002 if (emitInputs) { 6003 fixed.inputs = [...inputs.keys()].map(input => input.toJSON()) 6004 } 6005 6006 return fixed 6007 } 6008 6009 toProxy() { 6010 if (!this.proxyCache) { 6011 this.proxyCache = new Proxy(this, this.getProxyProcessor()) 6012 } 6013 return this.proxyCache 6014 } 6015 6016 toString(stringifier = stringify) { 6017 if (stringifier.stringify) stringifier = stringifier.stringify 6018 let result = '' 6019 stringifier(this, i => { 6020 result += i 6021 }) 6022 return result 6023 } 6024 6025 warn(result, text, opts) { 6026 let data = { node: this } 6027 for (let i in opts) data[i] = opts[i] 6028 return result.warn(text, data) 6029 } 6030 } 6031 6032 module.exports = Node 6033 Node.default = Node 6034 6035 6036 /***/ }), 6037 6038 /***/ 7520: 6039 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6040 6041 module.exports = __webpack_require__(7191); 6042 6043 6044 /***/ }), 6045 6046 /***/ 7661: 6047 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6048 6049 "use strict"; 6050 6051 6052 let MapGenerator = __webpack_require__(1670) 6053 let parse = __webpack_require__(4295) 6054 const Result = __webpack_require__(9055) 6055 let stringify = __webpack_require__(633) 6056 let warnOnce = __webpack_require__(3122) 6057 6058 class NoWorkResult { 6059 get content() { 6060 return this.result.css 6061 } 6062 6063 get css() { 6064 return this.result.css 6065 } 6066 6067 get map() { 6068 return this.result.map 6069 } 6070 6071 get messages() { 6072 return [] 6073 } 6074 6075 get opts() { 6076 return this.result.opts 6077 } 6078 6079 get processor() { 6080 return this.result.processor 6081 } 6082 6083 get root() { 6084 if (this._root) { 6085 return this._root 6086 } 6087 6088 let root 6089 let parser = parse 6090 6091 try { 6092 root = parser(this._css, this._opts) 6093 } catch (error) { 6094 this.error = error 6095 } 6096 6097 if (this.error) { 6098 throw this.error 6099 } else { 6100 this._root = root 6101 return root 6102 } 6103 } 6104 6105 get [Symbol.toStringTag]() { 6106 return 'NoWorkResult' 6107 } 6108 6109 constructor(processor, css, opts) { 6110 css = css.toString() 6111 this.stringified = false 6112 6113 this._processor = processor 6114 this._css = css 6115 this._opts = opts 6116 this._map = undefined 6117 let root 6118 6119 let str = stringify 6120 this.result = new Result(this._processor, root, this._opts) 6121 this.result.css = css 6122 6123 let self = this 6124 Object.defineProperty(this.result, 'root', { 6125 get() { 6126 return self.root 6127 } 6128 }) 6129 6130 let map = new MapGenerator(str, root, this._opts, css) 6131 if (map.isMap()) { 6132 let [generatedCSS, generatedMap] = map.generate() 6133 if (generatedCSS) { 6134 this.result.css = generatedCSS 6135 } 6136 if (generatedMap) { 6137 this.result.map = generatedMap 6138 } 6139 } else { 6140 map.clearAnnotation() 6141 this.result.css = map.css 6142 } 6143 } 6144 6145 async() { 6146 if (this.error) return Promise.reject(this.error) 6147 return Promise.resolve(this.result) 6148 } 6149 6150 catch(onRejected) { 6151 return this.async().catch(onRejected) 6152 } 6153 6154 finally(onFinally) { 6155 return this.async().then(onFinally, onFinally) 6156 } 6157 6158 sync() { 6159 if (this.error) throw this.error 6160 return this.result 6161 } 6162 6163 then(onFulfilled, onRejected) { 6164 if (false) {} 6165 6166 return this.async().then(onFulfilled, onRejected) 6167 } 6168 6169 toString() { 6170 return this._css 6171 } 6172 6173 warnings() { 6174 return [] 6175 } 6176 } 6177 6178 module.exports = NoWorkResult 6179 NoWorkResult.default = NoWorkResult 6180 6181 6182 /***/ }), 6183 6184 /***/ 7734: 6185 /***/ ((module) => { 6186 6187 "use strict"; 6188 6189 6190 // do not edit .js files directly - edit src/index.jst 6191 6192 6193 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; 6194 6195 6196 module.exports = function equal(a, b) { 6197 if (a === b) return true; 6198 6199 if (a && b && typeof a == 'object' && typeof b == 'object') { 6200 if (a.constructor !== b.constructor) return false; 6201 6202 var length, i, keys; 6203 if (Array.isArray(a)) { 6204 length = a.length; 6205 if (length != b.length) return false; 6206 for (i = length; i-- !== 0;) 6207 if (!equal(a[i], b[i])) return false; 6208 return true; 6209 } 6210 6211 6212 if ((a instanceof Map) && (b instanceof Map)) { 6213 if (a.size !== b.size) return false; 6214 for (i of a.entries()) 6215 if (!b.has(i[0])) return false; 6216 for (i of a.entries()) 6217 if (!equal(i[1], b.get(i[0]))) return false; 6218 return true; 6219 } 6220 6221 if ((a instanceof Set) && (b instanceof Set)) { 6222 if (a.size !== b.size) return false; 6223 for (i of a.entries()) 6224 if (!b.has(i[0])) return false; 6225 return true; 6226 } 6227 6228 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 6229 length = a.length; 6230 if (length != b.length) return false; 6231 for (i = length; i-- !== 0;) 6232 if (a[i] !== b[i]) return false; 6233 return true; 6234 } 6235 6236 6237 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 6238 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 6239 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 6240 6241 keys = Object.keys(a); 6242 length = keys.length; 6243 if (length !== Object.keys(b).length) return false; 6244 6245 for (i = length; i-- !== 0;) 6246 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 6247 6248 for (i = length; i-- !== 0;) { 6249 var key = keys[i]; 6250 6251 if (!equal(a[key], b[key])) return false; 6252 } 6253 6254 return true; 6255 } 6256 6257 // true if both NaN, false otherwise 6258 return a!==a && b!==b; 6259 }; 6260 6261 6262 /***/ }), 6263 6264 /***/ 8021: 6265 /***/ ((__unused_webpack_module, exports, __webpack_require__) => { 6266 6267 "use strict"; 6268 var __webpack_unused_export__; 6269 /*istanbul ignore start*/ 6270 6271 6272 __webpack_unused_export__ = ({ 6273 value: true 6274 }); 6275 exports.JJ = diffChars; 6276 __webpack_unused_export__ = void 0; 6277 6278 /*istanbul ignore end*/ 6279 var 6280 /*istanbul ignore start*/ 6281 _base = _interopRequireDefault(__webpack_require__(5417)) 6282 /*istanbul ignore end*/ 6283 ; 6284 6285 /*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 6286 6287 /*istanbul ignore end*/ 6288 var characterDiff = new 6289 /*istanbul ignore start*/ 6290 _base 6291 /*istanbul ignore end*/ 6292 . 6293 /*istanbul ignore start*/ 6294 default 6295 /*istanbul ignore end*/ 6296 (); 6297 6298 /*istanbul ignore start*/ 6299 __webpack_unused_export__ = characterDiff; 6300 6301 /*istanbul ignore end*/ 6302 function diffChars(oldStr, newStr, options) { 6303 return characterDiff.diff(oldStr, newStr, options); 6304 } 6305 6306 6307 /***/ }), 6308 6309 /***/ 8202: 6310 /***/ ((module) => { 6311 6312 "use strict"; 6313 /** 6314 * Copyright (c) 2015, Facebook, Inc. 6315 * All rights reserved. 6316 * 6317 * This source code is licensed under the BSD-style license found in the 6318 * LICENSE file in the root directory of this source tree. An additional grant 6319 * of patent rights can be found in the PATENTS file in the same directory. 6320 * 6321 * @providesModule ExecutionEnvironment 6322 */ 6323 6324 /*jslint evil: true */ 6325 6326 6327 6328 var canUseDOM = !!( 6329 typeof window !== 'undefined' && 6330 window.document && 6331 window.document.createElement 6332 ); 6333 6334 /** 6335 * Simple, lightweight module assisting with the detection and context of 6336 * Worker. Helps avoid circular dependencies and allows code to reason about 6337 * whether or not they are in a Worker, even if they never include the main 6338 * `ReactWorker` dependency. 6339 */ 6340 var ExecutionEnvironment = { 6341 6342 canUseDOM: canUseDOM, 6343 6344 canUseWorkers: typeof Worker !== 'undefined', 6345 6346 canUseEventListeners: 6347 canUseDOM && !!(window.addEventListener || window.attachEvent), 6348 6349 canUseViewport: canUseDOM && !!window.screen, 6350 6351 isInWorker: !canUseDOM // For now, this is true - might change in the future. 6352 6353 }; 6354 6355 module.exports = ExecutionEnvironment; 6356 6357 6358 /***/ }), 6359 6360 /***/ 8491: 6361 /***/ ((module) => { 6362 6363 var openParentheses = "(".charCodeAt(0); 6364 var closeParentheses = ")".charCodeAt(0); 6365 var singleQuote = "'".charCodeAt(0); 6366 var doubleQuote = '"'.charCodeAt(0); 6367 var backslash = "\\".charCodeAt(0); 6368 var slash = "/".charCodeAt(0); 6369 var comma = ",".charCodeAt(0); 6370 var colon = ":".charCodeAt(0); 6371 var star = "*".charCodeAt(0); 6372 var uLower = "u".charCodeAt(0); 6373 var uUpper = "U".charCodeAt(0); 6374 var plus = "+".charCodeAt(0); 6375 var isUnicodeRange = /^[a-f0-9?-]+$/i; 6376 6377 module.exports = function(input) { 6378 var tokens = []; 6379 var value = input; 6380 6381 var next, 6382 quote, 6383 prev, 6384 token, 6385 escape, 6386 escapePos, 6387 whitespacePos, 6388 parenthesesOpenPos; 6389 var pos = 0; 6390 var code = value.charCodeAt(pos); 6391 var max = value.length; 6392 var stack = [{ nodes: tokens }]; 6393 var balanced = 0; 6394 var parent; 6395 6396 var name = ""; 6397 var before = ""; 6398 var after = ""; 6399 6400 while (pos < max) { 6401 // Whitespaces 6402 if (code <= 32) { 6403 next = pos; 6404 do { 6405 next += 1; 6406 code = value.charCodeAt(next); 6407 } while (code <= 32); 6408 token = value.slice(pos, next); 6409 6410 prev = tokens[tokens.length - 1]; 6411 if (code === closeParentheses && balanced) { 6412 after = token; 6413 } else if (prev && prev.type === "div") { 6414 prev.after = token; 6415 prev.sourceEndIndex += token.length; 6416 } else if ( 6417 code === comma || 6418 code === colon || 6419 (code === slash && 6420 value.charCodeAt(next + 1) !== star && 6421 (!parent || 6422 (parent && parent.type === "function" && parent.value !== "calc"))) 6423 ) { 6424 before = token; 6425 } else { 6426 tokens.push({ 6427 type: "space", 6428 sourceIndex: pos, 6429 sourceEndIndex: next, 6430 value: token 6431 }); 6432 } 6433 6434 pos = next; 6435 6436 // Quotes 6437 } else if (code === singleQuote || code === doubleQuote) { 6438 next = pos; 6439 quote = code === singleQuote ? "'" : '"'; 6440 token = { 6441 type: "string", 6442 sourceIndex: pos, 6443 quote: quote 6444 }; 6445 do { 6446 escape = false; 6447 next = value.indexOf(quote, next + 1); 6448 if (~next) { 6449 escapePos = next; 6450 while (value.charCodeAt(escapePos - 1) === backslash) { 6451 escapePos -= 1; 6452 escape = !escape; 6453 } 6454 } else { 6455 value += quote; 6456 next = value.length - 1; 6457 token.unclosed = true; 6458 } 6459 } while (escape); 6460 token.value = value.slice(pos + 1, next); 6461 token.sourceEndIndex = token.unclosed ? next : next + 1; 6462 tokens.push(token); 6463 pos = next + 1; 6464 code = value.charCodeAt(pos); 6465 6466 // Comments 6467 } else if (code === slash && value.charCodeAt(pos + 1) === star) { 6468 next = value.indexOf("*/", pos); 6469 6470 token = { 6471 type: "comment", 6472 sourceIndex: pos, 6473 sourceEndIndex: next + 2 6474 }; 6475 6476 if (next === -1) { 6477 token.unclosed = true; 6478 next = value.length; 6479 token.sourceEndIndex = next; 6480 } 6481 6482 token.value = value.slice(pos + 2, next); 6483 tokens.push(token); 6484 6485 pos = next + 2; 6486 code = value.charCodeAt(pos); 6487 6488 // Operation within calc 6489 } else if ( 6490 (code === slash || code === star) && 6491 parent && 6492 parent.type === "function" && 6493 parent.value === "calc" 6494 ) { 6495 token = value[pos]; 6496 tokens.push({ 6497 type: "word", 6498 sourceIndex: pos - before.length, 6499 sourceEndIndex: pos + token.length, 6500 value: token 6501 }); 6502 pos += 1; 6503 code = value.charCodeAt(pos); 6504 6505 // Dividers 6506 } else if (code === slash || code === comma || code === colon) { 6507 token = value[pos]; 6508 6509 tokens.push({ 6510 type: "div", 6511 sourceIndex: pos - before.length, 6512 sourceEndIndex: pos + token.length, 6513 value: token, 6514 before: before, 6515 after: "" 6516 }); 6517 before = ""; 6518 6519 pos += 1; 6520 code = value.charCodeAt(pos); 6521 6522 // Open parentheses 6523 } else if (openParentheses === code) { 6524 // Whitespaces after open parentheses 6525 next = pos; 6526 do { 6527 next += 1; 6528 code = value.charCodeAt(next); 6529 } while (code <= 32); 6530 parenthesesOpenPos = pos; 6531 token = { 6532 type: "function", 6533 sourceIndex: pos - name.length, 6534 value: name, 6535 before: value.slice(parenthesesOpenPos + 1, next) 6536 }; 6537 pos = next; 6538 6539 if (name === "url" && code !== singleQuote && code !== doubleQuote) { 6540 next -= 1; 6541 do { 6542 escape = false; 6543 next = value.indexOf(")", next + 1); 6544 if (~next) { 6545 escapePos = next; 6546 while (value.charCodeAt(escapePos - 1) === backslash) { 6547 escapePos -= 1; 6548 escape = !escape; 6549 } 6550 } else { 6551 value += ")"; 6552 next = value.length - 1; 6553 token.unclosed = true; 6554 } 6555 } while (escape); 6556 // Whitespaces before closed 6557 whitespacePos = next; 6558 do { 6559 whitespacePos -= 1; 6560 code = value.charCodeAt(whitespacePos); 6561 } while (code <= 32); 6562 if (parenthesesOpenPos < whitespacePos) { 6563 if (pos !== whitespacePos + 1) { 6564 token.nodes = [ 6565 { 6566 type: "word", 6567 sourceIndex: pos, 6568 sourceEndIndex: whitespacePos + 1, 6569 value: value.slice(pos, whitespacePos + 1) 6570 } 6571 ]; 6572 } else { 6573 token.nodes = []; 6574 } 6575 if (token.unclosed && whitespacePos + 1 !== next) { 6576 token.after = ""; 6577 token.nodes.push({ 6578 type: "space", 6579 sourceIndex: whitespacePos + 1, 6580 sourceEndIndex: next, 6581 value: value.slice(whitespacePos + 1, next) 6582 }); 6583 } else { 6584 token.after = value.slice(whitespacePos + 1, next); 6585 token.sourceEndIndex = next; 6586 } 6587 } else { 6588 token.after = ""; 6589 token.nodes = []; 6590 } 6591 pos = next + 1; 6592 token.sourceEndIndex = token.unclosed ? next : pos; 6593 code = value.charCodeAt(pos); 6594 tokens.push(token); 6595 } else { 6596 balanced += 1; 6597 token.after = ""; 6598 token.sourceEndIndex = pos + 1; 6599 tokens.push(token); 6600 stack.push(token); 6601 tokens = token.nodes = []; 6602 parent = token; 6603 } 6604 name = ""; 6605 6606 // Close parentheses 6607 } else if (closeParentheses === code && balanced) { 6608 pos += 1; 6609 code = value.charCodeAt(pos); 6610 6611 parent.after = after; 6612 parent.sourceEndIndex += after.length; 6613 after = ""; 6614 balanced -= 1; 6615 stack[stack.length - 1].sourceEndIndex = pos; 6616 stack.pop(); 6617 parent = stack[balanced]; 6618 tokens = parent.nodes; 6619 6620 // Words 6621 } else { 6622 next = pos; 6623 do { 6624 if (code === backslash) { 6625 next += 1; 6626 } 6627 next += 1; 6628 code = value.charCodeAt(next); 6629 } while ( 6630 next < max && 6631 !( 6632 code <= 32 || 6633 code === singleQuote || 6634 code === doubleQuote || 6635 code === comma || 6636 code === colon || 6637 code === slash || 6638 code === openParentheses || 6639 (code === star && 6640 parent && 6641 parent.type === "function" && 6642 parent.value === "calc") || 6643 (code === slash && 6644 parent.type === "function" && 6645 parent.value === "calc") || 6646 (code === closeParentheses && balanced) 6647 ) 6648 ); 6649 token = value.slice(pos, next); 6650 6651 if (openParentheses === code) { 6652 name = token; 6653 } else if ( 6654 (uLower === token.charCodeAt(0) || uUpper === token.charCodeAt(0)) && 6655 plus === token.charCodeAt(1) && 6656 isUnicodeRange.test(token.slice(2)) 6657 ) { 6658 tokens.push({ 6659 type: "unicode-range", 6660 sourceIndex: pos, 6661 sourceEndIndex: next, 6662 value: token 6663 }); 6664 } else { 6665 tokens.push({ 6666 type: "word", 6667 sourceIndex: pos, 6668 sourceEndIndex: next, 6669 value: token 6670 }); 6671 } 6672 6673 pos = next; 6674 } 6675 } 6676 6677 for (pos = stack.length - 1; pos; pos -= 1) { 6678 stack[pos].unclosed = true; 6679 stack[pos].sourceEndIndex = value.length; 6680 } 6681 6682 return stack[0].nodes; 6683 }; 6684 6685 6686 /***/ }), 6687 6688 /***/ 9055: 6689 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6690 6691 "use strict"; 6692 6693 6694 let Warning = __webpack_require__(5776) 6695 6696 class Result { 6697 get content() { 6698 return this.css 6699 } 6700 6701 constructor(processor, root, opts) { 6702 this.processor = processor 6703 this.messages = [] 6704 this.root = root 6705 this.opts = opts 6706 this.css = undefined 6707 this.map = undefined 6708 } 6709 6710 toString() { 6711 return this.css 6712 } 6713 6714 warn(text, opts = {}) { 6715 if (!opts.plugin) { 6716 if (this.lastPlugin && this.lastPlugin.postcssPlugin) { 6717 opts.plugin = this.lastPlugin.postcssPlugin 6718 } 6719 } 6720 6721 let warning = new Warning(text, opts) 6722 this.messages.push(warning) 6723 6724 return warning 6725 } 6726 6727 warnings() { 6728 return this.messages.filter(i => i.type === 'warning') 6729 } 6730 } 6731 6732 module.exports = Result 6733 Result.default = Result 6734 6735 6736 /***/ }), 6737 6738 /***/ 9434: 6739 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6740 6741 "use strict"; 6742 6743 6744 let Container = __webpack_require__(683) 6745 6746 let LazyResult, Processor 6747 6748 class Root extends Container { 6749 constructor(defaults) { 6750 super(defaults) 6751 this.type = 'root' 6752 if (!this.nodes) this.nodes = [] 6753 } 6754 6755 normalize(child, sample, type) { 6756 let nodes = super.normalize(child) 6757 6758 if (sample) { 6759 if (type === 'prepend') { 6760 if (this.nodes.length > 1) { 6761 sample.raws.before = this.nodes[1].raws.before 6762 } else { 6763 delete sample.raws.before 6764 } 6765 } else if (this.first !== sample) { 6766 for (let node of nodes) { 6767 node.raws.before = sample.raws.before 6768 } 6769 } 6770 } 6771 6772 return nodes 6773 } 6774 6775 removeChild(child, ignore) { 6776 let index = this.index(child) 6777 6778 if (!ignore && index === 0 && this.nodes.length > 1) { 6779 this.nodes[1].raws.before = this.nodes[index].raws.before 6780 } 6781 6782 return super.removeChild(child) 6783 } 6784 6785 toResult(opts = {}) { 6786 let lazy = new LazyResult(new Processor(), this, opts) 6787 return lazy.stringify() 6788 } 6789 } 6790 6791 Root.registerLazyResult = dependant => { 6792 LazyResult = dependant 6793 } 6794 6795 Root.registerProcessor = dependant => { 6796 Processor = dependant 6797 } 6798 6799 module.exports = Root 6800 Root.default = Root 6801 6802 Container.registerRoot(Root) 6803 6804 6805 /***/ }), 6806 6807 /***/ 9656: 6808 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 6809 6810 "use strict"; 6811 6812 6813 let Document = __webpack_require__(271) 6814 let LazyResult = __webpack_require__(448) 6815 let NoWorkResult = __webpack_require__(7661) 6816 let Root = __webpack_require__(9434) 6817 6818 class Processor { 6819 constructor(plugins = []) { 6820 this.version = '8.5.3' 6821 this.plugins = this.normalize(plugins) 6822 } 6823 6824 normalize(plugins) { 6825 let normalized = [] 6826 for (let i of plugins) { 6827 if (i.postcss === true) { 6828 i = i() 6829 } else if (i.postcss) { 6830 i = i.postcss 6831 } 6832 6833 if (typeof i === 'object' && Array.isArray(i.plugins)) { 6834 normalized = normalized.concat(i.plugins) 6835 } else if (typeof i === 'object' && i.postcssPlugin) { 6836 normalized.push(i) 6837 } else if (typeof i === 'function') { 6838 normalized.push(i) 6839 } else if (typeof i === 'object' && (i.parse || i.stringify)) { 6840 if (false) {} 6841 } else { 6842 throw new Error(i + ' is not a PostCSS plugin') 6843 } 6844 } 6845 return normalized 6846 } 6847 6848 process(css, opts = {}) { 6849 if ( 6850 !this.plugins.length && 6851 !opts.parser && 6852 !opts.stringifier && 6853 !opts.syntax 6854 ) { 6855 return new NoWorkResult(this, css, opts) 6856 } else { 6857 return new LazyResult(this, css, opts) 6858 } 6859 } 6860 6861 use(plugin) { 6862 this.plugins = this.plugins.concat(this.normalize([plugin])) 6863 return this 6864 } 6865 } 6866 6867 module.exports = Processor 6868 Processor.default = Processor 6869 6870 Root.registerProcessor(Processor) 6871 Document.registerProcessor(Processor) 6872 6873 6874 /***/ }), 6875 6876 /***/ 9681: 6877 /***/ ((module) => { 6878 6879 var characterMap = { 6880 "À": "A", 6881 "Á": "A", 6882 "Â": "A", 6883 "Ã": "A", 6884 "Ä": "A", 6885 "Å": "A", 6886 "Ấ": "A", 6887 "Ắ": "A", 6888 "Ẳ": "A", 6889 "Ẵ": "A", 6890 "Ặ": "A", 6891 "Æ": "AE", 6892 "Ầ": "A", 6893 "Ằ": "A", 6894 "Ȃ": "A", 6895 "Ả": "A", 6896 "Ạ": "A", 6897 "Ẩ": "A", 6898 "Ẫ": "A", 6899 "Ậ": "A", 6900 "Ç": "C", 6901 "Ḉ": "C", 6902 "È": "E", 6903 "É": "E", 6904 "Ê": "E", 6905 "Ë": "E", 6906 "Ế": "E", 6907 "Ḗ": "E", 6908 "Ề": "E", 6909 "Ḕ": "E", 6910 "Ḝ": "E", 6911 "Ȇ": "E", 6912 "Ẻ": "E", 6913 "Ẽ": "E", 6914 "Ẹ": "E", 6915 "Ể": "E", 6916 "Ễ": "E", 6917 "Ệ": "E", 6918 "Ì": "I", 6919 "Í": "I", 6920 "Î": "I", 6921 "Ï": "I", 6922 "Ḯ": "I", 6923 "Ȋ": "I", 6924 "Ỉ": "I", 6925 "Ị": "I", 6926 "Ð": "D", 6927 "Ñ": "N", 6928 "Ò": "O", 6929 "Ó": "O", 6930 "Ô": "O", 6931 "Õ": "O", 6932 "Ö": "O", 6933 "Ø": "O", 6934 "Ố": "O", 6935 "Ṍ": "O", 6936 "Ṓ": "O", 6937 "Ȏ": "O", 6938 "Ỏ": "O", 6939 "Ọ": "O", 6940 "Ổ": "O", 6941 "Ỗ": "O", 6942 "Ộ": "O", 6943 "Ờ": "O", 6944 "Ở": "O", 6945 "Ỡ": "O", 6946 "Ớ": "O", 6947 "Ợ": "O", 6948 "Ù": "U", 6949 "Ú": "U", 6950 "Û": "U", 6951 "Ü": "U", 6952 "Ủ": "U", 6953 "Ụ": "U", 6954 "Ử": "U", 6955 "Ữ": "U", 6956 "Ự": "U", 6957 "Ý": "Y", 6958 "à": "a", 6959 "á": "a", 6960 "â": "a", 6961 "ã": "a", 6962 "ä": "a", 6963 "å": "a", 6964 "ấ": "a", 6965 "ắ": "a", 6966 "ẳ": "a", 6967 "ẵ": "a", 6968 "ặ": "a", 6969 "æ": "ae", 6970 "ầ": "a", 6971 "ằ": "a", 6972 "ȃ": "a", 6973 "ả": "a", 6974 "ạ": "a", 6975 "ẩ": "a", 6976 "ẫ": "a", 6977 "ậ": "a", 6978 "ç": "c", 6979 "ḉ": "c", 6980 "è": "e", 6981 "é": "e", 6982 "ê": "e", 6983 "ë": "e", 6984 "ế": "e", 6985 "ḗ": "e", 6986 "ề": "e", 6987 "ḕ": "e", 6988 "ḝ": "e", 6989 "ȇ": "e", 6990 "ẻ": "e", 6991 "ẽ": "e", 6992 "ẹ": "e", 6993 "ể": "e", 6994 "ễ": "e", 6995 "ệ": "e", 6996 "ì": "i", 6997 "í": "i", 6998 "î": "i", 6999 "ï": "i", 7000 "ḯ": "i", 7001 "ȋ": "i", 7002 "ỉ": "i", 7003 "ị": "i", 7004 "ð": "d", 7005 "ñ": "n", 7006 "ò": "o", 7007 "ó": "o", 7008 "ô": "o", 7009 "õ": "o", 7010 "ö": "o", 7011 "ø": "o", 7012 "ố": "o", 7013 "ṍ": "o", 7014 "ṓ": "o", 7015 "ȏ": "o", 7016 "ỏ": "o", 7017 "ọ": "o", 7018 "ổ": "o", 7019 "ỗ": "o", 7020 "ộ": "o", 7021 "ờ": "o", 7022 "ở": "o", 7023 "ỡ": "o", 7024 "ớ": "o", 7025 "ợ": "o", 7026 "ù": "u", 7027 "ú": "u", 7028 "û": "u", 7029 "ü": "u", 7030 "ủ": "u", 7031 "ụ": "u", 7032 "ử": "u", 7033 "ữ": "u", 7034 "ự": "u", 7035 "ý": "y", 7036 "ÿ": "y", 7037 "Ā": "A", 7038 "ā": "a", 7039 "Ă": "A", 7040 "ă": "a", 7041 "Ą": "A", 7042 "ą": "a", 7043 "Ć": "C", 7044 "ć": "c", 7045 "Ĉ": "C", 7046 "ĉ": "c", 7047 "Ċ": "C", 7048 "ċ": "c", 7049 "Č": "C", 7050 "č": "c", 7051 "C̆": "C", 7052 "c̆": "c", 7053 "Ď": "D", 7054 "ď": "d", 7055 "Đ": "D", 7056 "đ": "d", 7057 "Ē": "E", 7058 "ē": "e", 7059 "Ĕ": "E", 7060 "ĕ": "e", 7061 "Ė": "E", 7062 "ė": "e", 7063 "Ę": "E", 7064 "ę": "e", 7065 "Ě": "E", 7066 "ě": "e", 7067 "Ĝ": "G", 7068 "Ǵ": "G", 7069 "ĝ": "g", 7070 "ǵ": "g", 7071 "Ğ": "G", 7072 "ğ": "g", 7073 "Ġ": "G", 7074 "ġ": "g", 7075 "Ģ": "G", 7076 "ģ": "g", 7077 "Ĥ": "H", 7078 "ĥ": "h", 7079 "Ħ": "H", 7080 "ħ": "h", 7081 "Ḫ": "H", 7082 "ḫ": "h", 7083 "Ĩ": "I", 7084 "ĩ": "i", 7085 "Ī": "I", 7086 "ī": "i", 7087 "Ĭ": "I", 7088 "ĭ": "i", 7089 "Į": "I", 7090 "į": "i", 7091 "İ": "I", 7092 "ı": "i", 7093 "IJ": "IJ", 7094 "ij": "ij", 7095 "Ĵ": "J", 7096 "ĵ": "j", 7097 "Ķ": "K", 7098 "ķ": "k", 7099 "Ḱ": "K", 7100 "ḱ": "k", 7101 "K̆": "K", 7102 "k̆": "k", 7103 "Ĺ": "L", 7104 "ĺ": "l", 7105 "Ļ": "L", 7106 "ļ": "l", 7107 "Ľ": "L", 7108 "ľ": "l", 7109 "Ŀ": "L", 7110 "ŀ": "l", 7111 "Ł": "l", 7112 "ł": "l", 7113 "Ḿ": "M", 7114 "ḿ": "m", 7115 "M̆": "M", 7116 "m̆": "m", 7117 "Ń": "N", 7118 "ń": "n", 7119 "Ņ": "N", 7120 "ņ": "n", 7121 "Ň": "N", 7122 "ň": "n", 7123 "ʼn": "n", 7124 "N̆": "N", 7125 "n̆": "n", 7126 "Ō": "O", 7127 "ō": "o", 7128 "Ŏ": "O", 7129 "ŏ": "o", 7130 "Ő": "O", 7131 "ő": "o", 7132 "Œ": "OE", 7133 "œ": "oe", 7134 "P̆": "P", 7135 "p̆": "p", 7136 "Ŕ": "R", 7137 "ŕ": "r", 7138 "Ŗ": "R", 7139 "ŗ": "r", 7140 "Ř": "R", 7141 "ř": "r", 7142 "R̆": "R", 7143 "r̆": "r", 7144 "Ȓ": "R", 7145 "ȓ": "r", 7146 "Ś": "S", 7147 "ś": "s", 7148 "Ŝ": "S", 7149 "ŝ": "s", 7150 "Ş": "S", 7151 "Ș": "S", 7152 "ș": "s", 7153 "ş": "s", 7154 "Š": "S", 7155 "š": "s", 7156 "Ţ": "T", 7157 "ţ": "t", 7158 "ț": "t", 7159 "Ț": "T", 7160 "Ť": "T", 7161 "ť": "t", 7162 "Ŧ": "T", 7163 "ŧ": "t", 7164 "T̆": "T", 7165 "t̆": "t", 7166 "Ũ": "U", 7167 "ũ": "u", 7168 "Ū": "U", 7169 "ū": "u", 7170 "Ŭ": "U", 7171 "ŭ": "u", 7172 "Ů": "U", 7173 "ů": "u", 7174 "Ű": "U", 7175 "ű": "u", 7176 "Ų": "U", 7177 "ų": "u", 7178 "Ȗ": "U", 7179 "ȗ": "u", 7180 "V̆": "V", 7181 "v̆": "v", 7182 "Ŵ": "W", 7183 "ŵ": "w", 7184 "Ẃ": "W", 7185 "ẃ": "w", 7186 "X̆": "X", 7187 "x̆": "x", 7188 "Ŷ": "Y", 7189 "ŷ": "y", 7190 "Ÿ": "Y", 7191 "Y̆": "Y", 7192 "y̆": "y", 7193 "Ź": "Z", 7194 "ź": "z", 7195 "Ż": "Z", 7196 "ż": "z", 7197 "Ž": "Z", 7198 "ž": "z", 7199 "ſ": "s", 7200 "ƒ": "f", 7201 "Ơ": "O", 7202 "ơ": "o", 7203 "Ư": "U", 7204 "ư": "u", 7205 "Ǎ": "A", 7206 "ǎ": "a", 7207 "Ǐ": "I", 7208 "ǐ": "i", 7209 "Ǒ": "O", 7210 "ǒ": "o", 7211 "Ǔ": "U", 7212 "ǔ": "u", 7213 "Ǖ": "U", 7214 "ǖ": "u", 7215 "Ǘ": "U", 7216 "ǘ": "u", 7217 "Ǚ": "U", 7218 "ǚ": "u", 7219 "Ǜ": "U", 7220 "ǜ": "u", 7221 "Ứ": "U", 7222 "ứ": "u", 7223 "Ṹ": "U", 7224 "ṹ": "u", 7225 "Ǻ": "A", 7226 "ǻ": "a", 7227 "Ǽ": "AE", 7228 "ǽ": "ae", 7229 "Ǿ": "O", 7230 "ǿ": "o", 7231 "Þ": "TH", 7232 "þ": "th", 7233 "Ṕ": "P", 7234 "ṕ": "p", 7235 "Ṥ": "S", 7236 "ṥ": "s", 7237 "X́": "X", 7238 "x́": "x", 7239 "Ѓ": "Г", 7240 "ѓ": "г", 7241 "Ќ": "К", 7242 "ќ": "к", 7243 "A̋": "A", 7244 "a̋": "a", 7245 "E̋": "E", 7246 "e̋": "e", 7247 "I̋": "I", 7248 "i̋": "i", 7249 "Ǹ": "N", 7250 "ǹ": "n", 7251 "Ồ": "O", 7252 "ồ": "o", 7253 "Ṑ": "O", 7254 "ṑ": "o", 7255 "Ừ": "U", 7256 "ừ": "u", 7257 "Ẁ": "W", 7258 "ẁ": "w", 7259 "Ỳ": "Y", 7260 "ỳ": "y", 7261 "Ȁ": "A", 7262 "ȁ": "a", 7263 "Ȅ": "E", 7264 "ȅ": "e", 7265 "Ȉ": "I", 7266 "ȉ": "i", 7267 "Ȍ": "O", 7268 "ȍ": "o", 7269 "Ȑ": "R", 7270 "ȑ": "r", 7271 "Ȕ": "U", 7272 "ȕ": "u", 7273 "B̌": "B", 7274 "b̌": "b", 7275 "Č̣": "C", 7276 "č̣": "c", 7277 "Ê̌": "E", 7278 "ê̌": "e", 7279 "F̌": "F", 7280 "f̌": "f", 7281 "Ǧ": "G", 7282 "ǧ": "g", 7283 "Ȟ": "H", 7284 "ȟ": "h", 7285 "J̌": "J", 7286 "ǰ": "j", 7287 "Ǩ": "K", 7288 "ǩ": "k", 7289 "M̌": "M", 7290 "m̌": "m", 7291 "P̌": "P", 7292 "p̌": "p", 7293 "Q̌": "Q", 7294 "q̌": "q", 7295 "Ř̩": "R", 7296 "ř̩": "r", 7297 "Ṧ": "S", 7298 "ṧ": "s", 7299 "V̌": "V", 7300 "v̌": "v", 7301 "W̌": "W", 7302 "w̌": "w", 7303 "X̌": "X", 7304 "x̌": "x", 7305 "Y̌": "Y", 7306 "y̌": "y", 7307 "A̧": "A", 7308 "a̧": "a", 7309 "B̧": "B", 7310 "b̧": "b", 7311 "Ḑ": "D", 7312 "ḑ": "d", 7313 "Ȩ": "E", 7314 "ȩ": "e", 7315 "Ɛ̧": "E", 7316 "ɛ̧": "e", 7317 "Ḩ": "H", 7318 "ḩ": "h", 7319 "I̧": "I", 7320 "i̧": "i", 7321 "Ɨ̧": "I", 7322 "ɨ̧": "i", 7323 "M̧": "M", 7324 "m̧": "m", 7325 "O̧": "O", 7326 "o̧": "o", 7327 "Q̧": "Q", 7328 "q̧": "q", 7329 "U̧": "U", 7330 "u̧": "u", 7331 "X̧": "X", 7332 "x̧": "x", 7333 "Z̧": "Z", 7334 "z̧": "z", 7335 "й":"и", 7336 "Й":"И", 7337 "ё":"е", 7338 "Ё":"Е", 7339 }; 7340 7341 var chars = Object.keys(characterMap).join('|'); 7342 var allAccents = new RegExp(chars, 'g'); 7343 var firstAccent = new RegExp(chars, ''); 7344 7345 function matcher(match) { 7346 return characterMap[match]; 7347 } 7348 7349 var removeAccents = function(string) { 7350 return string.replace(allAccents, matcher); 7351 }; 7352 7353 var hasAccents = function(string) { 7354 return !!string.match(firstAccent); 7355 }; 7356 7357 module.exports = removeAccents; 7358 module.exports.has = hasAccents; 7359 module.exports.remove = removeAccents; 7360 7361 7362 /***/ }), 7363 7364 /***/ 9746: 7365 /***/ (() => { 7366 7367 /* (ignored) */ 7368 7369 /***/ }), 7370 7371 /***/ 9977: 7372 /***/ (() => { 7373 7374 /* (ignored) */ 7375 7376 /***/ }) 7377 7378 /******/ }); 7379 /************************************************************************/ 7380 /******/ // The module cache 7381 /******/ var __webpack_module_cache__ = {}; 7382 /******/ 7383 /******/ // The require function 7384 /******/ function __webpack_require__(moduleId) { 7385 /******/ // Check if module is in cache 7386 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 7387 /******/ if (cachedModule !== undefined) { 7388 /******/ return cachedModule.exports; 7389 /******/ } 7390 /******/ // Create a new module (and put it into the cache) 7391 /******/ var module = __webpack_module_cache__[moduleId] = { 7392 /******/ // no module.id needed 7393 /******/ // no module.loaded needed 7394 /******/ exports: {} 7395 /******/ }; 7396 /******/ 7397 /******/ // Execute the module function 7398 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 7399 /******/ 7400 /******/ // Return the exports of the module 7401 /******/ return module.exports; 7402 /******/ } 7403 /******/ 7404 /************************************************************************/ 7405 /******/ /* webpack/runtime/compat get default export */ 7406 /******/ (() => { 7407 /******/ // getDefaultExport function for compatibility with non-harmony modules 7408 /******/ __webpack_require__.n = (module) => { 7409 /******/ var getter = module && module.__esModule ? 7410 /******/ () => (module['default']) : 7411 /******/ () => (module); 7412 /******/ __webpack_require__.d(getter, { a: getter }); 7413 /******/ return getter; 7414 /******/ }; 7415 /******/ })(); 7416 /******/ 7417 /******/ /* webpack/runtime/define property getters */ 7418 /******/ (() => { 7419 /******/ // define getter functions for harmony exports 7420 /******/ __webpack_require__.d = (exports, definition) => { 7421 /******/ for(var key in definition) { 7422 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 7423 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 7424 /******/ } 7425 /******/ } 7426 /******/ }; 7427 /******/ })(); 7428 /******/ 7429 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 7430 /******/ (() => { 7431 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 7432 /******/ })(); 7433 /******/ 7434 /******/ /* webpack/runtime/make namespace object */ 7435 /******/ (() => { 7436 /******/ // define __esModule on exports 7437 /******/ __webpack_require__.r = (exports) => { 7438 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 7439 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 7440 /******/ } 7441 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 7442 /******/ }; 7443 /******/ })(); 7444 /******/ 7445 /************************************************************************/ 7446 var __webpack_exports__ = {}; 7447 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode. 7448 (() => { 7449 "use strict"; 7450 // ESM COMPAT FLAG 7451 __webpack_require__.r(__webpack_exports__); 7452 7453 // EXPORTS 7454 __webpack_require__.d(__webpack_exports__, { 7455 AlignmentControl: () => (/* reexport */ AlignmentControl), 7456 AlignmentToolbar: () => (/* reexport */ AlignmentToolbar), 7457 Autocomplete: () => (/* reexport */ autocomplete), 7458 BlockAlignmentControl: () => (/* reexport */ BlockAlignmentControl), 7459 BlockAlignmentToolbar: () => (/* reexport */ BlockAlignmentToolbar), 7460 BlockBreadcrumb: () => (/* reexport */ block_breadcrumb), 7461 BlockCanvas: () => (/* reexport */ block_canvas), 7462 BlockColorsStyleSelector: () => (/* reexport */ color_style_selector), 7463 BlockContextProvider: () => (/* reexport */ BlockContextProvider), 7464 BlockControls: () => (/* reexport */ block_controls), 7465 BlockEdit: () => (/* reexport */ BlockEdit), 7466 BlockEditorKeyboardShortcuts: () => (/* reexport */ keyboard_shortcuts), 7467 BlockEditorProvider: () => (/* reexport */ components_provider), 7468 BlockFormatControls: () => (/* reexport */ BlockFormatControls), 7469 BlockIcon: () => (/* reexport */ block_icon), 7470 BlockInspector: () => (/* reexport */ block_inspector), 7471 BlockList: () => (/* reexport */ BlockList), 7472 BlockMover: () => (/* reexport */ block_mover), 7473 BlockNavigationDropdown: () => (/* reexport */ dropdown), 7474 BlockPopover: () => (/* reexport */ block_popover), 7475 BlockPreview: () => (/* reexport */ block_preview), 7476 BlockSelectionClearer: () => (/* reexport */ BlockSelectionClearer), 7477 BlockSettingsMenu: () => (/* reexport */ block_settings_menu), 7478 BlockSettingsMenuControls: () => (/* reexport */ block_settings_menu_controls), 7479 BlockStyles: () => (/* reexport */ block_styles), 7480 BlockTitle: () => (/* reexport */ BlockTitle), 7481 BlockToolbar: () => (/* reexport */ BlockToolbar), 7482 BlockTools: () => (/* reexport */ BlockTools), 7483 BlockVerticalAlignmentControl: () => (/* reexport */ BlockVerticalAlignmentControl), 7484 BlockVerticalAlignmentToolbar: () => (/* reexport */ BlockVerticalAlignmentToolbar), 7485 ButtonBlockAppender: () => (/* reexport */ button_block_appender), 7486 ButtonBlockerAppender: () => (/* reexport */ ButtonBlockerAppender), 7487 ColorPalette: () => (/* reexport */ color_palette), 7488 ColorPaletteControl: () => (/* reexport */ ColorPaletteControl), 7489 ContrastChecker: () => (/* reexport */ contrast_checker), 7490 CopyHandler: () => (/* reexport */ CopyHandler), 7491 DefaultBlockAppender: () => (/* reexport */ DefaultBlockAppender), 7492 FontSizePicker: () => (/* reexport */ font_size_picker), 7493 HeadingLevelDropdown: () => (/* reexport */ HeadingLevelDropdown), 7494 HeightControl: () => (/* reexport */ HeightControl), 7495 InnerBlocks: () => (/* reexport */ inner_blocks), 7496 Inserter: () => (/* reexport */ inserter), 7497 InspectorAdvancedControls: () => (/* reexport */ InspectorAdvancedControls), 7498 InspectorControls: () => (/* reexport */ inspector_controls), 7499 JustifyContentControl: () => (/* reexport */ JustifyContentControl), 7500 JustifyToolbar: () => (/* reexport */ JustifyToolbar), 7501 LineHeightControl: () => (/* reexport */ line_height_control), 7502 LinkControl: () => (/* reexport */ link_control), 7503 MediaPlaceholder: () => (/* reexport */ media_placeholder), 7504 MediaReplaceFlow: () => (/* reexport */ media_replace_flow), 7505 MediaUpload: () => (/* reexport */ media_upload), 7506 MediaUploadCheck: () => (/* reexport */ check), 7507 MultiSelectScrollIntoView: () => (/* reexport */ MultiSelectScrollIntoView), 7508 NavigableToolbar: () => (/* reexport */ NavigableToolbar), 7509 ObserveTyping: () => (/* reexport */ observe_typing), 7510 PanelColorSettings: () => (/* reexport */ panel_color_settings), 7511 PlainText: () => (/* reexport */ plain_text), 7512 RecursionProvider: () => (/* reexport */ RecursionProvider), 7513 RichText: () => (/* reexport */ rich_text), 7514 RichTextShortcut: () => (/* reexport */ RichTextShortcut), 7515 RichTextToolbarButton: () => (/* reexport */ RichTextToolbarButton), 7516 SETTINGS_DEFAULTS: () => (/* reexport */ SETTINGS_DEFAULTS), 7517 SkipToSelectedBlock: () => (/* reexport */ SkipToSelectedBlock), 7518 ToolSelector: () => (/* reexport */ tool_selector), 7519 Typewriter: () => (/* reexport */ typewriter), 7520 URLInput: () => (/* reexport */ url_input), 7521 URLInputButton: () => (/* reexport */ url_input_button), 7522 URLPopover: () => (/* reexport */ url_popover), 7523 Warning: () => (/* reexport */ warning), 7524 WritingFlow: () => (/* reexport */ writing_flow), 7525 __experimentalBlockAlignmentMatrixControl: () => (/* reexport */ block_alignment_matrix_control), 7526 __experimentalBlockFullHeightAligmentControl: () => (/* reexport */ block_full_height_alignment_control), 7527 __experimentalBlockPatternSetup: () => (/* reexport */ block_pattern_setup), 7528 __experimentalBlockPatternsList: () => (/* reexport */ block_patterns_list), 7529 __experimentalBlockVariationPicker: () => (/* reexport */ block_variation_picker), 7530 __experimentalBlockVariationTransforms: () => (/* reexport */ block_variation_transforms), 7531 __experimentalBorderRadiusControl: () => (/* reexport */ BorderRadiusControl), 7532 __experimentalColorGradientControl: () => (/* reexport */ control), 7533 __experimentalColorGradientSettingsDropdown: () => (/* reexport */ ColorGradientSettingsDropdown), 7534 __experimentalDateFormatPicker: () => (/* reexport */ DateFormatPicker), 7535 __experimentalDuotoneControl: () => (/* reexport */ duotone_control), 7536 __experimentalFontAppearanceControl: () => (/* reexport */ FontAppearanceControl), 7537 __experimentalFontFamilyControl: () => (/* reexport */ FontFamilyControl), 7538 __experimentalGetBorderClassesAndStyles: () => (/* reexport */ getBorderClassesAndStyles), 7539 __experimentalGetColorClassesAndStyles: () => (/* reexport */ getColorClassesAndStyles), 7540 __experimentalGetElementClassName: () => (/* reexport */ __experimentalGetElementClassName), 7541 __experimentalGetGapCSSValue: () => (/* reexport */ getGapCSSValue), 7542 __experimentalGetGradientClass: () => (/* reexport */ __experimentalGetGradientClass), 7543 __experimentalGetGradientObjectByGradientValue: () => (/* reexport */ __experimentalGetGradientObjectByGradientValue), 7544 __experimentalGetShadowClassesAndStyles: () => (/* reexport */ getShadowClassesAndStyles), 7545 __experimentalGetSpacingClassesAndStyles: () => (/* reexport */ getSpacingClassesAndStyles), 7546 __experimentalImageEditor: () => (/* reexport */ ImageEditor), 7547 __experimentalImageSizeControl: () => (/* reexport */ ImageSizeControl), 7548 __experimentalImageURLInputUI: () => (/* reexport */ ImageURLInputUI), 7549 __experimentalInspectorPopoverHeader: () => (/* reexport */ InspectorPopoverHeader), 7550 __experimentalLetterSpacingControl: () => (/* reexport */ LetterSpacingControl), 7551 __experimentalLibrary: () => (/* reexport */ library), 7552 __experimentalLinkControl: () => (/* reexport */ DeprecatedExperimentalLinkControl), 7553 __experimentalLinkControlSearchInput: () => (/* reexport */ __experimentalLinkControlSearchInput), 7554 __experimentalLinkControlSearchItem: () => (/* reexport */ __experimentalLinkControlSearchItem), 7555 __experimentalLinkControlSearchResults: () => (/* reexport */ __experimentalLinkControlSearchResults), 7556 __experimentalListView: () => (/* reexport */ components_list_view), 7557 __experimentalPanelColorGradientSettings: () => (/* reexport */ panel_color_gradient_settings), 7558 __experimentalPreviewOptions: () => (/* reexport */ PreviewOptions), 7559 __experimentalPublishDateTimePicker: () => (/* reexport */ publish_date_time_picker), 7560 __experimentalRecursionProvider: () => (/* reexport */ DeprecatedExperimentalRecursionProvider), 7561 __experimentalResponsiveBlockControl: () => (/* reexport */ responsive_block_control), 7562 __experimentalSpacingSizesControl: () => (/* reexport */ SpacingSizesControl), 7563 __experimentalTextDecorationControl: () => (/* reexport */ TextDecorationControl), 7564 __experimentalTextTransformControl: () => (/* reexport */ TextTransformControl), 7565 __experimentalUnitControl: () => (/* reexport */ UnitControl), 7566 __experimentalUseBlockOverlayActive: () => (/* reexport */ useBlockOverlayActive), 7567 __experimentalUseBlockPreview: () => (/* reexport */ useBlockPreview), 7568 __experimentalUseBorderProps: () => (/* reexport */ useBorderProps), 7569 __experimentalUseColorProps: () => (/* reexport */ useColorProps), 7570 __experimentalUseCustomSides: () => (/* reexport */ useCustomSides), 7571 __experimentalUseGradient: () => (/* reexport */ __experimentalUseGradient), 7572 __experimentalUseHasRecursion: () => (/* reexport */ DeprecatedExperimentalUseHasRecursion), 7573 __experimentalUseMultipleOriginColorsAndGradients: () => (/* reexport */ useMultipleOriginColorsAndGradients), 7574 __experimentalUseResizeCanvas: () => (/* reexport */ useResizeCanvas), 7575 __experimentalWritingModeControl: () => (/* reexport */ WritingModeControl), 7576 __unstableBlockNameContext: () => (/* reexport */ block_name_context), 7577 __unstableBlockSettingsMenuFirstItem: () => (/* reexport */ block_settings_menu_first_item), 7578 __unstableBlockToolbarLastItem: () => (/* reexport */ block_toolbar_last_item), 7579 __unstableEditorStyles: () => (/* reexport */ editor_styles), 7580 __unstableIframe: () => (/* reexport */ iframe), 7581 __unstableInserterMenuExtension: () => (/* reexport */ inserter_menu_extension), 7582 __unstableRichTextInputEvent: () => (/* reexport */ __unstableRichTextInputEvent), 7583 __unstableUseBlockSelectionClearer: () => (/* reexport */ useBlockSelectionClearer), 7584 __unstableUseClipboardHandler: () => (/* reexport */ __unstableUseClipboardHandler), 7585 __unstableUseMouseMoveTypingReset: () => (/* reexport */ useMouseMoveTypingReset), 7586 __unstableUseTypewriter: () => (/* reexport */ useTypewriter), 7587 __unstableUseTypingObserver: () => (/* reexport */ useTypingObserver), 7588 createCustomColorsHOC: () => (/* reexport */ createCustomColorsHOC), 7589 getColorClassName: () => (/* reexport */ getColorClassName), 7590 getColorObjectByAttributeValues: () => (/* reexport */ getColorObjectByAttributeValues), 7591 getColorObjectByColorValue: () => (/* reexport */ getColorObjectByColorValue), 7592 getComputedFluidTypographyValue: () => (/* reexport */ getComputedFluidTypographyValue), 7593 getCustomValueFromPreset: () => (/* reexport */ getCustomValueFromPreset), 7594 getFontSize: () => (/* reexport */ utils_getFontSize), 7595 getFontSizeClass: () => (/* reexport */ getFontSizeClass), 7596 getFontSizeObjectByValue: () => (/* reexport */ utils_getFontSizeObjectByValue), 7597 getGradientSlugByValue: () => (/* reexport */ getGradientSlugByValue), 7598 getGradientValueBySlug: () => (/* reexport */ getGradientValueBySlug), 7599 getPxFromCssUnit: () => (/* reexport */ get_px_from_css_unit), 7600 getSpacingPresetCssVar: () => (/* reexport */ getSpacingPresetCssVar), 7601 getTypographyClassesAndStyles: () => (/* reexport */ getTypographyClassesAndStyles), 7602 isValueSpacingPreset: () => (/* reexport */ isValueSpacingPreset), 7603 privateApis: () => (/* reexport */ privateApis), 7604 store: () => (/* reexport */ store), 7605 storeConfig: () => (/* reexport */ storeConfig), 7606 transformStyles: () => (/* reexport */ transform_styles), 7607 useBlockBindingsUtils: () => (/* reexport */ useBlockBindingsUtils), 7608 useBlockCommands: () => (/* reexport */ useBlockCommands), 7609 useBlockDisplayInformation: () => (/* reexport */ useBlockDisplayInformation), 7610 useBlockEditContext: () => (/* reexport */ useBlockEditContext), 7611 useBlockEditingMode: () => (/* reexport */ useBlockEditingMode), 7612 useBlockProps: () => (/* reexport */ use_block_props_useBlockProps), 7613 useCachedTruthy: () => (/* reexport */ useCachedTruthy), 7614 useHasRecursion: () => (/* reexport */ useHasRecursion), 7615 useInnerBlocksProps: () => (/* reexport */ useInnerBlocksProps), 7616 useSetting: () => (/* reexport */ useSetting), 7617 useSettings: () => (/* reexport */ use_settings_useSettings), 7618 useStyleOverride: () => (/* reexport */ useStyleOverride), 7619 withColorContext: () => (/* reexport */ with_color_context), 7620 withColors: () => (/* reexport */ withColors), 7621 withFontSizes: () => (/* reexport */ with_font_sizes) 7622 }); 7623 7624 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/private-selectors.js 7625 var private_selectors_namespaceObject = {}; 7626 __webpack_require__.r(private_selectors_namespaceObject); 7627 __webpack_require__.d(private_selectors_namespaceObject, { 7628 getAllPatterns: () => (getAllPatterns), 7629 getBlockRemovalRules: () => (getBlockRemovalRules), 7630 getBlockSettings: () => (getBlockSettings), 7631 getBlockStyles: () => (getBlockStyles), 7632 getBlockWithoutAttributes: () => (getBlockWithoutAttributes), 7633 getClosestAllowedInsertionPoint: () => (getClosestAllowedInsertionPoint), 7634 getClosestAllowedInsertionPointForPattern: () => (getClosestAllowedInsertionPointForPattern), 7635 getContentLockingParent: () => (getContentLockingParent), 7636 getEnabledBlockParents: () => (getEnabledBlockParents), 7637 getEnabledClientIdsTree: () => (getEnabledClientIdsTree), 7638 getExpandedBlock: () => (getExpandedBlock), 7639 getInserterMediaCategories: () => (getInserterMediaCategories), 7640 getInsertionPoint: () => (getInsertionPoint), 7641 getLastFocus: () => (getLastFocus), 7642 getLastInsertedBlocksClientIds: () => (getLastInsertedBlocksClientIds), 7643 getOpenedBlockSettingsMenu: () => (getOpenedBlockSettingsMenu), 7644 getParentSectionBlock: () => (getParentSectionBlock), 7645 getPatternBySlug: () => (getPatternBySlug), 7646 getRegisteredInserterMediaCategories: () => (getRegisteredInserterMediaCategories), 7647 getRemovalPromptData: () => (getRemovalPromptData), 7648 getReusableBlocks: () => (getReusableBlocks), 7649 getSectionRootClientId: () => (getSectionRootClientId), 7650 getStyleOverrides: () => (getStyleOverrides), 7651 getTemporarilyEditingAsBlocks: () => (getTemporarilyEditingAsBlocks), 7652 getTemporarilyEditingFocusModeToRevert: () => (getTemporarilyEditingFocusModeToRevert), 7653 getZoomLevel: () => (getZoomLevel), 7654 hasAllowedPatterns: () => (hasAllowedPatterns), 7655 isBlockInterfaceHidden: () => (private_selectors_isBlockInterfaceHidden), 7656 isBlockSubtreeDisabled: () => (isBlockSubtreeDisabled), 7657 isDragging: () => (private_selectors_isDragging), 7658 isSectionBlock: () => (isSectionBlock), 7659 isZoomOut: () => (isZoomOut) 7660 }); 7661 7662 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/selectors.js 7663 var selectors_namespaceObject = {}; 7664 __webpack_require__.r(selectors_namespaceObject); 7665 __webpack_require__.d(selectors_namespaceObject, { 7666 __experimentalGetActiveBlockIdByBlockNames: () => (__experimentalGetActiveBlockIdByBlockNames), 7667 __experimentalGetAllowedBlocks: () => (__experimentalGetAllowedBlocks), 7668 __experimentalGetAllowedPatterns: () => (__experimentalGetAllowedPatterns), 7669 __experimentalGetBlockListSettingsForBlocks: () => (__experimentalGetBlockListSettingsForBlocks), 7670 __experimentalGetDirectInsertBlock: () => (__experimentalGetDirectInsertBlock), 7671 __experimentalGetGlobalBlocksByName: () => (__experimentalGetGlobalBlocksByName), 7672 __experimentalGetLastBlockAttributeChanges: () => (__experimentalGetLastBlockAttributeChanges), 7673 __experimentalGetParsedPattern: () => (__experimentalGetParsedPattern), 7674 __experimentalGetPatternTransformItems: () => (__experimentalGetPatternTransformItems), 7675 __experimentalGetPatternsByBlockTypes: () => (__experimentalGetPatternsByBlockTypes), 7676 __experimentalGetReusableBlockTitle: () => (__experimentalGetReusableBlockTitle), 7677 __unstableGetBlockWithoutInnerBlocks: () => (__unstableGetBlockWithoutInnerBlocks), 7678 __unstableGetClientIdWithClientIdsTree: () => (__unstableGetClientIdWithClientIdsTree), 7679 __unstableGetClientIdsTree: () => (__unstableGetClientIdsTree), 7680 __unstableGetContentLockingParent: () => (__unstableGetContentLockingParent), 7681 __unstableGetEditorMode: () => (__unstableGetEditorMode), 7682 __unstableGetSelectedBlocksWithPartialSelection: () => (__unstableGetSelectedBlocksWithPartialSelection), 7683 __unstableGetTemporarilyEditingAsBlocks: () => (__unstableGetTemporarilyEditingAsBlocks), 7684 __unstableGetTemporarilyEditingFocusModeToRevert: () => (__unstableGetTemporarilyEditingFocusModeToRevert), 7685 __unstableGetVisibleBlocks: () => (__unstableGetVisibleBlocks), 7686 __unstableHasActiveBlockOverlayActive: () => (__unstableHasActiveBlockOverlayActive), 7687 __unstableIsFullySelected: () => (__unstableIsFullySelected), 7688 __unstableIsLastBlockChangeIgnored: () => (__unstableIsLastBlockChangeIgnored), 7689 __unstableIsSelectionCollapsed: () => (__unstableIsSelectionCollapsed), 7690 __unstableIsSelectionMergeable: () => (__unstableIsSelectionMergeable), 7691 __unstableIsWithinBlockOverlay: () => (__unstableIsWithinBlockOverlay), 7692 __unstableSelectionHasUnmergeableBlock: () => (__unstableSelectionHasUnmergeableBlock), 7693 areInnerBlocksControlled: () => (areInnerBlocksControlled), 7694 canEditBlock: () => (canEditBlock), 7695 canInsertBlockType: () => (canInsertBlockType), 7696 canInsertBlocks: () => (canInsertBlocks), 7697 canLockBlockType: () => (canLockBlockType), 7698 canMoveBlock: () => (canMoveBlock), 7699 canMoveBlocks: () => (canMoveBlocks), 7700 canRemoveBlock: () => (canRemoveBlock), 7701 canRemoveBlocks: () => (canRemoveBlocks), 7702 didAutomaticChange: () => (didAutomaticChange), 7703 getAdjacentBlockClientId: () => (getAdjacentBlockClientId), 7704 getAllowedBlocks: () => (getAllowedBlocks), 7705 getBlock: () => (getBlock), 7706 getBlockAttributes: () => (getBlockAttributes), 7707 getBlockCount: () => (getBlockCount), 7708 getBlockEditingMode: () => (getBlockEditingMode), 7709 getBlockHierarchyRootClientId: () => (getBlockHierarchyRootClientId), 7710 getBlockIndex: () => (getBlockIndex), 7711 getBlockInsertionPoint: () => (getBlockInsertionPoint), 7712 getBlockListSettings: () => (getBlockListSettings), 7713 getBlockMode: () => (getBlockMode), 7714 getBlockName: () => (getBlockName), 7715 getBlockNamesByClientId: () => (getBlockNamesByClientId), 7716 getBlockOrder: () => (getBlockOrder), 7717 getBlockParents: () => (getBlockParents), 7718 getBlockParentsByBlockName: () => (getBlockParentsByBlockName), 7719 getBlockRootClientId: () => (getBlockRootClientId), 7720 getBlockSelectionEnd: () => (getBlockSelectionEnd), 7721 getBlockSelectionStart: () => (getBlockSelectionStart), 7722 getBlockTransformItems: () => (getBlockTransformItems), 7723 getBlocks: () => (getBlocks), 7724 getBlocksByClientId: () => (getBlocksByClientId), 7725 getBlocksByName: () => (getBlocksByName), 7726 getClientIdsOfDescendants: () => (getClientIdsOfDescendants), 7727 getClientIdsWithDescendants: () => (getClientIdsWithDescendants), 7728 getDirectInsertBlock: () => (getDirectInsertBlock), 7729 getDraggedBlockClientIds: () => (getDraggedBlockClientIds), 7730 getFirstMultiSelectedBlockClientId: () => (getFirstMultiSelectedBlockClientId), 7731 getGlobalBlockCount: () => (getGlobalBlockCount), 7732 getHoveredBlockClientId: () => (getHoveredBlockClientId), 7733 getInserterItems: () => (getInserterItems), 7734 getLastMultiSelectedBlockClientId: () => (getLastMultiSelectedBlockClientId), 7735 getLowestCommonAncestorWithSelectedBlock: () => (getLowestCommonAncestorWithSelectedBlock), 7736 getMultiSelectedBlockClientIds: () => (getMultiSelectedBlockClientIds), 7737 getMultiSelectedBlocks: () => (getMultiSelectedBlocks), 7738 getMultiSelectedBlocksEndClientId: () => (getMultiSelectedBlocksEndClientId), 7739 getMultiSelectedBlocksStartClientId: () => (getMultiSelectedBlocksStartClientId), 7740 getNextBlockClientId: () => (getNextBlockClientId), 7741 getPatternsByBlockTypes: () => (getPatternsByBlockTypes), 7742 getPreviousBlockClientId: () => (getPreviousBlockClientId), 7743 getSelectedBlock: () => (getSelectedBlock), 7744 getSelectedBlockClientId: () => (getSelectedBlockClientId), 7745 getSelectedBlockClientIds: () => (getSelectedBlockClientIds), 7746 getSelectedBlockCount: () => (getSelectedBlockCount), 7747 getSelectedBlocksInitialCaretPosition: () => (getSelectedBlocksInitialCaretPosition), 7748 getSelectionEnd: () => (getSelectionEnd), 7749 getSelectionStart: () => (getSelectionStart), 7750 getSettings: () => (getSettings), 7751 getTemplate: () => (getTemplate), 7752 getTemplateLock: () => (getTemplateLock), 7753 hasBlockMovingClientId: () => (hasBlockMovingClientId), 7754 hasDraggedInnerBlock: () => (hasDraggedInnerBlock), 7755 hasInserterItems: () => (hasInserterItems), 7756 hasMultiSelection: () => (hasMultiSelection), 7757 hasSelectedBlock: () => (hasSelectedBlock), 7758 hasSelectedInnerBlock: () => (hasSelectedInnerBlock), 7759 isAncestorBeingDragged: () => (isAncestorBeingDragged), 7760 isAncestorMultiSelected: () => (isAncestorMultiSelected), 7761 isBlockBeingDragged: () => (isBlockBeingDragged), 7762 isBlockHighlighted: () => (isBlockHighlighted), 7763 isBlockInsertionPointVisible: () => (isBlockInsertionPointVisible), 7764 isBlockMultiSelected: () => (isBlockMultiSelected), 7765 isBlockSelected: () => (isBlockSelected), 7766 isBlockValid: () => (isBlockValid), 7767 isBlockVisible: () => (isBlockVisible), 7768 isBlockWithinSelection: () => (isBlockWithinSelection), 7769 isCaretWithinFormattedText: () => (isCaretWithinFormattedText), 7770 isDraggingBlocks: () => (isDraggingBlocks), 7771 isFirstMultiSelectedBlock: () => (isFirstMultiSelectedBlock), 7772 isGroupable: () => (isGroupable), 7773 isLastBlockChangePersistent: () => (isLastBlockChangePersistent), 7774 isMultiSelecting: () => (selectors_isMultiSelecting), 7775 isNavigationMode: () => (isNavigationMode), 7776 isSelectionEnabled: () => (selectors_isSelectionEnabled), 7777 isTyping: () => (selectors_isTyping), 7778 isUngroupable: () => (isUngroupable), 7779 isValidTemplate: () => (isValidTemplate), 7780 wasBlockJustInserted: () => (wasBlockJustInserted) 7781 }); 7782 7783 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/private-actions.js 7784 var private_actions_namespaceObject = {}; 7785 __webpack_require__.r(private_actions_namespaceObject); 7786 __webpack_require__.d(private_actions_namespaceObject, { 7787 __experimentalUpdateSettings: () => (__experimentalUpdateSettings), 7788 clearBlockRemovalPrompt: () => (clearBlockRemovalPrompt), 7789 deleteStyleOverride: () => (deleteStyleOverride), 7790 ensureDefaultBlock: () => (ensureDefaultBlock), 7791 expandBlock: () => (expandBlock), 7792 hideBlockInterface: () => (hideBlockInterface), 7793 modifyContentLockBlock: () => (modifyContentLockBlock), 7794 privateRemoveBlocks: () => (privateRemoveBlocks), 7795 resetZoomLevel: () => (resetZoomLevel), 7796 setBlockRemovalRules: () => (setBlockRemovalRules), 7797 setInsertionPoint: () => (setInsertionPoint), 7798 setLastFocus: () => (setLastFocus), 7799 setOpenedBlockSettingsMenu: () => (setOpenedBlockSettingsMenu), 7800 setStyleOverride: () => (setStyleOverride), 7801 setZoomLevel: () => (setZoomLevel), 7802 showBlockInterface: () => (showBlockInterface), 7803 startDragging: () => (startDragging), 7804 stopDragging: () => (stopDragging), 7805 stopEditingAsBlocks: () => (stopEditingAsBlocks) 7806 }); 7807 7808 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/actions.js 7809 var actions_namespaceObject = {}; 7810 __webpack_require__.r(actions_namespaceObject); 7811 __webpack_require__.d(actions_namespaceObject, { 7812 __unstableDeleteSelection: () => (__unstableDeleteSelection), 7813 __unstableExpandSelection: () => (__unstableExpandSelection), 7814 __unstableMarkAutomaticChange: () => (__unstableMarkAutomaticChange), 7815 __unstableMarkLastChangeAsPersistent: () => (__unstableMarkLastChangeAsPersistent), 7816 __unstableMarkNextChangeAsNotPersistent: () => (__unstableMarkNextChangeAsNotPersistent), 7817 __unstableSaveReusableBlock: () => (__unstableSaveReusableBlock), 7818 __unstableSetEditorMode: () => (__unstableSetEditorMode), 7819 __unstableSetTemporarilyEditingAsBlocks: () => (__unstableSetTemporarilyEditingAsBlocks), 7820 __unstableSplitSelection: () => (__unstableSplitSelection), 7821 clearSelectedBlock: () => (clearSelectedBlock), 7822 duplicateBlocks: () => (duplicateBlocks), 7823 enterFormattedText: () => (enterFormattedText), 7824 exitFormattedText: () => (exitFormattedText), 7825 flashBlock: () => (flashBlock), 7826 hideInsertionPoint: () => (hideInsertionPoint), 7827 hoverBlock: () => (hoverBlock), 7828 insertAfterBlock: () => (insertAfterBlock), 7829 insertBeforeBlock: () => (insertBeforeBlock), 7830 insertBlock: () => (insertBlock), 7831 insertBlocks: () => (insertBlocks), 7832 insertDefaultBlock: () => (insertDefaultBlock), 7833 mergeBlocks: () => (mergeBlocks), 7834 moveBlockToPosition: () => (moveBlockToPosition), 7835 moveBlocksDown: () => (moveBlocksDown), 7836 moveBlocksToPosition: () => (moveBlocksToPosition), 7837 moveBlocksUp: () => (moveBlocksUp), 7838 multiSelect: () => (multiSelect), 7839 receiveBlocks: () => (receiveBlocks), 7840 registerInserterMediaCategory: () => (registerInserterMediaCategory), 7841 removeBlock: () => (removeBlock), 7842 removeBlocks: () => (removeBlocks), 7843 replaceBlock: () => (replaceBlock), 7844 replaceBlocks: () => (replaceBlocks), 7845 replaceInnerBlocks: () => (replaceInnerBlocks), 7846 resetBlocks: () => (resetBlocks), 7847 resetSelection: () => (resetSelection), 7848 selectBlock: () => (selectBlock), 7849 selectNextBlock: () => (selectNextBlock), 7850 selectPreviousBlock: () => (selectPreviousBlock), 7851 selectionChange: () => (selectionChange), 7852 setBlockEditingMode: () => (setBlockEditingMode), 7853 setBlockMovingClientId: () => (setBlockMovingClientId), 7854 setBlockVisibility: () => (setBlockVisibility), 7855 setHasControlledInnerBlocks: () => (setHasControlledInnerBlocks), 7856 setNavigationMode: () => (setNavigationMode), 7857 setTemplateValidity: () => (setTemplateValidity), 7858 showInsertionPoint: () => (showInsertionPoint), 7859 startDraggingBlocks: () => (startDraggingBlocks), 7860 startMultiSelect: () => (startMultiSelect), 7861 startTyping: () => (startTyping), 7862 stopDraggingBlocks: () => (stopDraggingBlocks), 7863 stopMultiSelect: () => (stopMultiSelect), 7864 stopTyping: () => (stopTyping), 7865 synchronizeTemplate: () => (synchronizeTemplate), 7866 toggleBlockHighlight: () => (toggleBlockHighlight), 7867 toggleBlockMode: () => (toggleBlockMode), 7868 toggleSelection: () => (toggleSelection), 7869 unsetBlockEditingMode: () => (unsetBlockEditingMode), 7870 updateBlock: () => (updateBlock), 7871 updateBlockAttributes: () => (updateBlockAttributes), 7872 updateBlockListSettings: () => (updateBlockListSettings), 7873 updateSettings: () => (updateSettings), 7874 validateBlocksToTemplate: () => (validateBlocksToTemplate) 7875 }); 7876 7877 // NAMESPACE OBJECT: ./node_modules/@wordpress/upload-media/build-module/store/selectors.js 7878 var store_selectors_namespaceObject = {}; 7879 __webpack_require__.r(store_selectors_namespaceObject); 7880 __webpack_require__.d(store_selectors_namespaceObject, { 7881 getItems: () => (getItems), 7882 getSettings: () => (selectors_getSettings), 7883 isUploading: () => (isUploading), 7884 isUploadingById: () => (isUploadingById), 7885 isUploadingByUrl: () => (isUploadingByUrl) 7886 }); 7887 7888 // NAMESPACE OBJECT: ./node_modules/@wordpress/upload-media/build-module/store/private-selectors.js 7889 var store_private_selectors_namespaceObject = {}; 7890 __webpack_require__.r(store_private_selectors_namespaceObject); 7891 __webpack_require__.d(store_private_selectors_namespaceObject, { 7892 getAllItems: () => (getAllItems), 7893 getBlobUrls: () => (getBlobUrls), 7894 getItem: () => (getItem), 7895 getPausedUploadForPost: () => (getPausedUploadForPost), 7896 isBatchUploaded: () => (isBatchUploaded), 7897 isPaused: () => (isPaused), 7898 isUploadingToPost: () => (isUploadingToPost) 7899 }); 7900 7901 // NAMESPACE OBJECT: ./node_modules/@wordpress/upload-media/build-module/store/actions.js 7902 var store_actions_namespaceObject = {}; 7903 __webpack_require__.r(store_actions_namespaceObject); 7904 __webpack_require__.d(store_actions_namespaceObject, { 7905 addItems: () => (addItems), 7906 cancelItem: () => (cancelItem) 7907 }); 7908 7909 // NAMESPACE OBJECT: ./node_modules/@wordpress/upload-media/build-module/store/private-actions.js 7910 var store_private_actions_namespaceObject = {}; 7911 __webpack_require__.r(store_private_actions_namespaceObject); 7912 __webpack_require__.d(store_private_actions_namespaceObject, { 7913 addItem: () => (addItem), 7914 finishOperation: () => (finishOperation), 7915 pauseQueue: () => (pauseQueue), 7916 prepareItem: () => (prepareItem), 7917 processItem: () => (processItem), 7918 removeItem: () => (removeItem), 7919 resumeQueue: () => (resumeQueue), 7920 revokeBlobUrls: () => (revokeBlobUrls), 7921 updateSettings: () => (private_actions_updateSettings), 7922 uploadItem: () => (uploadItem) 7923 }); 7924 7925 // NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/index.js 7926 var global_styles_namespaceObject = {}; 7927 __webpack_require__.r(global_styles_namespaceObject); 7928 __webpack_require__.d(global_styles_namespaceObject, { 7929 AdvancedPanel: () => (AdvancedPanel), 7930 BackgroundPanel: () => (background_panel_BackgroundImagePanel), 7931 BorderPanel: () => (BorderPanel), 7932 ColorPanel: () => (ColorPanel), 7933 DimensionsPanel: () => (DimensionsPanel), 7934 FiltersPanel: () => (FiltersPanel), 7935 GlobalStylesContext: () => (GlobalStylesContext), 7936 ImageSettingsPanel: () => (ImageSettingsPanel), 7937 TypographyPanel: () => (TypographyPanel), 7938 areGlobalStyleConfigsEqual: () => (areGlobalStyleConfigsEqual), 7939 getBlockCSSSelector: () => (getBlockCSSSelector), 7940 getBlockSelectors: () => (getBlockSelectors), 7941 getGlobalStylesChanges: () => (getGlobalStylesChanges), 7942 getLayoutStyles: () => (getLayoutStyles), 7943 toStyles: () => (toStyles), 7944 useGlobalSetting: () => (useGlobalSetting), 7945 useGlobalStyle: () => (useGlobalStyle), 7946 useGlobalStylesOutput: () => (useGlobalStylesOutput), 7947 useGlobalStylesOutputWithConfig: () => (useGlobalStylesOutputWithConfig), 7948 useGlobalStylesReset: () => (useGlobalStylesReset), 7949 useHasBackgroundPanel: () => (useHasBackgroundPanel), 7950 useHasBorderPanel: () => (useHasBorderPanel), 7951 useHasBorderPanelControls: () => (useHasBorderPanelControls), 7952 useHasColorPanel: () => (useHasColorPanel), 7953 useHasDimensionsPanel: () => (useHasDimensionsPanel), 7954 useHasFiltersPanel: () => (useHasFiltersPanel), 7955 useHasImageSettingsPanel: () => (useHasImageSettingsPanel), 7956 useHasTypographyPanel: () => (useHasTypographyPanel), 7957 useSettingsForBlockElement: () => (useSettingsForBlockElement) 7958 }); 7959 7960 ;// external ["wp","blocks"] 7961 const external_wp_blocks_namespaceObject = window["wp"]["blocks"]; 7962 ;// external ["wp","element"] 7963 const external_wp_element_namespaceObject = window["wp"]["element"]; 7964 ;// external ["wp","data"] 7965 const external_wp_data_namespaceObject = window["wp"]["data"]; 7966 ;// external ["wp","compose"] 7967 const external_wp_compose_namespaceObject = window["wp"]["compose"]; 7968 ;// external ["wp","hooks"] 7969 const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 7970 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-edit/context.js 7971 /** 7972 * WordPress dependencies 7973 */ 7974 7975 const mayDisplayControlsKey = Symbol('mayDisplayControls'); 7976 const mayDisplayParentControlsKey = Symbol('mayDisplayParentControls'); 7977 const blockEditingModeKey = Symbol('blockEditingMode'); 7978 const blockBindingsKey = Symbol('blockBindings'); 7979 const isPreviewModeKey = Symbol('isPreviewMode'); 7980 const DEFAULT_BLOCK_EDIT_CONTEXT = { 7981 name: '', 7982 isSelected: false 7983 }; 7984 const Context = (0,external_wp_element_namespaceObject.createContext)(DEFAULT_BLOCK_EDIT_CONTEXT); 7985 const { 7986 Provider 7987 } = Context; 7988 7989 7990 /** 7991 * A hook that returns the block edit context. 7992 * 7993 * @return {Object} Block edit context 7994 */ 7995 function useBlockEditContext() { 7996 return (0,external_wp_element_namespaceObject.useContext)(Context); 7997 } 7998 7999 ;// external ["wp","deprecated"] 8000 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 8001 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 8002 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 8003 var es6 = __webpack_require__(7734); 8004 var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 8005 ;// external ["wp","i18n"] 8006 const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 8007 ;// ./node_modules/@wordpress/block-editor/build-module/store/defaults.js 8008 /** 8009 * WordPress dependencies 8010 */ 8011 8012 const PREFERENCES_DEFAULTS = { 8013 insertUsage: {} 8014 }; 8015 8016 /** 8017 * The default editor settings 8018 * 8019 * @typedef {Object} SETTINGS_DEFAULT 8020 * @property {boolean} alignWide Enable/Disable Wide/Full Alignments 8021 * @property {boolean} supportsLayout Enable/disable layouts support in container blocks. 8022 * @property {boolean} imageEditing Image Editing settings set to false to disable. 8023 * @property {Array} imageSizes Available image sizes 8024 * @property {number} maxWidth Max width to constraint resizing 8025 * @property {boolean|Array} allowedBlockTypes Allowed block types 8026 * @property {boolean} hasFixedToolbar Whether or not the editor toolbar is fixed 8027 * @property {boolean} distractionFree Whether or not the editor UI is distraction free 8028 * @property {boolean} focusMode Whether the focus mode is enabled or not 8029 * @property {Array} styles Editor Styles 8030 * @property {boolean} keepCaretInsideBlock Whether caret should move between blocks in edit mode 8031 * @property {string} bodyPlaceholder Empty post placeholder 8032 * @property {string} titlePlaceholder Empty title placeholder 8033 * @property {boolean} canLockBlocks Whether the user can manage Block Lock state 8034 * @property {boolean} codeEditingEnabled Whether or not the user can switch to the code editor 8035 * @property {boolean} generateAnchors Enable/Disable auto anchor generation for Heading blocks 8036 * @property {boolean} enableOpenverseMediaCategory Enable/Disable the Openverse media category in the inserter. 8037 * @property {boolean} clearBlockSelection Whether the block editor should clear selection on mousedown when a block is not clicked. 8038 * @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. 8039 * @property {boolean} __experimentalBlockDirectory Whether the user has enabled the Block Directory 8040 * @property {Array} __experimentalBlockPatterns Array of objects representing the block patterns 8041 * @property {Array} __experimentalBlockPatternCategories Array of objects representing the block pattern categories 8042 */ 8043 const SETTINGS_DEFAULTS = { 8044 alignWide: false, 8045 supportsLayout: true, 8046 // colors setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. 8047 // The setting is only kept for backward compatibility purposes. 8048 colors: [{ 8049 name: (0,external_wp_i18n_namespaceObject.__)('Black'), 8050 slug: 'black', 8051 color: '#000000' 8052 }, { 8053 name: (0,external_wp_i18n_namespaceObject.__)('Cyan bluish gray'), 8054 slug: 'cyan-bluish-gray', 8055 color: '#abb8c3' 8056 }, { 8057 name: (0,external_wp_i18n_namespaceObject.__)('White'), 8058 slug: 'white', 8059 color: '#ffffff' 8060 }, { 8061 name: (0,external_wp_i18n_namespaceObject.__)('Pale pink'), 8062 slug: 'pale-pink', 8063 color: '#f78da7' 8064 }, { 8065 name: (0,external_wp_i18n_namespaceObject.__)('Vivid red'), 8066 slug: 'vivid-red', 8067 color: '#cf2e2e' 8068 }, { 8069 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid orange'), 8070 slug: 'luminous-vivid-orange', 8071 color: '#ff6900' 8072 }, { 8073 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid amber'), 8074 slug: 'luminous-vivid-amber', 8075 color: '#fcb900' 8076 }, { 8077 name: (0,external_wp_i18n_namespaceObject.__)('Light green cyan'), 8078 slug: 'light-green-cyan', 8079 color: '#7bdcb5' 8080 }, { 8081 name: (0,external_wp_i18n_namespaceObject.__)('Vivid green cyan'), 8082 slug: 'vivid-green-cyan', 8083 color: '#00d084' 8084 }, { 8085 name: (0,external_wp_i18n_namespaceObject.__)('Pale cyan blue'), 8086 slug: 'pale-cyan-blue', 8087 color: '#8ed1fc' 8088 }, { 8089 name: (0,external_wp_i18n_namespaceObject.__)('Vivid cyan blue'), 8090 slug: 'vivid-cyan-blue', 8091 color: '#0693e3' 8092 }, { 8093 name: (0,external_wp_i18n_namespaceObject.__)('Vivid purple'), 8094 slug: 'vivid-purple', 8095 color: '#9b51e0' 8096 }], 8097 // fontSizes setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. 8098 // The setting is only kept for backward compatibility purposes. 8099 fontSizes: [{ 8100 name: (0,external_wp_i18n_namespaceObject._x)('Small', 'font size name'), 8101 size: 13, 8102 slug: 'small' 8103 }, { 8104 name: (0,external_wp_i18n_namespaceObject._x)('Normal', 'font size name'), 8105 size: 16, 8106 slug: 'normal' 8107 }, { 8108 name: (0,external_wp_i18n_namespaceObject._x)('Medium', 'font size name'), 8109 size: 20, 8110 slug: 'medium' 8111 }, { 8112 name: (0,external_wp_i18n_namespaceObject._x)('Large', 'font size name'), 8113 size: 36, 8114 slug: 'large' 8115 }, { 8116 name: (0,external_wp_i18n_namespaceObject._x)('Huge', 'font size name'), 8117 size: 42, 8118 slug: 'huge' 8119 }], 8120 // Image default size slug. 8121 imageDefaultSize: 'large', 8122 imageSizes: [{ 8123 slug: 'thumbnail', 8124 name: (0,external_wp_i18n_namespaceObject.__)('Thumbnail') 8125 }, { 8126 slug: 'medium', 8127 name: (0,external_wp_i18n_namespaceObject.__)('Medium') 8128 }, { 8129 slug: 'large', 8130 name: (0,external_wp_i18n_namespaceObject.__)('Large') 8131 }, { 8132 slug: 'full', 8133 name: (0,external_wp_i18n_namespaceObject.__)('Full Size') 8134 }], 8135 // Allow plugin to disable Image Editor if need be. 8136 imageEditing: true, 8137 // This is current max width of the block inner area 8138 // It's used to constraint image resizing and this value could be overridden later by themes 8139 maxWidth: 580, 8140 // Allowed block types for the editor, defaulting to true (all supported). 8141 allowedBlockTypes: true, 8142 // Maximum upload size in bytes allowed for the site. 8143 maxUploadFileSize: 0, 8144 // List of allowed mime types and file extensions. 8145 allowedMimeTypes: null, 8146 // Allows to disable block locking interface. 8147 canLockBlocks: true, 8148 // Allows to disable Openverse media category in the inserter. 8149 enableOpenverseMediaCategory: true, 8150 clearBlockSelection: true, 8151 __experimentalCanUserUseUnfilteredHTML: false, 8152 __experimentalBlockDirectory: false, 8153 __mobileEnablePageTemplates: false, 8154 __experimentalBlockPatterns: [], 8155 __experimentalBlockPatternCategories: [], 8156 isPreviewMode: false, 8157 // These settings will be completely revamped in the future. 8158 // The goal is to evolve this into an API which will instruct 8159 // the block inspector to animate transitions between what it 8160 // displays based on the relationship between the selected block 8161 // and its parent, and only enable it if the parent is controlling 8162 // its children blocks. 8163 blockInspectorAnimation: { 8164 animationParent: 'core/navigation', 8165 'core/navigation': { 8166 enterDirection: 'leftToRight' 8167 }, 8168 'core/navigation-submenu': { 8169 enterDirection: 'rightToLeft' 8170 }, 8171 'core/navigation-link': { 8172 enterDirection: 'rightToLeft' 8173 }, 8174 'core/search': { 8175 enterDirection: 'rightToLeft' 8176 }, 8177 'core/social-links': { 8178 enterDirection: 'rightToLeft' 8179 }, 8180 'core/page-list': { 8181 enterDirection: 'rightToLeft' 8182 }, 8183 'core/spacer': { 8184 enterDirection: 'rightToLeft' 8185 }, 8186 'core/home-link': { 8187 enterDirection: 'rightToLeft' 8188 }, 8189 'core/site-title': { 8190 enterDirection: 'rightToLeft' 8191 }, 8192 'core/site-logo': { 8193 enterDirection: 'rightToLeft' 8194 } 8195 }, 8196 generateAnchors: false, 8197 // gradients setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. 8198 // The setting is only kept for backward compatibility purposes. 8199 gradients: [{ 8200 name: (0,external_wp_i18n_namespaceObject.__)('Vivid cyan blue to vivid purple'), 8201 gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', 8202 slug: 'vivid-cyan-blue-to-vivid-purple' 8203 }, { 8204 name: (0,external_wp_i18n_namespaceObject.__)('Light green cyan to vivid green cyan'), 8205 gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', 8206 slug: 'light-green-cyan-to-vivid-green-cyan' 8207 }, { 8208 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid amber to luminous vivid orange'), 8209 gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', 8210 slug: 'luminous-vivid-amber-to-luminous-vivid-orange' 8211 }, { 8212 name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid orange to vivid red'), 8213 gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', 8214 slug: 'luminous-vivid-orange-to-vivid-red' 8215 }, { 8216 name: (0,external_wp_i18n_namespaceObject.__)('Very light gray to cyan bluish gray'), 8217 gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', 8218 slug: 'very-light-gray-to-cyan-bluish-gray' 8219 }, { 8220 name: (0,external_wp_i18n_namespaceObject.__)('Cool to warm spectrum'), 8221 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%)', 8222 slug: 'cool-to-warm-spectrum' 8223 }, { 8224 name: (0,external_wp_i18n_namespaceObject.__)('Blush light purple'), 8225 gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', 8226 slug: 'blush-light-purple' 8227 }, { 8228 name: (0,external_wp_i18n_namespaceObject.__)('Blush bordeaux'), 8229 gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', 8230 slug: 'blush-bordeaux' 8231 }, { 8232 name: (0,external_wp_i18n_namespaceObject.__)('Luminous dusk'), 8233 gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', 8234 slug: 'luminous-dusk' 8235 }, { 8236 name: (0,external_wp_i18n_namespaceObject.__)('Pale ocean'), 8237 gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', 8238 slug: 'pale-ocean' 8239 }, { 8240 name: (0,external_wp_i18n_namespaceObject.__)('Electric grass'), 8241 gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', 8242 slug: 'electric-grass' 8243 }, { 8244 name: (0,external_wp_i18n_namespaceObject.__)('Midnight'), 8245 gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', 8246 slug: 'midnight' 8247 }], 8248 __unstableResolvedAssets: { 8249 styles: [], 8250 scripts: [] 8251 } 8252 }; 8253 8254 ;// ./node_modules/@wordpress/block-editor/build-module/store/array.js 8255 /** 8256 * Insert one or multiple elements into a given position of an array. 8257 * 8258 * @param {Array} array Source array. 8259 * @param {*} elements Elements to insert. 8260 * @param {number} index Insert Position. 8261 * 8262 * @return {Array} Result. 8263 */ 8264 function insertAt(array, elements, index) { 8265 return [...array.slice(0, index), ...(Array.isArray(elements) ? elements : [elements]), ...array.slice(index)]; 8266 } 8267 8268 /** 8269 * Moves an element in an array. 8270 * 8271 * @param {Array} array Source array. 8272 * @param {number} from Source index. 8273 * @param {number} to Destination index. 8274 * @param {number} count Number of elements to move. 8275 * 8276 * @return {Array} Result. 8277 */ 8278 function moveTo(array, from, to, count = 1) { 8279 const withoutMovedElements = [...array]; 8280 withoutMovedElements.splice(from, count); 8281 return insertAt(withoutMovedElements, array.slice(from, from + count), to); 8282 } 8283 8284 ;// ./node_modules/@wordpress/block-editor/build-module/store/private-keys.js 8285 const globalStylesDataKey = Symbol('globalStylesDataKey'); 8286 const globalStylesLinksDataKey = Symbol('globalStylesLinks'); 8287 const selectBlockPatternsKey = Symbol('selectBlockPatternsKey'); 8288 const reusableBlocksSelectKey = Symbol('reusableBlocksSelect'); 8289 const sectionRootClientIdKey = Symbol('sectionRootClientIdKey'); 8290 8291 ;// external ["wp","privateApis"] 8292 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 8293 ;// ./node_modules/@wordpress/block-editor/build-module/lock-unlock.js 8294 /** 8295 * WordPress dependencies 8296 */ 8297 8298 const { 8299 lock, 8300 unlock 8301 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/block-editor'); 8302 8303 ;// ./node_modules/@wordpress/block-editor/build-module/store/reducer.js 8304 /** 8305 * External dependencies 8306 */ 8307 8308 8309 /** 8310 * WordPress dependencies 8311 */ 8312 8313 8314 8315 8316 8317 /** 8318 * Internal dependencies 8319 */ 8320 8321 8322 8323 8324 const { 8325 isContentBlock 8326 } = unlock(external_wp_blocks_namespaceObject.privateApis); 8327 const identity = x => x; 8328 8329 /** 8330 * Given an array of blocks, returns an object where each key is a nesting 8331 * context, the value of which is an array of block client IDs existing within 8332 * that nesting context. 8333 * 8334 * @param {Array} blocks Blocks to map. 8335 * @param {?string} rootClientId Assumed root client ID. 8336 * 8337 * @return {Object} Block order map object. 8338 */ 8339 function mapBlockOrder(blocks, rootClientId = '') { 8340 const result = new Map(); 8341 const current = []; 8342 result.set(rootClientId, current); 8343 blocks.forEach(block => { 8344 const { 8345 clientId, 8346 innerBlocks 8347 } = block; 8348 current.push(clientId); 8349 mapBlockOrder(innerBlocks, clientId).forEach((order, subClientId) => { 8350 result.set(subClientId, order); 8351 }); 8352 }); 8353 return result; 8354 } 8355 8356 /** 8357 * Given an array of blocks, returns an object where each key contains 8358 * the clientId of the block and the value is the parent of the block. 8359 * 8360 * @param {Array} blocks Blocks to map. 8361 * @param {?string} rootClientId Assumed root client ID. 8362 * 8363 * @return {Object} Block order map object. 8364 */ 8365 function mapBlockParents(blocks, rootClientId = '') { 8366 const result = []; 8367 const stack = [[rootClientId, blocks]]; 8368 while (stack.length) { 8369 const [parent, currentBlocks] = stack.shift(); 8370 currentBlocks.forEach(({ 8371 innerBlocks, 8372 ...block 8373 }) => { 8374 result.push([block.clientId, parent]); 8375 if (innerBlocks?.length) { 8376 stack.push([block.clientId, innerBlocks]); 8377 } 8378 }); 8379 } 8380 return result; 8381 } 8382 8383 /** 8384 * Helper method to iterate through all blocks, recursing into inner blocks, 8385 * applying a transformation function to each one. 8386 * Returns a flattened object with the transformed blocks. 8387 * 8388 * @param {Array} blocks Blocks to flatten. 8389 * @param {Function} transform Transforming function to be applied to each block. 8390 * 8391 * @return {Array} Flattened object. 8392 */ 8393 function flattenBlocks(blocks, transform = identity) { 8394 const result = []; 8395 const stack = [...blocks]; 8396 while (stack.length) { 8397 const { 8398 innerBlocks, 8399 ...block 8400 } = stack.shift(); 8401 stack.push(...innerBlocks); 8402 result.push([block.clientId, transform(block)]); 8403 } 8404 return result; 8405 } 8406 function getFlattenedClientIds(blocks) { 8407 const result = {}; 8408 const stack = [...blocks]; 8409 while (stack.length) { 8410 const { 8411 innerBlocks, 8412 ...block 8413 } = stack.shift(); 8414 stack.push(...innerBlocks); 8415 result[block.clientId] = true; 8416 } 8417 return result; 8418 } 8419 8420 /** 8421 * Given an array of blocks, returns an object containing all blocks, without 8422 * attributes, recursing into inner blocks. Keys correspond to the block client 8423 * ID, the value of which is the attributes object. 8424 * 8425 * @param {Array} blocks Blocks to flatten. 8426 * 8427 * @return {Array} Flattened block attributes object. 8428 */ 8429 function getFlattenedBlocksWithoutAttributes(blocks) { 8430 return flattenBlocks(blocks, block => { 8431 const { 8432 attributes, 8433 ...restBlock 8434 } = block; 8435 return restBlock; 8436 }); 8437 } 8438 8439 /** 8440 * Given an array of blocks, returns an object containing all block attributes, 8441 * recursing into inner blocks. Keys correspond to the block client ID, the 8442 * value of which is the attributes object. 8443 * 8444 * @param {Array} blocks Blocks to flatten. 8445 * 8446 * @return {Array} Flattened block attributes object. 8447 */ 8448 function getFlattenedBlockAttributes(blocks) { 8449 return flattenBlocks(blocks, block => block.attributes); 8450 } 8451 8452 /** 8453 * Returns true if the two object arguments have the same keys, or false 8454 * otherwise. 8455 * 8456 * @param {Object} a First object. 8457 * @param {Object} b Second object. 8458 * 8459 * @return {boolean} Whether the two objects have the same keys. 8460 */ 8461 function hasSameKeys(a, b) { 8462 return es6_default()(Object.keys(a), Object.keys(b)); 8463 } 8464 8465 /** 8466 * Returns true if, given the currently dispatching action and the previously 8467 * dispatched action, the two actions are updating the same block attribute, or 8468 * false otherwise. 8469 * 8470 * @param {Object} action Currently dispatching action. 8471 * @param {Object} lastAction Previously dispatched action. 8472 * 8473 * @return {boolean} Whether actions are updating the same block attribute. 8474 */ 8475 function isUpdatingSameBlockAttribute(action, lastAction) { 8476 return action.type === 'UPDATE_BLOCK_ATTRIBUTES' && lastAction !== undefined && lastAction.type === 'UPDATE_BLOCK_ATTRIBUTES' && es6_default()(action.clientIds, lastAction.clientIds) && hasSameKeys(action.attributes, lastAction.attributes); 8477 } 8478 function updateBlockTreeForBlocks(state, blocks) { 8479 const treeToUpdate = state.tree; 8480 const stack = [...blocks]; 8481 const flattenedBlocks = [...blocks]; 8482 while (stack.length) { 8483 const block = stack.shift(); 8484 stack.push(...block.innerBlocks); 8485 flattenedBlocks.push(...block.innerBlocks); 8486 } 8487 // Create objects before mutating them, that way it's always defined. 8488 for (const block of flattenedBlocks) { 8489 treeToUpdate.set(block.clientId, {}); 8490 } 8491 for (const block of flattenedBlocks) { 8492 treeToUpdate.set(block.clientId, Object.assign(treeToUpdate.get(block.clientId), { 8493 ...state.byClientId.get(block.clientId), 8494 attributes: state.attributes.get(block.clientId), 8495 innerBlocks: block.innerBlocks.map(subBlock => treeToUpdate.get(subBlock.clientId)) 8496 })); 8497 } 8498 } 8499 function updateParentInnerBlocksInTree(state, updatedClientIds, updateChildrenOfUpdatedClientIds = false) { 8500 const treeToUpdate = state.tree; 8501 const uncontrolledParents = new Set([]); 8502 const controlledParents = new Set(); 8503 for (const clientId of updatedClientIds) { 8504 let current = updateChildrenOfUpdatedClientIds ? clientId : state.parents.get(clientId); 8505 do { 8506 if (state.controlledInnerBlocks[current]) { 8507 // Should stop on controlled blocks. 8508 // If we reach a controlled parent, break out of the loop. 8509 controlledParents.add(current); 8510 break; 8511 } else { 8512 // Else continue traversing up through parents. 8513 uncontrolledParents.add(current); 8514 current = state.parents.get(current); 8515 } 8516 } while (current !== undefined); 8517 } 8518 8519 // To make sure the order of assignments doesn't matter, 8520 // we first create empty objects and mutates the inner blocks later. 8521 for (const clientId of uncontrolledParents) { 8522 treeToUpdate.set(clientId, { 8523 ...treeToUpdate.get(clientId) 8524 }); 8525 } 8526 for (const clientId of uncontrolledParents) { 8527 treeToUpdate.get(clientId).innerBlocks = (state.order.get(clientId) || []).map(subClientId => treeToUpdate.get(subClientId)); 8528 } 8529 8530 // Controlled parent blocks, need a dedicated key for their inner blocks 8531 // to be used when doing getBlocks( controlledBlockClientId ). 8532 for (const clientId of controlledParents) { 8533 treeToUpdate.set('controlled||' + clientId, { 8534 innerBlocks: (state.order.get(clientId) || []).map(subClientId => treeToUpdate.get(subClientId)) 8535 }); 8536 } 8537 } 8538 8539 /** 8540 * Higher-order reducer intended to compute full block objects key for each block in the post. 8541 * This is a denormalization to optimize the performance of the getBlock selectors and avoid 8542 * recomputing the block objects and avoid heavy memoization. 8543 * 8544 * @param {Function} reducer Original reducer function. 8545 * 8546 * @return {Function} Enhanced reducer function. 8547 */ 8548 const withBlockTree = reducer => (state = {}, action) => { 8549 const newState = reducer(state, action); 8550 if (newState === state) { 8551 return state; 8552 } 8553 newState.tree = state.tree ? state.tree : new Map(); 8554 switch (action.type) { 8555 case 'RECEIVE_BLOCKS': 8556 case 'INSERT_BLOCKS': 8557 { 8558 newState.tree = new Map(newState.tree); 8559 updateBlockTreeForBlocks(newState, action.blocks); 8560 updateParentInnerBlocksInTree(newState, action.rootClientId ? [action.rootClientId] : [''], true); 8561 break; 8562 } 8563 case 'UPDATE_BLOCK': 8564 newState.tree = new Map(newState.tree); 8565 newState.tree.set(action.clientId, { 8566 ...newState.tree.get(action.clientId), 8567 ...newState.byClientId.get(action.clientId), 8568 attributes: newState.attributes.get(action.clientId) 8569 }); 8570 updateParentInnerBlocksInTree(newState, [action.clientId], false); 8571 break; 8572 case 'SYNC_DERIVED_BLOCK_ATTRIBUTES': 8573 case 'UPDATE_BLOCK_ATTRIBUTES': 8574 { 8575 newState.tree = new Map(newState.tree); 8576 action.clientIds.forEach(clientId => { 8577 newState.tree.set(clientId, { 8578 ...newState.tree.get(clientId), 8579 attributes: newState.attributes.get(clientId) 8580 }); 8581 }); 8582 updateParentInnerBlocksInTree(newState, action.clientIds, false); 8583 break; 8584 } 8585 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 8586 { 8587 const inserterClientIds = getFlattenedClientIds(action.blocks); 8588 newState.tree = new Map(newState.tree); 8589 action.replacedClientIds.forEach(clientId => { 8590 newState.tree.delete(clientId); 8591 // Controlled inner blocks are only removed 8592 // if the block doesn't move to another position 8593 // otherwise their content will be lost. 8594 if (!inserterClientIds[clientId]) { 8595 newState.tree.delete('controlled||' + clientId); 8596 } 8597 }); 8598 updateBlockTreeForBlocks(newState, action.blocks); 8599 updateParentInnerBlocksInTree(newState, action.blocks.map(b => b.clientId), false); 8600 8601 // If there are no replaced blocks, it means we're removing blocks so we need to update their parent. 8602 const parentsOfRemovedBlocks = []; 8603 for (const clientId of action.clientIds) { 8604 const parentId = state.parents.get(clientId); 8605 if (parentId !== undefined && (parentId === '' || newState.byClientId.get(parentId))) { 8606 parentsOfRemovedBlocks.push(parentId); 8607 } 8608 } 8609 updateParentInnerBlocksInTree(newState, parentsOfRemovedBlocks, true); 8610 break; 8611 } 8612 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 8613 const parentsOfRemovedBlocks = []; 8614 for (const clientId of action.clientIds) { 8615 const parentId = state.parents.get(clientId); 8616 if (parentId !== undefined && (parentId === '' || newState.byClientId.get(parentId))) { 8617 parentsOfRemovedBlocks.push(parentId); 8618 } 8619 } 8620 newState.tree = new Map(newState.tree); 8621 action.removedClientIds.forEach(clientId => { 8622 newState.tree.delete(clientId); 8623 newState.tree.delete('controlled||' + clientId); 8624 }); 8625 updateParentInnerBlocksInTree(newState, parentsOfRemovedBlocks, true); 8626 break; 8627 case 'MOVE_BLOCKS_TO_POSITION': 8628 { 8629 const updatedBlockUids = []; 8630 if (action.fromRootClientId) { 8631 updatedBlockUids.push(action.fromRootClientId); 8632 } else { 8633 updatedBlockUids.push(''); 8634 } 8635 if (action.toRootClientId) { 8636 updatedBlockUids.push(action.toRootClientId); 8637 } 8638 newState.tree = new Map(newState.tree); 8639 updateParentInnerBlocksInTree(newState, updatedBlockUids, true); 8640 break; 8641 } 8642 case 'MOVE_BLOCKS_UP': 8643 case 'MOVE_BLOCKS_DOWN': 8644 { 8645 const updatedBlockUids = [action.rootClientId ? action.rootClientId : '']; 8646 newState.tree = new Map(newState.tree); 8647 updateParentInnerBlocksInTree(newState, updatedBlockUids, true); 8648 break; 8649 } 8650 case 'SAVE_REUSABLE_BLOCK_SUCCESS': 8651 { 8652 const updatedBlockUids = []; 8653 newState.attributes.forEach((attributes, clientId) => { 8654 if (newState.byClientId.get(clientId).name === 'core/block' && attributes.ref === action.updatedId) { 8655 updatedBlockUids.push(clientId); 8656 } 8657 }); 8658 newState.tree = new Map(newState.tree); 8659 updatedBlockUids.forEach(clientId => { 8660 newState.tree.set(clientId, { 8661 ...newState.byClientId.get(clientId), 8662 attributes: newState.attributes.get(clientId), 8663 innerBlocks: newState.tree.get(clientId).innerBlocks 8664 }); 8665 }); 8666 updateParentInnerBlocksInTree(newState, updatedBlockUids, false); 8667 } 8668 } 8669 return newState; 8670 }; 8671 8672 /** 8673 * Higher-order reducer intended to augment the blocks reducer, assigning an 8674 * `isPersistentChange` property value corresponding to whether a change in 8675 * state can be considered as persistent. All changes are considered persistent 8676 * except when updating the same block attribute as in the previous action. 8677 * 8678 * @param {Function} reducer Original reducer function. 8679 * 8680 * @return {Function} Enhanced reducer function. 8681 */ 8682 function withPersistentBlockChange(reducer) { 8683 let lastAction; 8684 let markNextChangeAsNotPersistent = false; 8685 let explicitPersistent; 8686 return (state, action) => { 8687 let nextState = reducer(state, action); 8688 let nextIsPersistentChange; 8689 if (action.type === 'SET_EXPLICIT_PERSISTENT') { 8690 var _state$isPersistentCh; 8691 explicitPersistent = action.isPersistentChange; 8692 nextIsPersistentChange = (_state$isPersistentCh = state.isPersistentChange) !== null && _state$isPersistentCh !== void 0 ? _state$isPersistentCh : true; 8693 } 8694 if (explicitPersistent !== undefined) { 8695 nextIsPersistentChange = explicitPersistent; 8696 return nextIsPersistentChange === nextState.isPersistentChange ? nextState : { 8697 ...nextState, 8698 isPersistentChange: nextIsPersistentChange 8699 }; 8700 } 8701 const isExplicitPersistentChange = action.type === 'MARK_LAST_CHANGE_AS_PERSISTENT' || markNextChangeAsNotPersistent; 8702 8703 // Defer to previous state value (or default) unless changing or 8704 // explicitly marking as persistent. 8705 if (state === nextState && !isExplicitPersistentChange) { 8706 var _state$isPersistentCh2; 8707 markNextChangeAsNotPersistent = action.type === 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT'; 8708 nextIsPersistentChange = (_state$isPersistentCh2 = state?.isPersistentChange) !== null && _state$isPersistentCh2 !== void 0 ? _state$isPersistentCh2 : true; 8709 if (state.isPersistentChange === nextIsPersistentChange) { 8710 return state; 8711 } 8712 return { 8713 ...nextState, 8714 isPersistentChange: nextIsPersistentChange 8715 }; 8716 } 8717 nextState = { 8718 ...nextState, 8719 isPersistentChange: isExplicitPersistentChange ? !markNextChangeAsNotPersistent : !isUpdatingSameBlockAttribute(action, lastAction) 8720 }; 8721 8722 // In comparing against the previous action, consider only those which 8723 // would have qualified as one which would have been ignored or not 8724 // have resulted in a changed state. 8725 lastAction = action; 8726 markNextChangeAsNotPersistent = action.type === 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT'; 8727 return nextState; 8728 }; 8729 } 8730 8731 /** 8732 * Higher-order reducer intended to augment the blocks reducer, assigning an 8733 * `isIgnoredChange` property value corresponding to whether a change in state 8734 * can be considered as ignored. A change is considered ignored when the result 8735 * of an action not incurred by direct user interaction. 8736 * 8737 * @param {Function} reducer Original reducer function. 8738 * 8739 * @return {Function} Enhanced reducer function. 8740 */ 8741 function withIgnoredBlockChange(reducer) { 8742 /** 8743 * Set of action types for which a blocks state change should be ignored. 8744 * 8745 * @type {Set} 8746 */ 8747 const IGNORED_ACTION_TYPES = new Set(['RECEIVE_BLOCKS']); 8748 return (state, action) => { 8749 const nextState = reducer(state, action); 8750 if (nextState !== state) { 8751 nextState.isIgnoredChange = IGNORED_ACTION_TYPES.has(action.type); 8752 } 8753 return nextState; 8754 }; 8755 } 8756 8757 /** 8758 * Higher-order reducer targeting the combined blocks reducer, augmenting 8759 * block client IDs in remove action to include cascade of inner blocks. 8760 * 8761 * @param {Function} reducer Original reducer function. 8762 * 8763 * @return {Function} Enhanced reducer function. 8764 */ 8765 const withInnerBlocksRemoveCascade = reducer => (state, action) => { 8766 // Gets all children which need to be removed. 8767 const getAllChildren = clientIds => { 8768 let result = clientIds; 8769 for (let i = 0; i < result.length; i++) { 8770 if (!state.order.get(result[i]) || action.keepControlledInnerBlocks && action.keepControlledInnerBlocks[result[i]]) { 8771 continue; 8772 } 8773 if (result === clientIds) { 8774 result = [...result]; 8775 } 8776 result.push(...state.order.get(result[i])); 8777 } 8778 return result; 8779 }; 8780 if (state) { 8781 switch (action.type) { 8782 case 'REMOVE_BLOCKS': 8783 action = { 8784 ...action, 8785 type: 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN', 8786 removedClientIds: getAllChildren(action.clientIds) 8787 }; 8788 break; 8789 case 'REPLACE_BLOCKS': 8790 action = { 8791 ...action, 8792 type: 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN', 8793 replacedClientIds: getAllChildren(action.clientIds) 8794 }; 8795 break; 8796 } 8797 } 8798 return reducer(state, action); 8799 }; 8800 8801 /** 8802 * Higher-order reducer which targets the combined blocks reducer and handles 8803 * the `RESET_BLOCKS` action. When dispatched, this action will replace all 8804 * blocks that exist in the post, leaving blocks that exist only in state (e.g. 8805 * reusable blocks and blocks controlled by inner blocks controllers) alone. 8806 * 8807 * @param {Function} reducer Original reducer function. 8808 * 8809 * @return {Function} Enhanced reducer function. 8810 */ 8811 const withBlockReset = reducer => (state, action) => { 8812 if (action.type === 'RESET_BLOCKS') { 8813 const newState = { 8814 ...state, 8815 byClientId: new Map(getFlattenedBlocksWithoutAttributes(action.blocks)), 8816 attributes: new Map(getFlattenedBlockAttributes(action.blocks)), 8817 order: mapBlockOrder(action.blocks), 8818 parents: new Map(mapBlockParents(action.blocks)), 8819 controlledInnerBlocks: {} 8820 }; 8821 newState.tree = new Map(state?.tree); 8822 updateBlockTreeForBlocks(newState, action.blocks); 8823 newState.tree.set('', { 8824 innerBlocks: action.blocks.map(subBlock => newState.tree.get(subBlock.clientId)) 8825 }); 8826 return newState; 8827 } 8828 return reducer(state, action); 8829 }; 8830 8831 /** 8832 * Higher-order reducer which targets the combined blocks reducer and handles 8833 * the `REPLACE_INNER_BLOCKS` action. When dispatched, this action the state 8834 * should become equivalent to the execution of a `REMOVE_BLOCKS` action 8835 * containing all the child's of the root block followed by the execution of 8836 * `INSERT_BLOCKS` with the new blocks. 8837 * 8838 * @param {Function} reducer Original reducer function. 8839 * 8840 * @return {Function} Enhanced reducer function. 8841 */ 8842 const withReplaceInnerBlocks = reducer => (state, action) => { 8843 if (action.type !== 'REPLACE_INNER_BLOCKS') { 8844 return reducer(state, action); 8845 } 8846 8847 // Finds every nested inner block controller. We must check the action blocks 8848 // and not just the block parent state because some inner block controllers 8849 // should be deleted if specified, whereas others should not be deleted. If 8850 // a controlled should not be deleted, then we need to avoid deleting its 8851 // inner blocks from the block state because its inner blocks will not be 8852 // attached to the block in the action. 8853 const nestedControllers = {}; 8854 if (Object.keys(state.controlledInnerBlocks).length) { 8855 const stack = [...action.blocks]; 8856 while (stack.length) { 8857 const { 8858 innerBlocks, 8859 ...block 8860 } = stack.shift(); 8861 stack.push(...innerBlocks); 8862 if (!!state.controlledInnerBlocks[block.clientId]) { 8863 nestedControllers[block.clientId] = true; 8864 } 8865 } 8866 } 8867 8868 // The `keepControlledInnerBlocks` prop will keep the inner blocks of the 8869 // marked block in the block state so that they can be reattached to the 8870 // marked block when we re-insert everything a few lines below. 8871 let stateAfterBlocksRemoval = state; 8872 if (state.order.get(action.rootClientId)) { 8873 stateAfterBlocksRemoval = reducer(stateAfterBlocksRemoval, { 8874 type: 'REMOVE_BLOCKS', 8875 keepControlledInnerBlocks: nestedControllers, 8876 clientIds: state.order.get(action.rootClientId) 8877 }); 8878 } 8879 let stateAfterInsert = stateAfterBlocksRemoval; 8880 if (action.blocks.length) { 8881 stateAfterInsert = reducer(stateAfterInsert, { 8882 ...action, 8883 type: 'INSERT_BLOCKS', 8884 index: 0 8885 }); 8886 8887 // We need to re-attach the controlled inner blocks to the blocks tree and 8888 // preserve their block order. Otherwise, an inner block controller's blocks 8889 // will be deleted entirely from its entity. 8890 const stateAfterInsertOrder = new Map(stateAfterInsert.order); 8891 Object.keys(nestedControllers).forEach(key => { 8892 if (state.order.get(key)) { 8893 stateAfterInsertOrder.set(key, state.order.get(key)); 8894 } 8895 }); 8896 stateAfterInsert.order = stateAfterInsertOrder; 8897 stateAfterInsert.tree = new Map(stateAfterInsert.tree); 8898 Object.keys(nestedControllers).forEach(_key => { 8899 const key = `controlled||$_key}`; 8900 if (state.tree.has(key)) { 8901 stateAfterInsert.tree.set(key, state.tree.get(key)); 8902 } 8903 }); 8904 } 8905 return stateAfterInsert; 8906 }; 8907 8908 /** 8909 * Higher-order reducer which targets the combined blocks reducer and handles 8910 * the `SAVE_REUSABLE_BLOCK_SUCCESS` action. This action can't be handled by 8911 * regular reducers and needs a higher-order reducer since it needs access to 8912 * both `byClientId` and `attributes` simultaneously. 8913 * 8914 * @param {Function} reducer Original reducer function. 8915 * 8916 * @return {Function} Enhanced reducer function. 8917 */ 8918 const withSaveReusableBlock = reducer => (state, action) => { 8919 if (state && action.type === 'SAVE_REUSABLE_BLOCK_SUCCESS') { 8920 const { 8921 id, 8922 updatedId 8923 } = action; 8924 8925 // If a temporary reusable block is saved, we swap the temporary id with the final one. 8926 if (id === updatedId) { 8927 return state; 8928 } 8929 state = { 8930 ...state 8931 }; 8932 state.attributes = new Map(state.attributes); 8933 state.attributes.forEach((attributes, clientId) => { 8934 const { 8935 name 8936 } = state.byClientId.get(clientId); 8937 if (name === 'core/block' && attributes.ref === id) { 8938 state.attributes.set(clientId, { 8939 ...attributes, 8940 ref: updatedId 8941 }); 8942 } 8943 }); 8944 } 8945 return reducer(state, action); 8946 }; 8947 /** 8948 * Higher-order reducer which removes blocks from state when switching parent block controlled state. 8949 * 8950 * @param {Function} reducer Original reducer function. 8951 * 8952 * @return {Function} Enhanced reducer function. 8953 */ 8954 const withResetControlledBlocks = reducer => (state, action) => { 8955 if (action.type === 'SET_HAS_CONTROLLED_INNER_BLOCKS') { 8956 // when switching a block from controlled to uncontrolled or inverse, 8957 // we need to remove its content first. 8958 const tempState = reducer(state, { 8959 type: 'REPLACE_INNER_BLOCKS', 8960 rootClientId: action.clientId, 8961 blocks: [] 8962 }); 8963 return reducer(tempState, action); 8964 } 8965 return reducer(state, action); 8966 }; 8967 8968 /** 8969 * Reducer returning the blocks state. 8970 * 8971 * @param {Object} state Current state. 8972 * @param {Object} action Dispatched action. 8973 * 8974 * @return {Object} Updated state. 8975 */ 8976 const blocks = (0,external_wp_compose_namespaceObject.pipe)(external_wp_data_namespaceObject.combineReducers, withSaveReusableBlock, 8977 // Needs to be before withBlockCache. 8978 withBlockTree, 8979 // Needs to be before withInnerBlocksRemoveCascade. 8980 withInnerBlocksRemoveCascade, withReplaceInnerBlocks, 8981 // Needs to be after withInnerBlocksRemoveCascade. 8982 withBlockReset, withPersistentBlockChange, withIgnoredBlockChange, withResetControlledBlocks)({ 8983 // The state is using a Map instead of a plain object for performance reasons. 8984 // You can run the "./test/performance.js" unit test to check the impact 8985 // code changes can have on this reducer. 8986 byClientId(state = new Map(), action) { 8987 switch (action.type) { 8988 case 'RECEIVE_BLOCKS': 8989 case 'INSERT_BLOCKS': 8990 { 8991 const newState = new Map(state); 8992 getFlattenedBlocksWithoutAttributes(action.blocks).forEach(([key, value]) => { 8993 newState.set(key, value); 8994 }); 8995 return newState; 8996 } 8997 case 'UPDATE_BLOCK': 8998 { 8999 // Ignore updates if block isn't known. 9000 if (!state.has(action.clientId)) { 9001 return state; 9002 } 9003 9004 // Do nothing if only attributes change. 9005 const { 9006 attributes, 9007 ...changes 9008 } = action.updates; 9009 if (Object.values(changes).length === 0) { 9010 return state; 9011 } 9012 const newState = new Map(state); 9013 newState.set(action.clientId, { 9014 ...state.get(action.clientId), 9015 ...changes 9016 }); 9017 return newState; 9018 } 9019 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9020 { 9021 if (!action.blocks) { 9022 return state; 9023 } 9024 const newState = new Map(state); 9025 action.replacedClientIds.forEach(clientId => { 9026 newState.delete(clientId); 9027 }); 9028 getFlattenedBlocksWithoutAttributes(action.blocks).forEach(([key, value]) => { 9029 newState.set(key, value); 9030 }); 9031 return newState; 9032 } 9033 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9034 { 9035 const newState = new Map(state); 9036 action.removedClientIds.forEach(clientId => { 9037 newState.delete(clientId); 9038 }); 9039 return newState; 9040 } 9041 } 9042 return state; 9043 }, 9044 // The state is using a Map instead of a plain object for performance reasons. 9045 // You can run the "./test/performance.js" unit test to check the impact 9046 // code changes can have on this reducer. 9047 attributes(state = new Map(), action) { 9048 switch (action.type) { 9049 case 'RECEIVE_BLOCKS': 9050 case 'INSERT_BLOCKS': 9051 { 9052 const newState = new Map(state); 9053 getFlattenedBlockAttributes(action.blocks).forEach(([key, value]) => { 9054 newState.set(key, value); 9055 }); 9056 return newState; 9057 } 9058 case 'UPDATE_BLOCK': 9059 { 9060 // Ignore updates if block isn't known or there are no attribute changes. 9061 if (!state.get(action.clientId) || !action.updates.attributes) { 9062 return state; 9063 } 9064 const newState = new Map(state); 9065 newState.set(action.clientId, { 9066 ...state.get(action.clientId), 9067 ...action.updates.attributes 9068 }); 9069 return newState; 9070 } 9071 case 'SYNC_DERIVED_BLOCK_ATTRIBUTES': 9072 case 'UPDATE_BLOCK_ATTRIBUTES': 9073 { 9074 // Avoid a state change if none of the block IDs are known. 9075 if (action.clientIds.every(id => !state.get(id))) { 9076 return state; 9077 } 9078 let hasChange = false; 9079 const newState = new Map(state); 9080 for (const clientId of action.clientIds) { 9081 var _action$attributes; 9082 const updatedAttributeEntries = Object.entries(action.uniqueByBlock ? action.attributes[clientId] : (_action$attributes = action.attributes) !== null && _action$attributes !== void 0 ? _action$attributes : {}); 9083 if (updatedAttributeEntries.length === 0) { 9084 continue; 9085 } 9086 let hasUpdatedAttributes = false; 9087 const existingAttributes = state.get(clientId); 9088 const newAttributes = {}; 9089 updatedAttributeEntries.forEach(([key, value]) => { 9090 if (existingAttributes[key] !== value) { 9091 hasUpdatedAttributes = true; 9092 newAttributes[key] = value; 9093 } 9094 }); 9095 hasChange = hasChange || hasUpdatedAttributes; 9096 if (hasUpdatedAttributes) { 9097 newState.set(clientId, { 9098 ...existingAttributes, 9099 ...newAttributes 9100 }); 9101 } 9102 } 9103 return hasChange ? newState : state; 9104 } 9105 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9106 { 9107 if (!action.blocks) { 9108 return state; 9109 } 9110 const newState = new Map(state); 9111 action.replacedClientIds.forEach(clientId => { 9112 newState.delete(clientId); 9113 }); 9114 getFlattenedBlockAttributes(action.blocks).forEach(([key, value]) => { 9115 newState.set(key, value); 9116 }); 9117 return newState; 9118 } 9119 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9120 { 9121 const newState = new Map(state); 9122 action.removedClientIds.forEach(clientId => { 9123 newState.delete(clientId); 9124 }); 9125 return newState; 9126 } 9127 } 9128 return state; 9129 }, 9130 // The state is using a Map instead of a plain object for performance reasons. 9131 // You can run the "./test/performance.js" unit test to check the impact 9132 // code changes can have on this reducer. 9133 order(state = new Map(), action) { 9134 switch (action.type) { 9135 case 'RECEIVE_BLOCKS': 9136 { 9137 var _state$get; 9138 const blockOrder = mapBlockOrder(action.blocks); 9139 const newState = new Map(state); 9140 blockOrder.forEach((order, clientId) => { 9141 if (clientId !== '') { 9142 newState.set(clientId, order); 9143 } 9144 }); 9145 newState.set('', ((_state$get = state.get('')) !== null && _state$get !== void 0 ? _state$get : []).concat(blockOrder[''])); 9146 return newState; 9147 } 9148 case 'INSERT_BLOCKS': 9149 { 9150 const { 9151 rootClientId = '' 9152 } = action; 9153 const subState = state.get(rootClientId) || []; 9154 const mappedBlocks = mapBlockOrder(action.blocks, rootClientId); 9155 const { 9156 index = subState.length 9157 } = action; 9158 const newState = new Map(state); 9159 mappedBlocks.forEach((order, clientId) => { 9160 newState.set(clientId, order); 9161 }); 9162 newState.set(rootClientId, insertAt(subState, mappedBlocks.get(rootClientId), index)); 9163 return newState; 9164 } 9165 case 'MOVE_BLOCKS_TO_POSITION': 9166 { 9167 var _state$get$filter; 9168 const { 9169 fromRootClientId = '', 9170 toRootClientId = '', 9171 clientIds 9172 } = action; 9173 const { 9174 index = state.get(toRootClientId).length 9175 } = action; 9176 9177 // Moving inside the same parent block. 9178 if (fromRootClientId === toRootClientId) { 9179 const subState = state.get(toRootClientId); 9180 const fromIndex = subState.indexOf(clientIds[0]); 9181 const newState = new Map(state); 9182 newState.set(toRootClientId, moveTo(state.get(toRootClientId), fromIndex, index, clientIds.length)); 9183 return newState; 9184 } 9185 9186 // Moving from a parent block to another. 9187 const newState = new Map(state); 9188 newState.set(fromRootClientId, (_state$get$filter = state.get(fromRootClientId)?.filter(id => !clientIds.includes(id))) !== null && _state$get$filter !== void 0 ? _state$get$filter : []); 9189 newState.set(toRootClientId, insertAt(state.get(toRootClientId), clientIds, index)); 9190 return newState; 9191 } 9192 case 'MOVE_BLOCKS_UP': 9193 { 9194 const { 9195 clientIds, 9196 rootClientId = '' 9197 } = action; 9198 const firstClientId = clientIds[0]; 9199 const subState = state.get(rootClientId); 9200 if (!subState.length || firstClientId === subState[0]) { 9201 return state; 9202 } 9203 const firstIndex = subState.indexOf(firstClientId); 9204 const newState = new Map(state); 9205 newState.set(rootClientId, moveTo(subState, firstIndex, firstIndex - 1, clientIds.length)); 9206 return newState; 9207 } 9208 case 'MOVE_BLOCKS_DOWN': 9209 { 9210 const { 9211 clientIds, 9212 rootClientId = '' 9213 } = action; 9214 const firstClientId = clientIds[0]; 9215 const lastClientId = clientIds[clientIds.length - 1]; 9216 const subState = state.get(rootClientId); 9217 if (!subState.length || lastClientId === subState[subState.length - 1]) { 9218 return state; 9219 } 9220 const firstIndex = subState.indexOf(firstClientId); 9221 const newState = new Map(state); 9222 newState.set(rootClientId, moveTo(subState, firstIndex, firstIndex + 1, clientIds.length)); 9223 return newState; 9224 } 9225 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9226 { 9227 const { 9228 clientIds 9229 } = action; 9230 if (!action.blocks) { 9231 return state; 9232 } 9233 const mappedBlocks = mapBlockOrder(action.blocks); 9234 const newState = new Map(state); 9235 action.replacedClientIds.forEach(clientId => { 9236 newState.delete(clientId); 9237 }); 9238 mappedBlocks.forEach((order, clientId) => { 9239 if (clientId !== '') { 9240 newState.set(clientId, order); 9241 } 9242 }); 9243 newState.forEach((order, clientId) => { 9244 const newSubOrder = Object.values(order).reduce((result, subClientId) => { 9245 if (subClientId === clientIds[0]) { 9246 return [...result, ...mappedBlocks.get('')]; 9247 } 9248 if (clientIds.indexOf(subClientId) === -1) { 9249 result.push(subClientId); 9250 } 9251 return result; 9252 }, []); 9253 newState.set(clientId, newSubOrder); 9254 }); 9255 return newState; 9256 } 9257 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9258 { 9259 const newState = new Map(state); 9260 // Remove inner block ordering for removed blocks. 9261 action.removedClientIds.forEach(clientId => { 9262 newState.delete(clientId); 9263 }); 9264 newState.forEach((order, clientId) => { 9265 var _order$filter; 9266 const newSubOrder = (_order$filter = order?.filter(id => !action.removedClientIds.includes(id))) !== null && _order$filter !== void 0 ? _order$filter : []; 9267 if (newSubOrder.length !== order.length) { 9268 newState.set(clientId, newSubOrder); 9269 } 9270 }); 9271 return newState; 9272 } 9273 } 9274 return state; 9275 }, 9276 // While technically redundant data as the inverse of `order`, it serves as 9277 // an optimization for the selectors which derive the ancestry of a block. 9278 parents(state = new Map(), action) { 9279 switch (action.type) { 9280 case 'RECEIVE_BLOCKS': 9281 { 9282 const newState = new Map(state); 9283 mapBlockParents(action.blocks).forEach(([key, value]) => { 9284 newState.set(key, value); 9285 }); 9286 return newState; 9287 } 9288 case 'INSERT_BLOCKS': 9289 { 9290 const newState = new Map(state); 9291 mapBlockParents(action.blocks, action.rootClientId || '').forEach(([key, value]) => { 9292 newState.set(key, value); 9293 }); 9294 return newState; 9295 } 9296 case 'MOVE_BLOCKS_TO_POSITION': 9297 { 9298 const newState = new Map(state); 9299 action.clientIds.forEach(id => { 9300 newState.set(id, action.toRootClientId || ''); 9301 }); 9302 return newState; 9303 } 9304 case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9305 { 9306 const newState = new Map(state); 9307 action.replacedClientIds.forEach(clientId => { 9308 newState.delete(clientId); 9309 }); 9310 mapBlockParents(action.blocks, state.get(action.clientIds[0])).forEach(([key, value]) => { 9311 newState.set(key, value); 9312 }); 9313 return newState; 9314 } 9315 case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN': 9316 { 9317 const newState = new Map(state); 9318 action.removedClientIds.forEach(clientId => { 9319 newState.delete(clientId); 9320 }); 9321 return newState; 9322 } 9323 } 9324 return state; 9325 }, 9326 controlledInnerBlocks(state = {}, { 9327 type, 9328 clientId, 9329 hasControlledInnerBlocks 9330 }) { 9331 if (type === 'SET_HAS_CONTROLLED_INNER_BLOCKS') { 9332 return { 9333 ...state, 9334 [clientId]: hasControlledInnerBlocks 9335 }; 9336 } 9337 return state; 9338 } 9339 }); 9340 9341 /** 9342 * Reducer returning visibility status of block interface. 9343 * 9344 * @param {boolean} state Current state. 9345 * @param {Object} action Dispatched action. 9346 * 9347 * @return {boolean} Updated state. 9348 */ 9349 function isBlockInterfaceHidden(state = false, action) { 9350 switch (action.type) { 9351 case 'HIDE_BLOCK_INTERFACE': 9352 return true; 9353 case 'SHOW_BLOCK_INTERFACE': 9354 return false; 9355 } 9356 return state; 9357 } 9358 9359 /** 9360 * Reducer returning typing state. 9361 * 9362 * @param {boolean} state Current state. 9363 * @param {Object} action Dispatched action. 9364 * 9365 * @return {boolean} Updated state. 9366 */ 9367 function isTyping(state = false, action) { 9368 switch (action.type) { 9369 case 'START_TYPING': 9370 return true; 9371 case 'STOP_TYPING': 9372 return false; 9373 } 9374 return state; 9375 } 9376 9377 /** 9378 * Reducer returning dragging state. It is possible for a user to be dragging 9379 * data from outside of the editor, so this state is separate from `draggedBlocks`. 9380 * 9381 * @param {boolean} state Current state. 9382 * @param {Object} action Dispatched action. 9383 * 9384 * @return {boolean} Updated state. 9385 */ 9386 function isDragging(state = false, action) { 9387 switch (action.type) { 9388 case 'START_DRAGGING': 9389 return true; 9390 case 'STOP_DRAGGING': 9391 return false; 9392 } 9393 return state; 9394 } 9395 9396 /** 9397 * Reducer returning dragged block client id. 9398 * 9399 * @param {string[]} state Current state. 9400 * @param {Object} action Dispatched action. 9401 * 9402 * @return {string[]} Updated state. 9403 */ 9404 function draggedBlocks(state = [], action) { 9405 switch (action.type) { 9406 case 'START_DRAGGING_BLOCKS': 9407 return action.clientIds; 9408 case 'STOP_DRAGGING_BLOCKS': 9409 return []; 9410 } 9411 return state; 9412 } 9413 9414 /** 9415 * Reducer tracking the visible blocks. 9416 * 9417 * @param {Record<string,boolean>} state Current state. 9418 * @param {Object} action Dispatched action. 9419 * 9420 * @return {Record<string,boolean>} Block visibility. 9421 */ 9422 function blockVisibility(state = {}, action) { 9423 if (action.type === 'SET_BLOCK_VISIBILITY') { 9424 return { 9425 ...state, 9426 ...action.updates 9427 }; 9428 } 9429 return state; 9430 } 9431 9432 /** 9433 * Internal helper reducer for selectionStart and selectionEnd. Can hold a block 9434 * selection, represented by an object with property clientId. 9435 * 9436 * @param {Object} state Current state. 9437 * @param {Object} action Dispatched action. 9438 * 9439 * @return {Object} Updated state. 9440 */ 9441 function selectionHelper(state = {}, action) { 9442 switch (action.type) { 9443 case 'CLEAR_SELECTED_BLOCK': 9444 { 9445 if (state.clientId) { 9446 return {}; 9447 } 9448 return state; 9449 } 9450 case 'SELECT_BLOCK': 9451 if (action.clientId === state.clientId) { 9452 return state; 9453 } 9454 return { 9455 clientId: action.clientId 9456 }; 9457 case 'REPLACE_INNER_BLOCKS': 9458 case 'INSERT_BLOCKS': 9459 { 9460 if (!action.updateSelection || !action.blocks.length) { 9461 return state; 9462 } 9463 return { 9464 clientId: action.blocks[0].clientId 9465 }; 9466 } 9467 case 'REMOVE_BLOCKS': 9468 if (!action.clientIds || !action.clientIds.length || action.clientIds.indexOf(state.clientId) === -1) { 9469 return state; 9470 } 9471 return {}; 9472 case 'REPLACE_BLOCKS': 9473 { 9474 if (action.clientIds.indexOf(state.clientId) === -1) { 9475 return state; 9476 } 9477 const blockToSelect = action.blocks[action.indexToSelect] || action.blocks[action.blocks.length - 1]; 9478 if (!blockToSelect) { 9479 return {}; 9480 } 9481 if (blockToSelect.clientId === state.clientId) { 9482 return state; 9483 } 9484 return { 9485 clientId: blockToSelect.clientId 9486 }; 9487 } 9488 } 9489 return state; 9490 } 9491 9492 /** 9493 * Reducer returning the selection state. 9494 * 9495 * @param {boolean} state Current state. 9496 * @param {Object} action Dispatched action. 9497 * 9498 * @return {boolean} Updated state. 9499 */ 9500 function selection(state = {}, action) { 9501 switch (action.type) { 9502 case 'SELECTION_CHANGE': 9503 if (action.clientId) { 9504 return { 9505 selectionStart: { 9506 clientId: action.clientId, 9507 attributeKey: action.attributeKey, 9508 offset: action.startOffset 9509 }, 9510 selectionEnd: { 9511 clientId: action.clientId, 9512 attributeKey: action.attributeKey, 9513 offset: action.endOffset 9514 } 9515 }; 9516 } 9517 return { 9518 selectionStart: action.start || state.selectionStart, 9519 selectionEnd: action.end || state.selectionEnd 9520 }; 9521 case 'RESET_SELECTION': 9522 const { 9523 selectionStart, 9524 selectionEnd 9525 } = action; 9526 return { 9527 selectionStart, 9528 selectionEnd 9529 }; 9530 case 'MULTI_SELECT': 9531 const { 9532 start, 9533 end 9534 } = action; 9535 if (start === state.selectionStart?.clientId && end === state.selectionEnd?.clientId) { 9536 return state; 9537 } 9538 return { 9539 selectionStart: { 9540 clientId: start 9541 }, 9542 selectionEnd: { 9543 clientId: end 9544 } 9545 }; 9546 case 'RESET_BLOCKS': 9547 const startClientId = state?.selectionStart?.clientId; 9548 const endClientId = state?.selectionEnd?.clientId; 9549 9550 // Do nothing if there's no selected block. 9551 if (!startClientId && !endClientId) { 9552 return state; 9553 } 9554 9555 // If the start of the selection won't exist after reset, remove selection. 9556 if (!action.blocks.some(block => block.clientId === startClientId)) { 9557 return { 9558 selectionStart: {}, 9559 selectionEnd: {} 9560 }; 9561 } 9562 9563 // If the end of the selection won't exist after reset, collapse selection. 9564 if (!action.blocks.some(block => block.clientId === endClientId)) { 9565 return { 9566 ...state, 9567 selectionEnd: state.selectionStart 9568 }; 9569 } 9570 } 9571 const selectionStart = selectionHelper(state.selectionStart, action); 9572 const selectionEnd = selectionHelper(state.selectionEnd, action); 9573 if (selectionStart === state.selectionStart && selectionEnd === state.selectionEnd) { 9574 return state; 9575 } 9576 return { 9577 selectionStart, 9578 selectionEnd 9579 }; 9580 } 9581 9582 /** 9583 * Reducer returning whether the user is multi-selecting. 9584 * 9585 * @param {boolean} state Current state. 9586 * @param {Object} action Dispatched action. 9587 * 9588 * @return {boolean} Updated state. 9589 */ 9590 function isMultiSelecting(state = false, action) { 9591 switch (action.type) { 9592 case 'START_MULTI_SELECT': 9593 return true; 9594 case 'STOP_MULTI_SELECT': 9595 return false; 9596 } 9597 return state; 9598 } 9599 9600 /** 9601 * Reducer returning whether selection is enabled. 9602 * 9603 * @param {boolean} state Current state. 9604 * @param {Object} action Dispatched action. 9605 * 9606 * @return {boolean} Updated state. 9607 */ 9608 function isSelectionEnabled(state = true, action) { 9609 switch (action.type) { 9610 case 'TOGGLE_SELECTION': 9611 return action.isSelectionEnabled; 9612 } 9613 return state; 9614 } 9615 9616 /** 9617 * Reducer returning the data needed to display a prompt when certain blocks 9618 * are removed, or `false` if no such prompt is requested. 9619 * 9620 * @param {boolean} state Current state. 9621 * @param {Object} action Dispatched action. 9622 * 9623 * @return {Object|false} Data for removal prompt display, if any. 9624 */ 9625 function removalPromptData(state = false, action) { 9626 switch (action.type) { 9627 case 'DISPLAY_BLOCK_REMOVAL_PROMPT': 9628 const { 9629 clientIds, 9630 selectPrevious, 9631 message 9632 } = action; 9633 return { 9634 clientIds, 9635 selectPrevious, 9636 message 9637 }; 9638 case 'CLEAR_BLOCK_REMOVAL_PROMPT': 9639 return false; 9640 } 9641 return state; 9642 } 9643 9644 /** 9645 * Reducer returning any rules that a block editor may provide in order to 9646 * prevent a user from accidentally removing certain blocks. These rules are 9647 * then used to display a confirmation prompt to the user. For instance, in the 9648 * Site Editor, the Query Loop block is important enough to warrant such 9649 * confirmation. 9650 * 9651 * The data is a record whose keys are block types (e.g. 'core/query') and 9652 * whose values are the explanation to be shown to users (e.g. 'Query Loop 9653 * displays a list of posts or pages.'). 9654 * 9655 * @param {boolean} state Current state. 9656 * @param {Object} action Dispatched action. 9657 * 9658 * @return {Record<string,string>} Updated state. 9659 */ 9660 function blockRemovalRules(state = false, action) { 9661 switch (action.type) { 9662 case 'SET_BLOCK_REMOVAL_RULES': 9663 return action.rules; 9664 } 9665 return state; 9666 } 9667 9668 /** 9669 * Reducer returning the initial block selection. 9670 * 9671 * Currently this in only used to restore the selection after block deletion and 9672 * pasting new content.This reducer should eventually be removed in favour of setting 9673 * selection directly. 9674 * 9675 * @param {boolean} state Current state. 9676 * @param {Object} action Dispatched action. 9677 * 9678 * @return {number|null} Initial position: 0, -1 or null. 9679 */ 9680 function initialPosition(state = null, action) { 9681 if (action.type === 'REPLACE_BLOCKS' && action.initialPosition !== undefined) { 9682 return action.initialPosition; 9683 } else if (['MULTI_SELECT', 'SELECT_BLOCK', 'RESET_SELECTION', 'INSERT_BLOCKS', 'REPLACE_INNER_BLOCKS'].includes(action.type)) { 9684 return action.initialPosition; 9685 } 9686 return state; 9687 } 9688 function blocksMode(state = {}, action) { 9689 if (action.type === 'TOGGLE_BLOCK_MODE') { 9690 const { 9691 clientId 9692 } = action; 9693 return { 9694 ...state, 9695 [clientId]: state[clientId] && state[clientId] === 'html' ? 'visual' : 'html' 9696 }; 9697 } 9698 return state; 9699 } 9700 9701 /** 9702 * Reducer returning the block insertion point visibility, either null if there 9703 * is not an explicit insertion point assigned, or an object of its `index` and 9704 * `rootClientId`. 9705 * 9706 * @param {Object} state Current state. 9707 * @param {Object} action Dispatched action. 9708 * 9709 * @return {Object} Updated state. 9710 */ 9711 function insertionCue(state = null, action) { 9712 switch (action.type) { 9713 case 'SHOW_INSERTION_POINT': 9714 { 9715 const { 9716 rootClientId, 9717 index, 9718 __unstableWithInserter, 9719 operation, 9720 nearestSide 9721 } = action; 9722 const nextState = { 9723 rootClientId, 9724 index, 9725 __unstableWithInserter, 9726 operation, 9727 nearestSide 9728 }; 9729 9730 // Bail out updates if the states are the same. 9731 return es6_default()(state, nextState) ? state : nextState; 9732 } 9733 case 'HIDE_INSERTION_POINT': 9734 return null; 9735 } 9736 return state; 9737 } 9738 9739 /** 9740 * Reducer returning whether the post blocks match the defined template or not. 9741 * 9742 * @param {Object} state Current state. 9743 * @param {Object} action Dispatched action. 9744 * 9745 * @return {boolean} Updated state. 9746 */ 9747 function template(state = { 9748 isValid: true 9749 }, action) { 9750 switch (action.type) { 9751 case 'SET_TEMPLATE_VALIDITY': 9752 return { 9753 ...state, 9754 isValid: action.isValid 9755 }; 9756 } 9757 return state; 9758 } 9759 9760 /** 9761 * Reducer returning the editor setting. 9762 * 9763 * @param {Object} state Current state. 9764 * @param {Object} action Dispatched action. 9765 * 9766 * @return {Object} Updated state. 9767 */ 9768 function settings(state = SETTINGS_DEFAULTS, action) { 9769 switch (action.type) { 9770 case 'UPDATE_SETTINGS': 9771 { 9772 const updatedSettings = action.reset ? { 9773 ...SETTINGS_DEFAULTS, 9774 ...action.settings 9775 } : { 9776 ...state, 9777 ...action.settings 9778 }; 9779 Object.defineProperty(updatedSettings, '__unstableIsPreviewMode', { 9780 get() { 9781 external_wp_deprecated_default()('__unstableIsPreviewMode', { 9782 since: '6.8', 9783 alternative: 'isPreviewMode' 9784 }); 9785 return this.isPreviewMode; 9786 } 9787 }); 9788 return updatedSettings; 9789 } 9790 } 9791 return state; 9792 } 9793 9794 /** 9795 * Reducer returning the user preferences. 9796 * 9797 * @param {Object} state Current state. 9798 * @param {Object} action Dispatched action. 9799 * 9800 * @return {string} Updated state. 9801 */ 9802 function preferences(state = PREFERENCES_DEFAULTS, action) { 9803 switch (action.type) { 9804 case 'INSERT_BLOCKS': 9805 case 'REPLACE_BLOCKS': 9806 { 9807 const nextInsertUsage = action.blocks.reduce((prevUsage, block) => { 9808 const { 9809 attributes, 9810 name: blockName 9811 } = block; 9812 let id = blockName; 9813 // If a block variation match is found change the name to be the same with the 9814 // one that is used for block variations in the Inserter (`getItemFromVariation`). 9815 const match = (0,external_wp_data_namespaceObject.select)(external_wp_blocks_namespaceObject.store).getActiveBlockVariation(blockName, attributes); 9816 if (match?.name) { 9817 id += '/' + match.name; 9818 } 9819 if (blockName === 'core/block') { 9820 id += '/' + attributes.ref; 9821 } 9822 return { 9823 ...prevUsage, 9824 [id]: { 9825 time: action.time, 9826 count: prevUsage[id] ? prevUsage[id].count + 1 : 1 9827 } 9828 }; 9829 }, state.insertUsage); 9830 return { 9831 ...state, 9832 insertUsage: nextInsertUsage 9833 }; 9834 } 9835 } 9836 return state; 9837 } 9838 9839 /** 9840 * Reducer returning an object where each key is a block client ID, its value 9841 * representing the settings for its nested blocks. 9842 * 9843 * @param {Object} state Current state. 9844 * @param {Object} action Dispatched action. 9845 * 9846 * @return {Object} Updated state. 9847 */ 9848 const blockListSettings = (state = {}, action) => { 9849 switch (action.type) { 9850 // Even if the replaced blocks have the same client ID, our logic 9851 // should correct the state. 9852 case 'REPLACE_BLOCKS': 9853 case 'REMOVE_BLOCKS': 9854 { 9855 return Object.fromEntries(Object.entries(state).filter(([id]) => !action.clientIds.includes(id))); 9856 } 9857 case 'UPDATE_BLOCK_LIST_SETTINGS': 9858 { 9859 const updates = typeof action.clientId === 'string' ? { 9860 [action.clientId]: action.settings 9861 } : action.clientId; 9862 9863 // Remove settings that are the same as the current state. 9864 for (const clientId in updates) { 9865 if (!updates[clientId]) { 9866 if (!state[clientId]) { 9867 delete updates[clientId]; 9868 } 9869 } else if (es6_default()(state[clientId], updates[clientId])) { 9870 delete updates[clientId]; 9871 } 9872 } 9873 if (Object.keys(updates).length === 0) { 9874 return state; 9875 } 9876 const merged = { 9877 ...state, 9878 ...updates 9879 }; 9880 for (const clientId in updates) { 9881 if (!updates[clientId]) { 9882 delete merged[clientId]; 9883 } 9884 } 9885 return merged; 9886 } 9887 } 9888 return state; 9889 }; 9890 9891 /** 9892 * Reducer return an updated state representing the most recent block attribute 9893 * update. The state is structured as an object where the keys represent the 9894 * client IDs of blocks, the values a subset of attributes from the most recent 9895 * block update. The state is always reset to null if the last action is 9896 * anything other than an attributes update. 9897 * 9898 * @param {Object<string,Object>} state Current state. 9899 * @param {Object} action Action object. 9900 * 9901 * @return {[string,Object]} Updated state. 9902 */ 9903 function lastBlockAttributesChange(state = null, action) { 9904 switch (action.type) { 9905 case 'UPDATE_BLOCK': 9906 if (!action.updates.attributes) { 9907 break; 9908 } 9909 return { 9910 [action.clientId]: action.updates.attributes 9911 }; 9912 case 'UPDATE_BLOCK_ATTRIBUTES': 9913 return action.clientIds.reduce((accumulator, id) => ({ 9914 ...accumulator, 9915 [id]: action.uniqueByBlock ? action.attributes[id] : action.attributes 9916 }), {}); 9917 } 9918 return state; 9919 } 9920 9921 /** 9922 * Reducer returning current highlighted block. 9923 * 9924 * @param {boolean} state Current highlighted block. 9925 * @param {Object} action Dispatched action. 9926 * 9927 * @return {string} Updated state. 9928 */ 9929 function highlightedBlock(state, action) { 9930 switch (action.type) { 9931 case 'TOGGLE_BLOCK_HIGHLIGHT': 9932 const { 9933 clientId, 9934 isHighlighted 9935 } = action; 9936 if (isHighlighted) { 9937 return clientId; 9938 } else if (state === clientId) { 9939 return null; 9940 } 9941 return state; 9942 case 'SELECT_BLOCK': 9943 if (action.clientId !== state) { 9944 return null; 9945 } 9946 } 9947 return state; 9948 } 9949 9950 /** 9951 * Reducer returning current expanded block in the list view. 9952 * 9953 * @param {string|null} state Current expanded block. 9954 * @param {Object} action Dispatched action. 9955 * 9956 * @return {string|null} Updated state. 9957 */ 9958 function expandedBlock(state = null, action) { 9959 switch (action.type) { 9960 case 'SET_BLOCK_EXPANDED_IN_LIST_VIEW': 9961 return action.clientId; 9962 case 'SELECT_BLOCK': 9963 if (action.clientId !== state) { 9964 return null; 9965 } 9966 } 9967 return state; 9968 } 9969 9970 /** 9971 * Reducer returning the block insertion event list state. 9972 * 9973 * @param {Object} state Current state. 9974 * @param {Object} action Dispatched action. 9975 * 9976 * @return {Object} Updated state. 9977 */ 9978 function lastBlockInserted(state = {}, action) { 9979 switch (action.type) { 9980 case 'INSERT_BLOCKS': 9981 case 'REPLACE_BLOCKS': 9982 if (!action.blocks.length) { 9983 return state; 9984 } 9985 const clientIds = action.blocks.map(block => { 9986 return block.clientId; 9987 }); 9988 const source = action.meta?.source; 9989 return { 9990 clientIds, 9991 source 9992 }; 9993 case 'RESET_BLOCKS': 9994 return {}; 9995 } 9996 return state; 9997 } 9998 9999 /** 10000 * Reducer returning the block that is eding temporarily edited as blocks. 10001 * 10002 * @param {Object} state Current state. 10003 * @param {Object} action Dispatched action. 10004 * 10005 * @return {Object} Updated state. 10006 */ 10007 function temporarilyEditingAsBlocks(state = '', action) { 10008 if (action.type === 'SET_TEMPORARILY_EDITING_AS_BLOCKS') { 10009 return action.temporarilyEditingAsBlocks; 10010 } 10011 return state; 10012 } 10013 10014 /** 10015 * Reducer returning the focus mode that should be used when temporarily edit as blocks finishes. 10016 * 10017 * @param {Object} state Current state. 10018 * @param {Object} action Dispatched action. 10019 * 10020 * @return {Object} Updated state. 10021 */ 10022 function temporarilyEditingFocusModeRevert(state = '', action) { 10023 if (action.type === 'SET_TEMPORARILY_EDITING_AS_BLOCKS') { 10024 return action.focusModeToRevert; 10025 } 10026 return state; 10027 } 10028 10029 /** 10030 * Reducer returning a map of block client IDs to block editing modes. 10031 * 10032 * @param {Map} state Current state. 10033 * @param {Object} action Dispatched action. 10034 * 10035 * @return {Map} Updated state. 10036 */ 10037 function blockEditingModes(state = new Map(), action) { 10038 switch (action.type) { 10039 case 'SET_BLOCK_EDITING_MODE': 10040 if (state.get(action.clientId) === action.mode) { 10041 return state; 10042 } 10043 return new Map(state).set(action.clientId, action.mode); 10044 case 'UNSET_BLOCK_EDITING_MODE': 10045 { 10046 if (!state.has(action.clientId)) { 10047 return state; 10048 } 10049 const newState = new Map(state); 10050 newState.delete(action.clientId); 10051 return newState; 10052 } 10053 case 'RESET_BLOCKS': 10054 { 10055 return state.has('') ? new Map().set('', state.get('')) : state; 10056 } 10057 } 10058 return state; 10059 } 10060 10061 /** 10062 * Reducer returning the clientId of the block settings menu that is currently open. 10063 * 10064 * @param {string|null} state Current state. 10065 * @param {Object} action Dispatched action. 10066 * 10067 * @return {string|null} Updated state. 10068 */ 10069 function openedBlockSettingsMenu(state = null, action) { 10070 if ('SET_OPENED_BLOCK_SETTINGS_MENU' === action.type) { 10071 var _action$clientId; 10072 return (_action$clientId = action?.clientId) !== null && _action$clientId !== void 0 ? _action$clientId : null; 10073 } 10074 return state; 10075 } 10076 10077 /** 10078 * Reducer returning a map of style IDs to style overrides. 10079 * 10080 * @param {Map} state Current state. 10081 * @param {Object} action Dispatched action. 10082 * 10083 * @return {Map} Updated state. 10084 */ 10085 function styleOverrides(state = new Map(), action) { 10086 switch (action.type) { 10087 case 'SET_STYLE_OVERRIDE': 10088 return new Map(state).set(action.id, action.style); 10089 case 'DELETE_STYLE_OVERRIDE': 10090 { 10091 const newState = new Map(state); 10092 newState.delete(action.id); 10093 return newState; 10094 } 10095 } 10096 return state; 10097 } 10098 10099 /** 10100 * Reducer returning a map of the registered inserter media categories. 10101 * 10102 * @param {Array} state Current state. 10103 * @param {Object} action Dispatched action. 10104 * 10105 * @return {Array} Updated state. 10106 */ 10107 function registeredInserterMediaCategories(state = [], action) { 10108 switch (action.type) { 10109 case 'REGISTER_INSERTER_MEDIA_CATEGORY': 10110 return [...state, action.category]; 10111 } 10112 return state; 10113 } 10114 10115 /** 10116 * Reducer setting last focused element 10117 * 10118 * @param {boolean} state Current state. 10119 * @param {Object} action Dispatched action. 10120 * 10121 * @return {boolean} Updated state. 10122 */ 10123 function lastFocus(state = false, action) { 10124 switch (action.type) { 10125 case 'LAST_FOCUS': 10126 return action.lastFocus; 10127 } 10128 return state; 10129 } 10130 10131 /** 10132 * Reducer setting currently hovered block. 10133 * 10134 * @param {boolean} state Current state. 10135 * @param {Object} action Dispatched action. 10136 * 10137 * @return {boolean} Updated state. 10138 */ 10139 function hoveredBlockClientId(state = false, action) { 10140 switch (action.type) { 10141 case 'HOVER_BLOCK': 10142 return action.clientId; 10143 } 10144 return state; 10145 } 10146 10147 /** 10148 * Reducer setting zoom out state. 10149 * 10150 * @param {boolean} state Current state. 10151 * @param {Object} action Dispatched action. 10152 * 10153 * @return {number} Updated state. 10154 */ 10155 function zoomLevel(state = 100, action) { 10156 switch (action.type) { 10157 case 'SET_ZOOM_LEVEL': 10158 return action.zoom; 10159 case 'RESET_ZOOM_LEVEL': 10160 return 100; 10161 } 10162 return state; 10163 } 10164 10165 /** 10166 * Reducer setting the insertion point 10167 * 10168 * @param {boolean} state Current state. 10169 * @param {Object} action Dispatched action. 10170 * 10171 * @return {Object} Updated state. 10172 */ 10173 function insertionPoint(state = null, action) { 10174 switch (action.type) { 10175 case 'SET_INSERTION_POINT': 10176 return action.value; 10177 case 'SELECT_BLOCK': 10178 return null; 10179 } 10180 return state; 10181 } 10182 const combinedReducers = (0,external_wp_data_namespaceObject.combineReducers)({ 10183 blocks, 10184 isDragging, 10185 isTyping, 10186 isBlockInterfaceHidden, 10187 draggedBlocks, 10188 selection, 10189 isMultiSelecting, 10190 isSelectionEnabled, 10191 initialPosition, 10192 blocksMode, 10193 blockListSettings, 10194 insertionPoint, 10195 insertionCue, 10196 template, 10197 settings, 10198 preferences, 10199 lastBlockAttributesChange, 10200 lastFocus, 10201 expandedBlock, 10202 highlightedBlock, 10203 lastBlockInserted, 10204 temporarilyEditingAsBlocks, 10205 temporarilyEditingFocusModeRevert, 10206 blockVisibility, 10207 blockEditingModes, 10208 styleOverrides, 10209 removalPromptData, 10210 blockRemovalRules, 10211 openedBlockSettingsMenu, 10212 registeredInserterMediaCategories, 10213 hoveredBlockClientId, 10214 zoomLevel 10215 }); 10216 10217 /** 10218 * Retrieves a block's tree structure, handling both controlled and uncontrolled inner blocks. 10219 * 10220 * @param {Object} state The current state object. 10221 * @param {string} clientId The client ID of the block to retrieve. 10222 * 10223 * @return {Object|undefined} The block tree object, or undefined if not found. For controlled blocks, 10224 * returns a merged tree with controlled inner blocks. 10225 */ 10226 function getBlockTreeBlock(state, clientId) { 10227 if (clientId === '') { 10228 const rootBlock = state.blocks.tree.get(clientId); 10229 if (!rootBlock) { 10230 return; 10231 } 10232 10233 // Patch the root block to have a clientId property. 10234 // TODO - consider updating the blocks reducer so that the root block has this property. 10235 return { 10236 clientId: '', 10237 ...rootBlock 10238 }; 10239 } 10240 if (!state.blocks.controlledInnerBlocks[clientId]) { 10241 return state.blocks.tree.get(clientId); 10242 } 10243 const controlledTree = state.blocks.tree.get(`controlled||$clientId}`); 10244 const regularTree = state.blocks.tree.get(clientId); 10245 return { 10246 ...regularTree, 10247 innerBlocks: controlledTree?.innerBlocks 10248 }; 10249 } 10250 10251 /** 10252 * Recursively traverses through a block tree of a given block and executes a callback for each block. 10253 * 10254 * @param {Object} state The store state. 10255 * @param {string} clientId The clientId of the block to start traversing from. 10256 * @param {Function} callback Function to execute for each block encountered during traversal. 10257 * The callback receives the current block as its argument. 10258 */ 10259 function traverseBlockTree(state, clientId, callback) { 10260 const tree = getBlockTreeBlock(state, clientId); 10261 if (!tree) { 10262 return; 10263 } 10264 callback(tree); 10265 if (!tree?.innerBlocks?.length) { 10266 return; 10267 } 10268 for (const innerBlock of tree?.innerBlocks) { 10269 traverseBlockTree(state, innerBlock.clientId, callback); 10270 } 10271 } 10272 10273 /** 10274 * Checks if a block has a parent in a list of client IDs, and if so returns the client ID of the parent. 10275 * 10276 * @param {Object} state The current state object. 10277 * @param {string} clientId The client ID of the block to search the parents of. 10278 * @param {Array} clientIds The client IDs of the blocks to check. 10279 * 10280 * @return {string|undefined} The client ID of the parent block if found, undefined otherwise. 10281 */ 10282 function findParentInClientIdsList(state, clientId, clientIds) { 10283 if (!clientIds.length) { 10284 return; 10285 } 10286 let parent = state.blocks.parents.get(clientId); 10287 while (parent !== undefined) { 10288 if (clientIds.includes(parent)) { 10289 return parent; 10290 } 10291 parent = state.blocks.parents.get(parent); 10292 } 10293 } 10294 10295 /** 10296 * Checks if a block has any bindings in its metadata attributes. 10297 * 10298 * @param {Object} block The block object to check for bindings. 10299 * @return {boolean} True if the block has bindings, false otherwise. 10300 */ 10301 function hasBindings(block) { 10302 return block?.attributes?.metadata?.bindings && Object.keys(block?.attributes?.metadata?.bindings).length; 10303 } 10304 10305 /** 10306 * Computes and returns derived block editing modes for a given block tree. 10307 * 10308 * This function calculates the editing modes for each block in the tree, taking into account 10309 * various factors such as zoom level, navigation mode, sections, and synced patterns. 10310 * 10311 * @param {Object} state The current state object. 10312 * @param {boolean} isNavMode Whether the navigation mode is active. 10313 * @param {string} treeClientId The client ID of the root block for the tree. Defaults to an empty string. 10314 * @return {Map} A Map containing the derived block editing modes, keyed by block client ID. 10315 */ 10316 function getDerivedBlockEditingModesForTree(state, isNavMode = false, treeClientId = '') { 10317 const isZoomedOut = state?.zoomLevel < 100 || state?.zoomLevel === 'auto-scaled'; 10318 const derivedBlockEditingModes = new Map(); 10319 10320 // When there are sections, the majority of blocks are disabled, 10321 // so the default block editing mode is set to disabled. 10322 const sectionRootClientId = state.settings?.[sectionRootClientIdKey]; 10323 const sectionClientIds = state.blocks.order.get(sectionRootClientId); 10324 const hasDisabledBlocks = Array.from(state.blockEditingModes).some(([, mode]) => mode === 'disabled'); 10325 const templatePartClientIds = []; 10326 const syncedPatternClientIds = []; 10327 Object.keys(state.blocks.controlledInnerBlocks).forEach(clientId => { 10328 const block = state.blocks.byClientId?.get(clientId); 10329 if (block?.name === 'core/template-part') { 10330 templatePartClientIds.push(clientId); 10331 } 10332 if (block?.name === 'core/block') { 10333 syncedPatternClientIds.push(clientId); 10334 } 10335 }); 10336 traverseBlockTree(state, treeClientId, block => { 10337 const { 10338 clientId, 10339 name: blockName 10340 } = block; 10341 10342 // If the block already has an explicit block editing mode set, 10343 // don't override it. 10344 if (state.blockEditingModes.has(clientId)) { 10345 return; 10346 } 10347 10348 // Disabled explicit block editing modes are inherited by children. 10349 // It's an expensive calculation, so only do it if there are disabled blocks. 10350 if (hasDisabledBlocks) { 10351 // Look through parents to find one with an explicit block editing mode. 10352 let ancestorBlockEditingMode; 10353 let parent = state.blocks.parents.get(clientId); 10354 while (parent !== undefined) { 10355 // There's a chance we only just calculated this for the parent, 10356 // if so we can return that value for a faster lookup. 10357 if (derivedBlockEditingModes.has(parent)) { 10358 ancestorBlockEditingMode = derivedBlockEditingModes.get(parent); 10359 } else if (state.blockEditingModes.has(parent)) { 10360 // Checking the explicit block editing mode will be slower, 10361 // as the block editing mode is more likely to be set on a 10362 // distant ancestor. 10363 ancestorBlockEditingMode = state.blockEditingModes.get(parent); 10364 } 10365 if (ancestorBlockEditingMode) { 10366 break; 10367 } 10368 parent = state.blocks.parents.get(parent); 10369 } 10370 10371 // If the ancestor block editing mode is disabled, it's inherited by the child. 10372 if (ancestorBlockEditingMode === 'disabled') { 10373 derivedBlockEditingModes.set(clientId, 'disabled'); 10374 return; 10375 } 10376 } 10377 if (isZoomedOut || isNavMode) { 10378 // If the root block is the section root set its editing mode to contentOnly. 10379 if (clientId === sectionRootClientId) { 10380 derivedBlockEditingModes.set(clientId, 'contentOnly'); 10381 return; 10382 } 10383 10384 // There are no sections, so everything else is disabled. 10385 if (!sectionClientIds?.length) { 10386 derivedBlockEditingModes.set(clientId, 'disabled'); 10387 return; 10388 } 10389 if (sectionClientIds.includes(clientId)) { 10390 derivedBlockEditingModes.set(clientId, 'contentOnly'); 10391 return; 10392 } 10393 10394 // If zoomed out, all blocks that aren't sections or the section root are 10395 // disabled. 10396 if (isZoomedOut) { 10397 derivedBlockEditingModes.set(clientId, 'disabled'); 10398 return; 10399 } 10400 const isInSection = !!findParentInClientIdsList(state, clientId, sectionClientIds); 10401 if (!isInSection) { 10402 if (clientId === '') { 10403 derivedBlockEditingModes.set(clientId, 'disabled'); 10404 return; 10405 } 10406 10407 // Allow selection of template parts outside of sections. 10408 if (blockName === 'core/template-part') { 10409 derivedBlockEditingModes.set(clientId, 'contentOnly'); 10410 return; 10411 } 10412 const isInTemplatePart = !!findParentInClientIdsList(state, clientId, templatePartClientIds); 10413 // Allow contentOnly blocks in template parts outside of sections 10414 // to be editable. Only disable blocks that don't fit this criteria. 10415 if (!isInTemplatePart && !isContentBlock(blockName)) { 10416 derivedBlockEditingModes.set(clientId, 'disabled'); 10417 return; 10418 } 10419 } 10420 10421 // Handle synced pattern content so the inner blocks of a synced pattern are 10422 // properly disabled. 10423 if (syncedPatternClientIds.length) { 10424 const parentPatternClientId = findParentInClientIdsList(state, clientId, syncedPatternClientIds); 10425 if (parentPatternClientId) { 10426 // This is a pattern nested in another pattern, it should be disabled. 10427 if (findParentInClientIdsList(state, parentPatternClientId, syncedPatternClientIds)) { 10428 derivedBlockEditingModes.set(clientId, 'disabled'); 10429 return; 10430 } 10431 if (hasBindings(block)) { 10432 derivedBlockEditingModes.set(clientId, 'contentOnly'); 10433 return; 10434 } 10435 10436 // Synced pattern content without a binding isn't editable 10437 // from the instance, the user has to edit the pattern source, 10438 // so return 'disabled'. 10439 derivedBlockEditingModes.set(clientId, 'disabled'); 10440 return; 10441 } 10442 } 10443 if (blockName && isContentBlock(blockName)) { 10444 derivedBlockEditingModes.set(clientId, 'contentOnly'); 10445 return; 10446 } 10447 derivedBlockEditingModes.set(clientId, 'disabled'); 10448 return; 10449 } 10450 if (syncedPatternClientIds.length) { 10451 // Synced pattern blocks (core/block). 10452 if (syncedPatternClientIds.includes(clientId)) { 10453 // This is a pattern nested in another pattern, it should be disabled. 10454 if (findParentInClientIdsList(state, clientId, syncedPatternClientIds)) { 10455 derivedBlockEditingModes.set(clientId, 'disabled'); 10456 return; 10457 } 10458 10459 // Else do nothing, use the default block editing mode. 10460 return; 10461 } 10462 10463 // Inner blocks of synced patterns. 10464 const parentPatternClientId = findParentInClientIdsList(state, clientId, syncedPatternClientIds); 10465 if (parentPatternClientId) { 10466 // This is a pattern nested in another pattern, it should be disabled. 10467 if (findParentInClientIdsList(state, parentPatternClientId, syncedPatternClientIds)) { 10468 derivedBlockEditingModes.set(clientId, 'disabled'); 10469 return; 10470 } 10471 if (hasBindings(block)) { 10472 derivedBlockEditingModes.set(clientId, 'contentOnly'); 10473 return; 10474 } 10475 10476 // Synced pattern content without a binding isn't editable 10477 // from the instance, the user has to edit the pattern source, 10478 // so return 'disabled'. 10479 derivedBlockEditingModes.set(clientId, 'disabled'); 10480 } 10481 } 10482 }); 10483 return derivedBlockEditingModes; 10484 } 10485 10486 /** 10487 * Updates the derived block editing modes based on added and removed blocks. 10488 * 10489 * This function handles the updating of block editing modes when blocks are added, 10490 * removed, or moved within the editor. 10491 * 10492 * It only returns a value when modifications are made to the block editing modes. 10493 * 10494 * @param {Object} options The options for updating derived block editing modes. 10495 * @param {Object} options.prevState The previous state object. 10496 * @param {Object} options.nextState The next state object. 10497 * @param {Array} [options.addedBlocks] An array of blocks that were added. 10498 * @param {Array} [options.removedClientIds] An array of client IDs of blocks that were removed. 10499 * @param {boolean} [options.isNavMode] Whether the navigation mode is active. 10500 * @return {Map|undefined} The updated derived block editing modes, or undefined if no changes were made. 10501 */ 10502 function getDerivedBlockEditingModesUpdates({ 10503 prevState, 10504 nextState, 10505 addedBlocks, 10506 removedClientIds, 10507 isNavMode = false 10508 }) { 10509 const prevDerivedBlockEditingModes = isNavMode ? prevState.derivedNavModeBlockEditingModes : prevState.derivedBlockEditingModes; 10510 let nextDerivedBlockEditingModes; 10511 10512 // Perform removals before additions to handle cases like the `MOVE_BLOCKS_TO_POSITION` action. 10513 // That action removes a set of clientIds, but adds the same blocks back in a different location. 10514 // If removals were performed after additions, those moved clientIds would be removed incorrectly. 10515 removedClientIds?.forEach(clientId => { 10516 // The actions only receive parent block IDs for removal. 10517 // Recurse through the block tree to ensure all blocks are removed. 10518 // Specifically use the previous state, before the blocks were removed. 10519 traverseBlockTree(prevState, clientId, block => { 10520 if (prevDerivedBlockEditingModes.has(block.clientId)) { 10521 if (!nextDerivedBlockEditingModes) { 10522 nextDerivedBlockEditingModes = new Map(prevDerivedBlockEditingModes); 10523 } 10524 nextDerivedBlockEditingModes.delete(block.clientId); 10525 } 10526 }); 10527 }); 10528 addedBlocks?.forEach(addedBlock => { 10529 traverseBlockTree(nextState, addedBlock.clientId, block => { 10530 const updates = getDerivedBlockEditingModesForTree(nextState, isNavMode, block.clientId); 10531 if (updates.size) { 10532 if (!nextDerivedBlockEditingModes) { 10533 nextDerivedBlockEditingModes = new Map([...(prevDerivedBlockEditingModes?.size ? prevDerivedBlockEditingModes : []), ...updates]); 10534 } else { 10535 nextDerivedBlockEditingModes = new Map([...(nextDerivedBlockEditingModes?.size ? nextDerivedBlockEditingModes : []), ...updates]); 10536 } 10537 } 10538 }); 10539 }); 10540 return nextDerivedBlockEditingModes; 10541 } 10542 10543 /** 10544 * Higher-order reducer that adds derived block editing modes to the state. 10545 * 10546 * This function wraps a reducer and enhances it to handle actions that affect 10547 * block editing modes. It updates the derivedBlockEditingModes in the state 10548 * based on various actions such as adding, removing, or moving blocks, or changing 10549 * the editor mode. 10550 * 10551 * @param {Function} reducer The original reducer function to be wrapped. 10552 * @return {Function} A new reducer function that includes derived block editing modes handling. 10553 */ 10554 function withDerivedBlockEditingModes(reducer) { 10555 return (state, action) => { 10556 var _state$derivedBlockEd, _state$derivedNavMode; 10557 const nextState = reducer(state, action); 10558 10559 // An exception is needed here to still recompute the block editing modes when 10560 // the editor mode changes since the editor mode isn't stored within the 10561 // block editor state and changing it won't trigger an altered new state. 10562 if (action.type !== 'SET_EDITOR_MODE' && nextState === state) { 10563 return state; 10564 } 10565 switch (action.type) { 10566 case 'REMOVE_BLOCKS': 10567 { 10568 const nextDerivedBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10569 prevState: state, 10570 nextState, 10571 removedClientIds: action.clientIds, 10572 isNavMode: false 10573 }); 10574 const nextDerivedNavModeBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10575 prevState: state, 10576 nextState, 10577 removedClientIds: action.clientIds, 10578 isNavMode: true 10579 }); 10580 if (nextDerivedBlockEditingModes || nextDerivedNavModeBlockEditingModes) { 10581 return { 10582 ...nextState, 10583 derivedBlockEditingModes: nextDerivedBlockEditingModes !== null && nextDerivedBlockEditingModes !== void 0 ? nextDerivedBlockEditingModes : state.derivedBlockEditingModes, 10584 derivedNavModeBlockEditingModes: nextDerivedNavModeBlockEditingModes !== null && nextDerivedNavModeBlockEditingModes !== void 0 ? nextDerivedNavModeBlockEditingModes : state.derivedNavModeBlockEditingModes 10585 }; 10586 } 10587 break; 10588 } 10589 case 'RECEIVE_BLOCKS': 10590 case 'INSERT_BLOCKS': 10591 { 10592 const nextDerivedBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10593 prevState: state, 10594 nextState, 10595 addedBlocks: action.blocks, 10596 isNavMode: false 10597 }); 10598 const nextDerivedNavModeBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10599 prevState: state, 10600 nextState, 10601 addedBlocks: action.blocks, 10602 isNavMode: true 10603 }); 10604 if (nextDerivedBlockEditingModes || nextDerivedNavModeBlockEditingModes) { 10605 return { 10606 ...nextState, 10607 derivedBlockEditingModes: nextDerivedBlockEditingModes !== null && nextDerivedBlockEditingModes !== void 0 ? nextDerivedBlockEditingModes : state.derivedBlockEditingModes, 10608 derivedNavModeBlockEditingModes: nextDerivedNavModeBlockEditingModes !== null && nextDerivedNavModeBlockEditingModes !== void 0 ? nextDerivedNavModeBlockEditingModes : state.derivedNavModeBlockEditingModes 10609 }; 10610 } 10611 break; 10612 } 10613 case 'SET_BLOCK_EDITING_MODE': 10614 case 'UNSET_BLOCK_EDITING_MODE': 10615 case 'SET_HAS_CONTROLLED_INNER_BLOCKS': 10616 { 10617 const updatedBlock = getBlockTreeBlock(nextState, action.clientId); 10618 10619 // The block might have been removed in which case it'll be 10620 // handled by the `REMOVE_BLOCKS` action. 10621 if (!updatedBlock) { 10622 break; 10623 } 10624 const nextDerivedBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10625 prevState: state, 10626 nextState, 10627 removedClientIds: [action.clientId], 10628 addedBlocks: [updatedBlock], 10629 isNavMode: false 10630 }); 10631 const nextDerivedNavModeBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10632 prevState: state, 10633 nextState, 10634 removedClientIds: [action.clientId], 10635 addedBlocks: [updatedBlock], 10636 isNavMode: true 10637 }); 10638 if (nextDerivedBlockEditingModes || nextDerivedNavModeBlockEditingModes) { 10639 return { 10640 ...nextState, 10641 derivedBlockEditingModes: nextDerivedBlockEditingModes !== null && nextDerivedBlockEditingModes !== void 0 ? nextDerivedBlockEditingModes : state.derivedBlockEditingModes, 10642 derivedNavModeBlockEditingModes: nextDerivedNavModeBlockEditingModes !== null && nextDerivedNavModeBlockEditingModes !== void 0 ? nextDerivedNavModeBlockEditingModes : state.derivedNavModeBlockEditingModes 10643 }; 10644 } 10645 break; 10646 } 10647 case 'REPLACE_BLOCKS': 10648 { 10649 const nextDerivedBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10650 prevState: state, 10651 nextState, 10652 addedBlocks: action.blocks, 10653 removedClientIds: action.clientIds, 10654 isNavMode: false 10655 }); 10656 const nextDerivedNavModeBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10657 prevState: state, 10658 nextState, 10659 addedBlocks: action.blocks, 10660 removedClientIds: action.clientIds, 10661 isNavMode: true 10662 }); 10663 if (nextDerivedBlockEditingModes || nextDerivedNavModeBlockEditingModes) { 10664 return { 10665 ...nextState, 10666 derivedBlockEditingModes: nextDerivedBlockEditingModes !== null && nextDerivedBlockEditingModes !== void 0 ? nextDerivedBlockEditingModes : state.derivedBlockEditingModes, 10667 derivedNavModeBlockEditingModes: nextDerivedNavModeBlockEditingModes !== null && nextDerivedNavModeBlockEditingModes !== void 0 ? nextDerivedNavModeBlockEditingModes : state.derivedNavModeBlockEditingModes 10668 }; 10669 } 10670 break; 10671 } 10672 case 'REPLACE_INNER_BLOCKS': 10673 { 10674 // Get the clientIds of the blocks that are being replaced 10675 // from the old state, before they were removed. 10676 const removedClientIds = state.blocks.order.get(action.rootClientId); 10677 const nextDerivedBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10678 prevState: state, 10679 nextState, 10680 addedBlocks: action.blocks, 10681 removedClientIds, 10682 isNavMode: false 10683 }); 10684 const nextDerivedNavModeBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10685 prevState: state, 10686 nextState, 10687 addedBlocks: action.blocks, 10688 removedClientIds, 10689 isNavMode: true 10690 }); 10691 if (nextDerivedBlockEditingModes || nextDerivedNavModeBlockEditingModes) { 10692 return { 10693 ...nextState, 10694 derivedBlockEditingModes: nextDerivedBlockEditingModes !== null && nextDerivedBlockEditingModes !== void 0 ? nextDerivedBlockEditingModes : state.derivedBlockEditingModes, 10695 derivedNavModeBlockEditingModes: nextDerivedNavModeBlockEditingModes !== null && nextDerivedNavModeBlockEditingModes !== void 0 ? nextDerivedNavModeBlockEditingModes : state.derivedNavModeBlockEditingModes 10696 }; 10697 } 10698 break; 10699 } 10700 case 'MOVE_BLOCKS_TO_POSITION': 10701 { 10702 const addedBlocks = action.clientIds.map(clientId => { 10703 return nextState.blocks.byClientId.get(clientId); 10704 }); 10705 const nextDerivedBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10706 prevState: state, 10707 nextState, 10708 addedBlocks, 10709 removedClientIds: action.clientIds, 10710 isNavMode: false 10711 }); 10712 const nextDerivedNavModeBlockEditingModes = getDerivedBlockEditingModesUpdates({ 10713 prevState: state, 10714 nextState, 10715 addedBlocks, 10716 removedClientIds: action.clientIds, 10717 isNavMode: true 10718 }); 10719 if (nextDerivedBlockEditingModes || nextDerivedNavModeBlockEditingModes) { 10720 return { 10721 ...nextState, 10722 derivedBlockEditingModes: nextDerivedBlockEditingModes !== null && nextDerivedBlockEditingModes !== void 0 ? nextDerivedBlockEditingModes : state.derivedBlockEditingModes, 10723 derivedNavModeBlockEditingModes: nextDerivedNavModeBlockEditingModes !== null && nextDerivedNavModeBlockEditingModes !== void 0 ? nextDerivedNavModeBlockEditingModes : state.derivedNavModeBlockEditingModes 10724 }; 10725 } 10726 break; 10727 } 10728 case 'UPDATE_SETTINGS': 10729 { 10730 // Recompute the entire tree if the section root changes. 10731 if (state?.settings?.[sectionRootClientIdKey] !== nextState?.settings?.[sectionRootClientIdKey]) { 10732 return { 10733 ...nextState, 10734 derivedBlockEditingModes: getDerivedBlockEditingModesForTree(nextState, false /* Nav mode off */), 10735 derivedNavModeBlockEditingModes: getDerivedBlockEditingModesForTree(nextState, true /* Nav mode on */) 10736 }; 10737 } 10738 break; 10739 } 10740 case 'RESET_BLOCKS': 10741 case 'SET_EDITOR_MODE': 10742 case 'RESET_ZOOM_LEVEL': 10743 case 'SET_ZOOM_LEVEL': 10744 { 10745 // Recompute the entire tree if the editor mode or zoom level changes, 10746 // or if all the blocks are reset. 10747 return { 10748 ...nextState, 10749 derivedBlockEditingModes: getDerivedBlockEditingModesForTree(nextState, false /* Nav mode off */), 10750 derivedNavModeBlockEditingModes: getDerivedBlockEditingModesForTree(nextState, true /* Nav mode on */) 10751 }; 10752 } 10753 } 10754 10755 // If there's no change, the derivedBlockEditingModes from the previous 10756 // state need to be preserved. 10757 nextState.derivedBlockEditingModes = (_state$derivedBlockEd = state?.derivedBlockEditingModes) !== null && _state$derivedBlockEd !== void 0 ? _state$derivedBlockEd : new Map(); 10758 nextState.derivedNavModeBlockEditingModes = (_state$derivedNavMode = state?.derivedNavModeBlockEditingModes) !== null && _state$derivedNavMode !== void 0 ? _state$derivedNavMode : new Map(); 10759 return nextState; 10760 }; 10761 } 10762 function withAutomaticChangeReset(reducer) { 10763 return (state, action) => { 10764 const nextState = reducer(state, action); 10765 if (!state) { 10766 return nextState; 10767 } 10768 10769 // Take over the last value without creating a new reference. 10770 nextState.automaticChangeStatus = state.automaticChangeStatus; 10771 if (action.type === 'MARK_AUTOMATIC_CHANGE') { 10772 return { 10773 ...nextState, 10774 automaticChangeStatus: 'pending' 10775 }; 10776 } 10777 if (action.type === 'MARK_AUTOMATIC_CHANGE_FINAL' && state.automaticChangeStatus === 'pending') { 10778 return { 10779 ...nextState, 10780 automaticChangeStatus: 'final' 10781 }; 10782 } 10783 10784 // If there's a change that doesn't affect blocks or selection, maintain 10785 // the current status. 10786 if (nextState.blocks === state.blocks && nextState.selection === state.selection) { 10787 return nextState; 10788 } 10789 10790 // As long as the state is not final, ignore any selection changes. 10791 if (nextState.automaticChangeStatus !== 'final' && nextState.selection !== state.selection) { 10792 return nextState; 10793 } 10794 10795 // Reset the status if blocks change or selection changes (when status is final). 10796 return { 10797 ...nextState, 10798 automaticChangeStatus: undefined 10799 }; 10800 }; 10801 } 10802 /* harmony default export */ const reducer = ((0,external_wp_compose_namespaceObject.pipe)(withDerivedBlockEditingModes, withAutomaticChangeReset)(combinedReducers)); 10803 10804 ;// external ["wp","primitives"] 10805 const external_wp_primitives_namespaceObject = window["wp"]["primitives"]; 10806 ;// external "ReactJSXRuntime" 10807 const external_ReactJSXRuntime_namespaceObject = window["ReactJSXRuntime"]; 10808 ;// ./node_modules/@wordpress/icons/build-module/library/symbol.js 10809 /** 10810 * WordPress dependencies 10811 */ 10812 10813 10814 const symbol = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 10815 xmlns: "http://www.w3.org/2000/svg", 10816 viewBox: "0 0 24 24", 10817 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 10818 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" 10819 }) 10820 }); 10821 /* harmony default export */ const library_symbol = (symbol); 10822 10823 ;// external ["wp","richText"] 10824 const external_wp_richText_namespaceObject = window["wp"]["richText"]; 10825 ;// external ["wp","preferences"] 10826 const external_wp_preferences_namespaceObject = window["wp"]["preferences"]; 10827 ;// external ["wp","blockSerializationDefaultParser"] 10828 const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 10829 ;// ./node_modules/@wordpress/block-editor/build-module/store/constants.js 10830 const STORE_NAME = 'core/block-editor'; 10831 10832 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/utils.js 10833 /** 10834 * WordPress dependencies 10835 */ 10836 10837 10838 const INSERTER_PATTERN_TYPES = { 10839 user: 'user', 10840 theme: 'theme', 10841 directory: 'directory' 10842 }; 10843 const INSERTER_SYNC_TYPES = { 10844 full: 'fully', 10845 unsynced: 'unsynced' 10846 }; 10847 const allPatternsCategory = { 10848 name: 'allPatterns', 10849 label: (0,external_wp_i18n_namespaceObject._x)('All', 'patterns') 10850 }; 10851 const myPatternsCategory = { 10852 name: 'myPatterns', 10853 label: (0,external_wp_i18n_namespaceObject.__)('My patterns') 10854 }; 10855 const starterPatternsCategory = { 10856 name: 'core/starter-content', 10857 label: (0,external_wp_i18n_namespaceObject.__)('Starter content') 10858 }; 10859 function isPatternFiltered(pattern, sourceFilter, syncFilter) { 10860 const isUserPattern = pattern.name.startsWith('core/block'); 10861 const isDirectoryPattern = pattern.source === 'core' || pattern.source?.startsWith('pattern-directory'); 10862 10863 // If theme source selected, filter out user created patterns and those from 10864 // the core patterns directory. 10865 if (sourceFilter === INSERTER_PATTERN_TYPES.theme && (isUserPattern || isDirectoryPattern)) { 10866 return true; 10867 } 10868 10869 // If the directory source is selected, filter out user created patterns 10870 // and those bundled with the theme. 10871 if (sourceFilter === INSERTER_PATTERN_TYPES.directory && (isUserPattern || !isDirectoryPattern)) { 10872 return true; 10873 } 10874 10875 // If user source selected, filter out theme patterns. 10876 if (sourceFilter === INSERTER_PATTERN_TYPES.user && pattern.type !== INSERTER_PATTERN_TYPES.user) { 10877 return true; 10878 } 10879 10880 // Filter by sync status. 10881 if (syncFilter === INSERTER_SYNC_TYPES.full && pattern.syncStatus !== '') { 10882 return true; 10883 } 10884 if (syncFilter === INSERTER_SYNC_TYPES.unsynced && pattern.syncStatus !== 'unsynced' && isUserPattern) { 10885 return true; 10886 } 10887 return false; 10888 } 10889 10890 ;// ./node_modules/@wordpress/block-editor/build-module/utils/object.js 10891 /** 10892 * Immutably sets a value inside an object. Like `lodash#set`, but returning a 10893 * new object. Treats nullish initial values as empty objects. Clones any 10894 * nested objects. Supports arrays, too. 10895 * 10896 * @param {Object} object Object to set a value in. 10897 * @param {number|string|Array} path Path in the object to modify. 10898 * @param {*} value New value to set. 10899 * @return {Object} Cloned object with the new value set. 10900 */ 10901 function setImmutably(object, path, value) { 10902 // Normalize path 10903 path = Array.isArray(path) ? [...path] : [path]; 10904 10905 // Shallowly clone the base of the object 10906 object = Array.isArray(object) ? [...object] : { 10907 ...object 10908 }; 10909 const leaf = path.pop(); 10910 10911 // Traverse object from root to leaf, shallowly cloning at each level 10912 let prev = object; 10913 for (const key of path) { 10914 const lvl = prev[key]; 10915 prev = prev[key] = Array.isArray(lvl) ? [...lvl] : { 10916 ...lvl 10917 }; 10918 } 10919 prev[leaf] = value; 10920 return object; 10921 } 10922 10923 /** 10924 * Helper util to return a value from a certain path of the object. 10925 * Path is specified as either: 10926 * - a string of properties, separated by dots, for example: "x.y". 10927 * - an array of properties, for example `[ 'x', 'y' ]`. 10928 * You can also specify a default value in case the result is nullish. 10929 * 10930 * @param {Object} object Input object. 10931 * @param {string|Array} path Path to the object property. 10932 * @param {*} defaultValue Default value if the value at the specified path is nullish. 10933 * @return {*} Value of the object property at the specified path. 10934 */ 10935 const getValueFromObjectPath = (object, path, defaultValue) => { 10936 var _value; 10937 const arrayPath = Array.isArray(path) ? path : path.split('.'); 10938 let value = object; 10939 arrayPath.forEach(fieldName => { 10940 value = value?.[fieldName]; 10941 }); 10942 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 10943 }; 10944 10945 /** 10946 * Helper util to filter out objects with duplicate values for a given property. 10947 * 10948 * @param {Object[]} array Array of objects to filter. 10949 * @param {string} property Property to filter unique values by. 10950 * 10951 * @return {Object[]} Array of objects with unique values for the specified property. 10952 */ 10953 function uniqByProperty(array, property) { 10954 const seen = new Set(); 10955 return array.filter(item => { 10956 const value = item[property]; 10957 return seen.has(value) ? false : seen.add(value); 10958 }); 10959 } 10960 10961 ;// ./node_modules/@wordpress/block-editor/build-module/store/get-block-settings.js 10962 /** 10963 * WordPress dependencies 10964 */ 10965 10966 10967 10968 /** 10969 * Internal dependencies 10970 */ 10971 10972 10973 const blockedPaths = ['color', 'border', 'dimensions', 'typography', 'spacing']; 10974 const deprecatedFlags = { 10975 'color.palette': settings => settings.colors, 10976 'color.gradients': settings => settings.gradients, 10977 'color.custom': settings => settings.disableCustomColors === undefined ? undefined : !settings.disableCustomColors, 10978 'color.customGradient': settings => settings.disableCustomGradients === undefined ? undefined : !settings.disableCustomGradients, 10979 'typography.fontSizes': settings => settings.fontSizes, 10980 'typography.customFontSize': settings => settings.disableCustomFontSizes === undefined ? undefined : !settings.disableCustomFontSizes, 10981 'typography.lineHeight': settings => settings.enableCustomLineHeight, 10982 'spacing.units': settings => { 10983 if (settings.enableCustomUnits === undefined) { 10984 return; 10985 } 10986 if (settings.enableCustomUnits === true) { 10987 return ['px', 'em', 'rem', 'vh', 'vw', '%']; 10988 } 10989 return settings.enableCustomUnits; 10990 }, 10991 'spacing.padding': settings => settings.enableCustomSpacing 10992 }; 10993 const prefixedFlags = { 10994 /* 10995 * These were only available in the plugin 10996 * and can be removed when the minimum WordPress version 10997 * for the plugin is 5.9. 10998 */ 10999 'border.customColor': 'border.color', 11000 'border.customStyle': 'border.style', 11001 'border.customWidth': 'border.width', 11002 'typography.customFontStyle': 'typography.fontStyle', 11003 'typography.customFontWeight': 'typography.fontWeight', 11004 'typography.customLetterSpacing': 'typography.letterSpacing', 11005 'typography.customTextDecorations': 'typography.textDecoration', 11006 'typography.customTextTransforms': 'typography.textTransform', 11007 /* 11008 * These were part of WordPress 5.8 and we need to keep them. 11009 */ 11010 'border.customRadius': 'border.radius', 11011 'spacing.customMargin': 'spacing.margin', 11012 'spacing.customPadding': 'spacing.padding', 11013 'typography.customLineHeight': 'typography.lineHeight' 11014 }; 11015 11016 /** 11017 * Remove `custom` prefixes for flags that did not land in 5.8. 11018 * 11019 * This provides continued support for `custom` prefixed properties. It will 11020 * be removed once third party devs have had sufficient time to update themes, 11021 * plugins, etc. 11022 * 11023 * @see https://github.com/WordPress/gutenberg/pull/34485 11024 * 11025 * @param {string} path Path to desired value in settings. 11026 * @return {string} The value for defined setting. 11027 */ 11028 const removeCustomPrefixes = path => { 11029 return prefixedFlags[path] || path; 11030 }; 11031 function getBlockSettings(state, clientId, ...paths) { 11032 const blockName = getBlockName(state, clientId); 11033 const candidates = []; 11034 if (clientId) { 11035 let id = clientId; 11036 do { 11037 const name = getBlockName(state, id); 11038 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, '__experimentalSettings', false)) { 11039 candidates.push(id); 11040 } 11041 } while (id = state.blocks.parents.get(id)); 11042 } 11043 return paths.map(path => { 11044 if (blockedPaths.includes(path)) { 11045 // eslint-disable-next-line no-console 11046 console.warn('Top level useSetting paths are disabled. Please use a subpath to query the information needed.'); 11047 return undefined; 11048 } 11049 11050 // 0. Allow third parties to filter the block's settings at runtime. 11051 let result = (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.useSetting.before', undefined, path, clientId, blockName); 11052 if (undefined !== result) { 11053 return result; 11054 } 11055 const normalizedPath = removeCustomPrefixes(path); 11056 11057 // 1. Take settings from the block instance or its ancestors. 11058 // Start from the current block and work our way up the ancestors. 11059 for (const candidateClientId of candidates) { 11060 var _getValueFromObjectPa; 11061 const candidateAtts = getBlockAttributes(state, candidateClientId); 11062 result = (_getValueFromObjectPa = getValueFromObjectPath(candidateAtts.settings?.blocks?.[blockName], normalizedPath)) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(candidateAtts.settings, normalizedPath); 11063 if (result !== undefined) { 11064 // Stop the search for more distant ancestors and move on. 11065 break; 11066 } 11067 } 11068 11069 // 2. Fall back to the settings from the block editor store (__experimentalFeatures). 11070 const settings = getSettings(state); 11071 if (result === undefined && blockName) { 11072 result = getValueFromObjectPath(settings.__experimentalFeatures?.blocks?.[blockName], normalizedPath); 11073 } 11074 if (result === undefined) { 11075 result = getValueFromObjectPath(settings.__experimentalFeatures, normalizedPath); 11076 } 11077 11078 // Return if the setting was found in either the block instance or the store. 11079 if (result !== undefined) { 11080 if (external_wp_blocks_namespaceObject.__EXPERIMENTAL_PATHS_WITH_OVERRIDE[normalizedPath]) { 11081 var _ref, _result$custom; 11082 return (_ref = (_result$custom = result.custom) !== null && _result$custom !== void 0 ? _result$custom : result.theme) !== null && _ref !== void 0 ? _ref : result.default; 11083 } 11084 return result; 11085 } 11086 11087 // 3. Otherwise, use deprecated settings. 11088 const deprecatedSettingsValue = deprecatedFlags[normalizedPath]?.(settings); 11089 if (deprecatedSettingsValue !== undefined) { 11090 return deprecatedSettingsValue; 11091 } 11092 11093 // 4. Fallback for typography.dropCap: 11094 // This is only necessary to support typography.dropCap. 11095 // when __experimentalFeatures are not present (core without plugin). 11096 // To remove when __experimentalFeatures are ported to core. 11097 return normalizedPath === 'typography.dropCap' ? true : undefined; 11098 }); 11099 } 11100 11101 ;// ./node_modules/@wordpress/block-editor/build-module/store/private-selectors.js 11102 /** 11103 * WordPress dependencies 11104 */ 11105 11106 11107 /** 11108 * Internal dependencies 11109 */ 11110 11111 11112 11113 11114 11115 11116 11117 11118 /** 11119 * Returns true if the block interface is hidden, or false otherwise. 11120 * 11121 * @param {Object} state Global application state. 11122 * 11123 * @return {boolean} Whether the block toolbar is hidden. 11124 */ 11125 function private_selectors_isBlockInterfaceHidden(state) { 11126 return state.isBlockInterfaceHidden; 11127 } 11128 11129 /** 11130 * Gets the client ids of the last inserted blocks. 11131 * 11132 * @param {Object} state Global application state. 11133 * @return {Array|undefined} Client Ids of the last inserted block(s). 11134 */ 11135 function getLastInsertedBlocksClientIds(state) { 11136 return state?.lastBlockInserted?.clientIds; 11137 } 11138 function getBlockWithoutAttributes(state, clientId) { 11139 return state.blocks.byClientId.get(clientId); 11140 } 11141 11142 /** 11143 * Returns true if all of the descendants of a block with the given client ID 11144 * have an editing mode of 'disabled', or false otherwise. 11145 * 11146 * @param {Object} state Global application state. 11147 * @param {string} clientId The block client ID. 11148 * 11149 * @return {boolean} Whether the block descendants are disabled. 11150 */ 11151 const isBlockSubtreeDisabled = (state, clientId) => { 11152 const isChildSubtreeDisabled = childClientId => { 11153 return getBlockEditingMode(state, childClientId) === 'disabled' && getBlockOrder(state, childClientId).every(isChildSubtreeDisabled); 11154 }; 11155 return getBlockOrder(state, clientId).every(isChildSubtreeDisabled); 11156 }; 11157 function getEnabledClientIdsTreeUnmemoized(state, rootClientId) { 11158 const blockOrder = getBlockOrder(state, rootClientId); 11159 const result = []; 11160 for (const clientId of blockOrder) { 11161 const innerBlocks = getEnabledClientIdsTreeUnmemoized(state, clientId); 11162 if (getBlockEditingMode(state, clientId) !== 'disabled') { 11163 result.push({ 11164 clientId, 11165 innerBlocks 11166 }); 11167 } else { 11168 result.push(...innerBlocks); 11169 } 11170 } 11171 return result; 11172 } 11173 11174 /** 11175 * Returns a tree of block objects with only clientID and innerBlocks set. 11176 * Blocks with a 'disabled' editing mode are not included. 11177 * 11178 * @param {Object} state Global application state. 11179 * @param {?string} rootClientId Optional root client ID of block list. 11180 * 11181 * @return {Object[]} Tree of block objects with only clientID and innerBlocks set. 11182 */ 11183 const getEnabledClientIdsTree = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)(getEnabledClientIdsTreeUnmemoized, state => [state.blocks.order, state.derivedBlockEditingModes, state.derivedNavModeBlockEditingModes, state.blockEditingModes, state.settings.templateLock, state.blockListSettings, select(STORE_NAME).__unstableGetEditorMode(state)])); 11184 11185 /** 11186 * Returns a list of a given block's ancestors, from top to bottom. Blocks with 11187 * a 'disabled' editing mode are excluded. 11188 * 11189 * @see getBlockParents 11190 * 11191 * @param {Object} state Global application state. 11192 * @param {string} clientId The block client ID. 11193 * @param {boolean} ascending Order results from bottom to top (true) or top 11194 * to bottom (false). 11195 */ 11196 const getEnabledBlockParents = (0,external_wp_data_namespaceObject.createSelector)((state, clientId, ascending = false) => { 11197 return getBlockParents(state, clientId, ascending).filter(parent => getBlockEditingMode(state, parent) !== 'disabled'); 11198 }, state => [state.blocks.parents, state.blockEditingModes, state.settings.templateLock, state.blockListSettings]); 11199 11200 /** 11201 * Selector that returns the data needed to display a prompt when certain 11202 * blocks are removed, or `false` if no such prompt is requested. 11203 * 11204 * @param {Object} state Global application state. 11205 * 11206 * @return {Object|false} Data for removal prompt display, if any. 11207 */ 11208 function getRemovalPromptData(state) { 11209 return state.removalPromptData; 11210 } 11211 11212 /** 11213 * Returns true if removal prompt exists, or false otherwise. 11214 * 11215 * @param {Object} state Global application state. 11216 * 11217 * @return {boolean} Whether removal prompt exists. 11218 */ 11219 function getBlockRemovalRules(state) { 11220 return state.blockRemovalRules; 11221 } 11222 11223 /** 11224 * Returns the client ID of the block settings menu that is currently open. 11225 * 11226 * @param {Object} state Global application state. 11227 * @return {string|null} The client ID of the block menu that is currently open. 11228 */ 11229 function getOpenedBlockSettingsMenu(state) { 11230 return state.openedBlockSettingsMenu; 11231 } 11232 11233 /** 11234 * Returns all style overrides, intended to be merged with global editor styles. 11235 * 11236 * Overrides are sorted to match the order of the blocks they relate to. This 11237 * is useful to maintain correct CSS cascade order. 11238 * 11239 * @param {Object} state Global application state. 11240 * 11241 * @return {Array} An array of style ID to style override pairs. 11242 */ 11243 const getStyleOverrides = (0,external_wp_data_namespaceObject.createSelector)(state => { 11244 const clientIds = getClientIdsWithDescendants(state); 11245 const clientIdMap = clientIds.reduce((acc, clientId, index) => { 11246 acc[clientId] = index; 11247 return acc; 11248 }, {}); 11249 return [...state.styleOverrides].sort((overrideA, overrideB) => { 11250 var _clientIdMap$clientId, _clientIdMap$clientId2; 11251 // Once the overrides Map is spread to an array, the first element 11252 // is the key, while the second is the override itself including 11253 // the clientId to sort by. 11254 const [, { 11255 clientId: clientIdA 11256 }] = overrideA; 11257 const [, { 11258 clientId: clientIdB 11259 }] = overrideB; 11260 const aIndex = (_clientIdMap$clientId = clientIdMap[clientIdA]) !== null && _clientIdMap$clientId !== void 0 ? _clientIdMap$clientId : -1; 11261 const bIndex = (_clientIdMap$clientId2 = clientIdMap[clientIdB]) !== null && _clientIdMap$clientId2 !== void 0 ? _clientIdMap$clientId2 : -1; 11262 return aIndex - bIndex; 11263 }); 11264 }, state => [state.blocks.order, state.styleOverrides]); 11265 11266 /** @typedef {import('./actions').InserterMediaCategory} InserterMediaCategory */ 11267 /** 11268 * Returns the registered inserter media categories through the public API. 11269 * 11270 * @param {Object} state Editor state. 11271 * 11272 * @return {InserterMediaCategory[]} Inserter media categories. 11273 */ 11274 function getRegisteredInserterMediaCategories(state) { 11275 return state.registeredInserterMediaCategories; 11276 } 11277 11278 /** 11279 * Returns an array containing the allowed inserter media categories. 11280 * It merges the registered media categories from extenders with the 11281 * core ones. It also takes into account the allowed `mime_types`, which 11282 * can be altered by `upload_mimes` filter and restrict some of them. 11283 * 11284 * @param {Object} state Global application state. 11285 * 11286 * @return {InserterMediaCategory[]} Client IDs of descendants. 11287 */ 11288 const getInserterMediaCategories = (0,external_wp_data_namespaceObject.createSelector)(state => { 11289 const { 11290 settings: { 11291 inserterMediaCategories, 11292 allowedMimeTypes, 11293 enableOpenverseMediaCategory 11294 }, 11295 registeredInserterMediaCategories 11296 } = state; 11297 // The allowed `mime_types` can be altered by `upload_mimes` filter and restrict 11298 // some of them. In this case we shouldn't add the category to the available media 11299 // categories list in the inserter. 11300 if (!inserterMediaCategories && !registeredInserterMediaCategories.length || !allowedMimeTypes) { 11301 return; 11302 } 11303 const coreInserterMediaCategoriesNames = inserterMediaCategories?.map(({ 11304 name 11305 }) => name) || []; 11306 const mergedCategories = [...(inserterMediaCategories || []), ...(registeredInserterMediaCategories || []).filter(({ 11307 name 11308 }) => !coreInserterMediaCategoriesNames.includes(name))]; 11309 return mergedCategories.filter(category => { 11310 // Check if Openverse category is enabled. 11311 if (!enableOpenverseMediaCategory && category.name === 'openverse') { 11312 return false; 11313 } 11314 return Object.values(allowedMimeTypes).some(mimeType => mimeType.startsWith(`$category.mediaType}/`)); 11315 }); 11316 }, state => [state.settings.inserterMediaCategories, state.settings.allowedMimeTypes, state.settings.enableOpenverseMediaCategory, state.registeredInserterMediaCategories]); 11317 11318 /** 11319 * Returns whether there is at least one allowed pattern for inner blocks children. 11320 * This is useful for deferring the parsing of all patterns until needed. 11321 * 11322 * @param {Object} state Editor state. 11323 * @param {string} [rootClientId=null] Target root client ID. 11324 * 11325 * @return {boolean} If there is at least one allowed pattern. 11326 */ 11327 const hasAllowedPatterns = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, rootClientId = null) => { 11328 const { 11329 getAllPatterns 11330 } = unlock(select(STORE_NAME)); 11331 const patterns = getAllPatterns(); 11332 const { 11333 allowedBlockTypes 11334 } = getSettings(state); 11335 return patterns.some(pattern => { 11336 const { 11337 inserter = true 11338 } = pattern; 11339 if (!inserter) { 11340 return false; 11341 } 11342 const grammar = getGrammar(pattern); 11343 return checkAllowListRecursive(grammar, allowedBlockTypes) && grammar.every(({ 11344 name: blockName 11345 }) => canInsertBlockType(state, blockName, rootClientId)); 11346 }); 11347 }, (state, rootClientId) => [...getAllPatternsDependants(select)(state), ...getInsertBlockTypeDependants(select)(state, rootClientId)])); 11348 function mapUserPattern(userPattern, __experimentalUserPatternCategories = []) { 11349 return { 11350 name: `core/block/$userPattern.id}`, 11351 id: userPattern.id, 11352 type: INSERTER_PATTERN_TYPES.user, 11353 title: userPattern.title.raw, 11354 categories: userPattern.wp_pattern_category?.map(catId => { 11355 const category = __experimentalUserPatternCategories.find(({ 11356 id 11357 }) => id === catId); 11358 return category ? category.slug : catId; 11359 }), 11360 content: userPattern.content.raw, 11361 syncStatus: userPattern.wp_pattern_sync_status 11362 }; 11363 } 11364 const getPatternBySlug = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, patternName) => { 11365 var _state$settings$__exp, _state$settings$selec; 11366 // Only fetch reusable blocks if we know we need them. To do: maybe 11367 // use the entity record API to retrieve the block by slug. 11368 if (patternName?.startsWith('core/block/')) { 11369 const _id = parseInt(patternName.slice('core/block/'.length), 10); 11370 const block = unlock(select(STORE_NAME)).getReusableBlocks().find(({ 11371 id 11372 }) => id === _id); 11373 if (!block) { 11374 return null; 11375 } 11376 return mapUserPattern(block, state.settings.__experimentalUserPatternCategories); 11377 } 11378 return [ 11379 // This setting is left for back compat. 11380 ...((_state$settings$__exp = state.settings.__experimentalBlockPatterns) !== null && _state$settings$__exp !== void 0 ? _state$settings$__exp : []), ...((_state$settings$selec = state.settings[selectBlockPatternsKey]?.(select)) !== null && _state$settings$selec !== void 0 ? _state$settings$selec : [])].find(({ 11381 name 11382 }) => name === patternName); 11383 }, (state, patternName) => patternName?.startsWith('core/block/') ? [unlock(select(STORE_NAME)).getReusableBlocks(), state.settings.__experimentalReusableBlocks] : [state.settings.__experimentalBlockPatterns, state.settings[selectBlockPatternsKey]?.(select)])); 11384 const getAllPatterns = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)(state => { 11385 var _state$settings$__exp2, _state$settings$selec2; 11386 return [...unlock(select(STORE_NAME)).getReusableBlocks().map(userPattern => mapUserPattern(userPattern, state.settings.__experimentalUserPatternCategories)), 11387 // This setting is left for back compat. 11388 ...((_state$settings$__exp2 = state.settings.__experimentalBlockPatterns) !== null && _state$settings$__exp2 !== void 0 ? _state$settings$__exp2 : []), ...((_state$settings$selec2 = state.settings[selectBlockPatternsKey]?.(select)) !== null && _state$settings$selec2 !== void 0 ? _state$settings$selec2 : [])].filter((x, index, arr) => index === arr.findIndex(y => x.name === y.name)); 11389 }, getAllPatternsDependants(select))); 11390 const EMPTY_ARRAY = []; 11391 const getReusableBlocks = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => state => { 11392 var _ref; 11393 const reusableBlocksSelect = state.settings[reusableBlocksSelectKey]; 11394 return (_ref = reusableBlocksSelect ? reusableBlocksSelect(select) : state.settings.__experimentalReusableBlocks) !== null && _ref !== void 0 ? _ref : EMPTY_ARRAY; 11395 }); 11396 11397 /** 11398 * Returns the element of the last element that had focus when focus left the editor canvas. 11399 * 11400 * @param {Object} state Block editor state. 11401 * 11402 * @return {Object} Element. 11403 */ 11404 function getLastFocus(state) { 11405 return state.lastFocus; 11406 } 11407 11408 /** 11409 * Returns true if the user is dragging anything, or false otherwise. It is possible for a 11410 * user to be dragging data from outside of the editor, so this selector is separate from 11411 * the `isDraggingBlocks` selector which only returns true if the user is dragging blocks. 11412 * 11413 * @param {Object} state Global application state. 11414 * 11415 * @return {boolean} Whether user is dragging. 11416 */ 11417 function private_selectors_isDragging(state) { 11418 return state.isDragging; 11419 } 11420 11421 /** 11422 * Retrieves the expanded block from the state. 11423 * 11424 * @param {Object} state Block editor state. 11425 * 11426 * @return {string|null} The client ID of the expanded block, if set. 11427 */ 11428 function getExpandedBlock(state) { 11429 return state.expandedBlock; 11430 } 11431 11432 /** 11433 * Retrieves the client ID of the ancestor block that is content locking the block 11434 * with the provided client ID. 11435 * 11436 * @param {Object} state Global application state. 11437 * @param {string} clientId Client Id of the block. 11438 * 11439 * @return {?string} Client ID of the ancestor block that is content locking the block. 11440 */ 11441 const getContentLockingParent = (state, clientId) => { 11442 let current = clientId; 11443 let result; 11444 while (!result && (current = state.blocks.parents.get(current))) { 11445 if (getTemplateLock(state, current) === 'contentOnly') { 11446 result = current; 11447 } 11448 } 11449 return result; 11450 }; 11451 11452 /** 11453 * Retrieves the client ID of the parent section block. 11454 * 11455 * @param {Object} state Global application state. 11456 * @param {string} clientId Client Id of the block. 11457 * 11458 * @return {?string} Client ID of the ancestor block that is content locking the block. 11459 */ 11460 const getParentSectionBlock = (state, clientId) => { 11461 let current = clientId; 11462 let result; 11463 while (!result && (current = state.blocks.parents.get(current))) { 11464 if (isSectionBlock(state, current)) { 11465 result = current; 11466 } 11467 } 11468 return result; 11469 }; 11470 11471 /** 11472 * Retrieves the client ID is a content locking parent 11473 * 11474 * @param {Object} state Global application state. 11475 * @param {string} clientId Client Id of the block. 11476 * 11477 * @return {boolean} Whether the block is a content locking parent. 11478 */ 11479 function isSectionBlock(state, clientId) { 11480 const blockName = getBlockName(state, clientId); 11481 if (blockName === 'core/block' || getTemplateLock(state, clientId) === 'contentOnly') { 11482 return true; 11483 } 11484 11485 // Template parts become sections in navigation mode. 11486 const _isNavigationMode = isNavigationMode(state); 11487 if (_isNavigationMode && blockName === 'core/template-part') { 11488 return true; 11489 } 11490 const sectionRootClientId = getSectionRootClientId(state); 11491 const sectionClientIds = getBlockOrder(state, sectionRootClientId); 11492 return _isNavigationMode && sectionClientIds.includes(clientId); 11493 } 11494 11495 /** 11496 * Retrieves the client ID of the block that is content locked but is 11497 * currently being temporarily edited as a non-locked block. 11498 * 11499 * @param {Object} state Global application state. 11500 * 11501 * @return {?string} The client ID of the block being temporarily edited as a non-locked block. 11502 */ 11503 function getTemporarilyEditingAsBlocks(state) { 11504 return state.temporarilyEditingAsBlocks; 11505 } 11506 11507 /** 11508 * Returns the focus mode that should be reapplied when the user stops editing 11509 * a content locked blocks as a block without locking. 11510 * 11511 * @param {Object} state Global application state. 11512 * 11513 * @return {?string} The focus mode that should be re-set when temporarily editing as blocks stops. 11514 */ 11515 function getTemporarilyEditingFocusModeToRevert(state) { 11516 return state.temporarilyEditingFocusModeRevert; 11517 } 11518 11519 /** 11520 * Returns the style attributes of multiple blocks. 11521 * 11522 * @param {Object} state Global application state. 11523 * @param {string[]} clientIds An array of block client IDs. 11524 * 11525 * @return {Object} An object where keys are client IDs and values are the corresponding block styles or undefined. 11526 */ 11527 const getBlockStyles = (0,external_wp_data_namespaceObject.createSelector)((state, clientIds) => clientIds.reduce((styles, clientId) => { 11528 styles[clientId] = state.blocks.attributes.get(clientId)?.style; 11529 return styles; 11530 }, {}), (state, clientIds) => [...clientIds.map(clientId => state.blocks.attributes.get(clientId)?.style)]); 11531 11532 /** 11533 * Retrieves the client ID of the block which contains the blocks 11534 * acting as "sections" in the editor. This is typically the "main content" 11535 * of the template/post. 11536 * 11537 * @param {Object} state Editor state. 11538 * 11539 * @return {string|undefined} The section root client ID or undefined if not set. 11540 */ 11541 function getSectionRootClientId(state) { 11542 return state.settings?.[sectionRootClientIdKey]; 11543 } 11544 11545 /** 11546 * Returns whether the editor is considered zoomed out. 11547 * 11548 * @param {Object} state Global application state. 11549 * @return {boolean} Whether the editor is zoomed. 11550 */ 11551 function isZoomOut(state) { 11552 return state.zoomLevel === 'auto-scaled' || state.zoomLevel < 100; 11553 } 11554 11555 /** 11556 * Returns whether the zoom level. 11557 * 11558 * @param {Object} state Global application state. 11559 * @return {number|"auto-scaled"} Zoom level. 11560 */ 11561 function getZoomLevel(state) { 11562 return state.zoomLevel; 11563 } 11564 11565 /** 11566 * Finds the closest block where the block is allowed to be inserted. 11567 * 11568 * @param {Object} state Editor state. 11569 * @param {string[] | string} name Block name or names. 11570 * @param {string} clientId Default insertion point. 11571 * 11572 * @return {string} clientID of the closest container when the block name can be inserted. 11573 */ 11574 function getClosestAllowedInsertionPoint(state, name, clientId = '') { 11575 const blockNames = Array.isArray(name) ? name : [name]; 11576 const areBlockNamesAllowedInClientId = id => blockNames.every(currentName => canInsertBlockType(state, currentName, id)); 11577 11578 // If we're trying to insert at the root level and it's not allowed 11579 // Try the section root instead. 11580 if (!clientId) { 11581 if (areBlockNamesAllowedInClientId(clientId)) { 11582 return clientId; 11583 } 11584 const sectionRootClientId = getSectionRootClientId(state); 11585 if (sectionRootClientId && areBlockNamesAllowedInClientId(sectionRootClientId)) { 11586 return sectionRootClientId; 11587 } 11588 return null; 11589 } 11590 11591 // Traverse the block tree up until we find a place where we can insert. 11592 let current = clientId; 11593 while (current !== null && !areBlockNamesAllowedInClientId(current)) { 11594 const parentClientId = getBlockRootClientId(state, current); 11595 current = parentClientId; 11596 } 11597 return current; 11598 } 11599 function getClosestAllowedInsertionPointForPattern(state, pattern, clientId) { 11600 const { 11601 allowedBlockTypes 11602 } = getSettings(state); 11603 const isAllowed = checkAllowListRecursive(getGrammar(pattern), allowedBlockTypes); 11604 if (!isAllowed) { 11605 return null; 11606 } 11607 const names = getGrammar(pattern).map(({ 11608 blockName: name 11609 }) => name); 11610 return getClosestAllowedInsertionPoint(state, names, clientId); 11611 } 11612 11613 /** 11614 * Where the point where the next block will be inserted into. 11615 * 11616 * @param {Object} state 11617 * @return {Object} where the insertion point in the block editor is or null if none is set. 11618 */ 11619 function getInsertionPoint(state) { 11620 return state.insertionPoint; 11621 } 11622 11623 ;// ./node_modules/@wordpress/block-editor/build-module/store/utils.js 11624 /** 11625 * WordPress dependencies 11626 */ 11627 11628 11629 11630 /** 11631 * Internal dependencies 11632 */ 11633 11634 11635 11636 11637 const isFiltered = Symbol('isFiltered'); 11638 const parsedPatternCache = new WeakMap(); 11639 const grammarMapCache = new WeakMap(); 11640 function parsePattern(pattern) { 11641 const blocks = (0,external_wp_blocks_namespaceObject.parse)(pattern.content, { 11642 __unstableSkipMigrationLogs: true 11643 }); 11644 if (blocks.length === 1) { 11645 blocks[0].attributes = { 11646 ...blocks[0].attributes, 11647 metadata: { 11648 ...(blocks[0].attributes.metadata || {}), 11649 categories: pattern.categories, 11650 patternName: pattern.name, 11651 name: blocks[0].attributes.metadata?.name || pattern.title 11652 } 11653 }; 11654 } 11655 return { 11656 ...pattern, 11657 blocks 11658 }; 11659 } 11660 function getParsedPattern(pattern) { 11661 let parsedPattern = parsedPatternCache.get(pattern); 11662 if (!parsedPattern) { 11663 parsedPattern = parsePattern(pattern); 11664 parsedPatternCache.set(pattern, parsedPattern); 11665 } 11666 return parsedPattern; 11667 } 11668 function getGrammar(pattern) { 11669 let grammarMap = grammarMapCache.get(pattern); 11670 if (!grammarMap) { 11671 grammarMap = (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(pattern.content); 11672 // Block names are null only at the top level for whitespace. 11673 grammarMap = grammarMap.filter(block => block.blockName !== null); 11674 grammarMapCache.set(pattern, grammarMap); 11675 } 11676 return grammarMap; 11677 } 11678 const checkAllowList = (list, item, defaultResult = null) => { 11679 if (typeof list === 'boolean') { 11680 return list; 11681 } 11682 if (Array.isArray(list)) { 11683 // TODO: when there is a canonical way to detect that we are editing a post 11684 // the following check should be changed to something like: 11685 // if ( list.includes( 'core/post-content' ) && getEditorMode() === 'post-content' && item === null ) 11686 if (list.includes('core/post-content') && item === null) { 11687 return true; 11688 } 11689 return list.includes(item); 11690 } 11691 return defaultResult; 11692 }; 11693 const checkAllowListRecursive = (blocks, allowedBlockTypes) => { 11694 if (typeof allowedBlockTypes === 'boolean') { 11695 return allowedBlockTypes; 11696 } 11697 const blocksQueue = [...blocks]; 11698 while (blocksQueue.length > 0) { 11699 const block = blocksQueue.shift(); 11700 const isAllowed = checkAllowList(allowedBlockTypes, block.name || block.blockName, true); 11701 if (!isAllowed) { 11702 return false; 11703 } 11704 block.innerBlocks?.forEach(innerBlock => { 11705 blocksQueue.push(innerBlock); 11706 }); 11707 } 11708 return true; 11709 }; 11710 const getAllPatternsDependants = select => state => { 11711 return [state.settings.__experimentalBlockPatterns, state.settings.__experimentalUserPatternCategories, state.settings.__experimentalReusableBlocks, state.settings[selectBlockPatternsKey]?.(select), state.blockPatterns, unlock(select(STORE_NAME)).getReusableBlocks()]; 11712 }; 11713 const getInsertBlockTypeDependants = select => (state, rootClientId) => { 11714 return [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.settings.allowedBlockTypes, state.settings.templateLock, state.blockEditingModes, select(STORE_NAME).__unstableGetEditorMode(state), getSectionRootClientId(state)]; 11715 }; 11716 11717 ;// ./node_modules/@wordpress/block-editor/build-module/utils/sorting.js 11718 /** 11719 * Recursive stable sorting comparator function. 11720 * 11721 * @param {string|Function} field Field to sort by. 11722 * @param {Array} items Items to sort. 11723 * @param {string} order Order, 'asc' or 'desc'. 11724 * @return {Function} Comparison function to be used in a `.sort()`. 11725 */ 11726 const comparator = (field, items, order) => { 11727 return (a, b) => { 11728 let cmpA, cmpB; 11729 if (typeof field === 'function') { 11730 cmpA = field(a); 11731 cmpB = field(b); 11732 } else { 11733 cmpA = a[field]; 11734 cmpB = b[field]; 11735 } 11736 if (cmpA > cmpB) { 11737 return order === 'asc' ? 1 : -1; 11738 } else if (cmpB > cmpA) { 11739 return order === 'asc' ? -1 : 1; 11740 } 11741 const orderA = items.findIndex(item => item === a); 11742 const orderB = items.findIndex(item => item === b); 11743 11744 // Stable sort: maintaining original array order 11745 if (orderA > orderB) { 11746 return 1; 11747 } else if (orderB > orderA) { 11748 return -1; 11749 } 11750 return 0; 11751 }; 11752 }; 11753 11754 /** 11755 * Order items by a certain key. 11756 * Supports decorator functions that allow complex picking of a comparison field. 11757 * Sorts in ascending order by default, but supports descending as well. 11758 * Stable sort - maintains original order of equal items. 11759 * 11760 * @param {Array} items Items to order. 11761 * @param {string|Function} field Field to order by. 11762 * @param {string} order Sorting order, `asc` or `desc`. 11763 * @return {Array} Sorted items. 11764 */ 11765 function orderBy(items, field, order = 'asc') { 11766 return items.concat().sort(comparator(field, items, order)); 11767 } 11768 11769 ;// ./node_modules/@wordpress/block-editor/build-module/store/selectors.js 11770 /** 11771 * WordPress dependencies 11772 */ 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 /** 11783 * Internal dependencies 11784 */ 11785 11786 11787 11788 11789 11790 11791 /** 11792 * A block selection object. 11793 * 11794 * @typedef {Object} WPBlockSelection 11795 * 11796 * @property {string} clientId A block client ID. 11797 * @property {string} attributeKey A block attribute key. 11798 * @property {number} offset An attribute value offset, based on the rich 11799 * text value. See `wp.richText.create`. 11800 */ 11801 11802 // Module constants. 11803 const MILLISECONDS_PER_HOUR = 3600 * 1000; 11804 const MILLISECONDS_PER_DAY = 24 * 3600 * 1000; 11805 const MILLISECONDS_PER_WEEK = 7 * 24 * 3600 * 1000; 11806 11807 /** 11808 * Shared reference to an empty array for cases where it is important to avoid 11809 * returning a new array reference on every invocation, as in a connected or 11810 * other pure component which performs `shouldComponentUpdate` check on props. 11811 * This should be used as a last resort, since the normalized data should be 11812 * maintained by the reducer result in state. 11813 * 11814 * @type {Array} 11815 */ 11816 const selectors_EMPTY_ARRAY = []; 11817 11818 /** 11819 * Shared reference to an empty Set for cases where it is important to avoid 11820 * returning a new Set reference on every invocation, as in a connected or 11821 * other pure component which performs `shouldComponentUpdate` check on props. 11822 * This should be used as a last resort, since the normalized data should be 11823 * maintained by the reducer result in state. 11824 * 11825 * @type {Set} 11826 */ 11827 const EMPTY_SET = new Set(); 11828 const DEFAULT_INSERTER_OPTIONS = { 11829 [isFiltered]: true 11830 }; 11831 11832 /** 11833 * Returns a block's name given its client ID, or null if no block exists with 11834 * the client ID. 11835 * 11836 * @param {Object} state Editor state. 11837 * @param {string} clientId Block client ID. 11838 * 11839 * @return {string} Block name. 11840 */ 11841 function getBlockName(state, clientId) { 11842 const block = state.blocks.byClientId.get(clientId); 11843 const socialLinkName = 'core/social-link'; 11844 if (external_wp_element_namespaceObject.Platform.OS !== 'web' && block?.name === socialLinkName) { 11845 const attributes = state.blocks.attributes.get(clientId); 11846 const { 11847 service 11848 } = attributes !== null && attributes !== void 0 ? attributes : {}; 11849 return service ? `$socialLinkName}-$service}` : socialLinkName; 11850 } 11851 return block ? block.name : null; 11852 } 11853 11854 /** 11855 * Returns whether a block is valid or not. 11856 * 11857 * @param {Object} state Editor state. 11858 * @param {string} clientId Block client ID. 11859 * 11860 * @return {boolean} Is Valid. 11861 */ 11862 function isBlockValid(state, clientId) { 11863 const block = state.blocks.byClientId.get(clientId); 11864 return !!block && block.isValid; 11865 } 11866 11867 /** 11868 * Returns a block's attributes given its client ID, or null if no block exists with 11869 * the client ID. 11870 * 11871 * @param {Object} state Editor state. 11872 * @param {string} clientId Block client ID. 11873 * 11874 * @return {?Object} Block attributes. 11875 */ 11876 function getBlockAttributes(state, clientId) { 11877 const block = state.blocks.byClientId.get(clientId); 11878 if (!block) { 11879 return null; 11880 } 11881 return state.blocks.attributes.get(clientId); 11882 } 11883 11884 /** 11885 * Returns a block given its client ID. This is a parsed copy of the block, 11886 * containing its `blockName`, `clientId`, and current `attributes` state. This 11887 * is not the block's registration settings, which must be retrieved from the 11888 * blocks module registration store. 11889 * 11890 * getBlock recurses through its inner blocks until all its children blocks have 11891 * been retrieved. Note that getBlock will not return the child inner blocks of 11892 * an inner block controller. This is because an inner block controller syncs 11893 * itself with its own entity, and should therefore not be included with the 11894 * blocks of a different entity. For example, say you call `getBlocks( TP )` to 11895 * get the blocks of a template part. If another template part is a child of TP, 11896 * then the nested template part's child blocks will not be returned. This way, 11897 * the template block itself is considered part of the parent, but the children 11898 * are not. 11899 * 11900 * @param {Object} state Editor state. 11901 * @param {string} clientId Block client ID. 11902 * 11903 * @return {Object} Parsed block object. 11904 */ 11905 function getBlock(state, clientId) { 11906 if (!state.blocks.byClientId.has(clientId)) { 11907 return null; 11908 } 11909 return state.blocks.tree.get(clientId); 11910 } 11911 const __unstableGetBlockWithoutInnerBlocks = (0,external_wp_data_namespaceObject.createSelector)((state, clientId) => { 11912 const block = state.blocks.byClientId.get(clientId); 11913 if (!block) { 11914 return null; 11915 } 11916 return { 11917 ...block, 11918 attributes: getBlockAttributes(state, clientId) 11919 }; 11920 }, (state, clientId) => [state.blocks.byClientId.get(clientId), state.blocks.attributes.get(clientId)]); 11921 11922 /** 11923 * Returns all block objects for the current post being edited as an array in 11924 * the order they appear in the post. Note that this will exclude child blocks 11925 * of nested inner block controllers. 11926 * 11927 * @param {Object} state Editor state. 11928 * @param {?string} rootClientId Optional root client ID of block list. 11929 * 11930 * @return {Object[]} Post blocks. 11931 */ 11932 function getBlocks(state, rootClientId) { 11933 const treeKey = !rootClientId || !areInnerBlocksControlled(state, rootClientId) ? rootClientId || '' : 'controlled||' + rootClientId; 11934 return state.blocks.tree.get(treeKey)?.innerBlocks || selectors_EMPTY_ARRAY; 11935 } 11936 11937 /** 11938 * Returns a stripped down block object containing only its client ID, 11939 * and its inner blocks' client IDs. 11940 * 11941 * @deprecated 11942 * 11943 * @param {Object} state Editor state. 11944 * @param {string} clientId Client ID of the block to get. 11945 * 11946 * @return {Object} Client IDs of the post blocks. 11947 */ 11948 const __unstableGetClientIdWithClientIdsTree = (0,external_wp_data_namespaceObject.createSelector)((state, clientId) => { 11949 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetClientIdWithClientIdsTree", { 11950 since: '6.3', 11951 version: '6.5' 11952 }); 11953 return { 11954 clientId, 11955 innerBlocks: __unstableGetClientIdsTree(state, clientId) 11956 }; 11957 }, state => [state.blocks.order]); 11958 11959 /** 11960 * Returns the block tree represented in the block-editor store from the 11961 * given root, consisting of stripped down block objects containing only 11962 * their client IDs, and their inner blocks' client IDs. 11963 * 11964 * @deprecated 11965 * 11966 * @param {Object} state Editor state. 11967 * @param {?string} rootClientId Optional root client ID of block list. 11968 * 11969 * @return {Object[]} Client IDs of the post blocks. 11970 */ 11971 const __unstableGetClientIdsTree = (0,external_wp_data_namespaceObject.createSelector)((state, rootClientId = '') => { 11972 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetClientIdsTree", { 11973 since: '6.3', 11974 version: '6.5' 11975 }); 11976 return getBlockOrder(state, rootClientId).map(clientId => __unstableGetClientIdWithClientIdsTree(state, clientId)); 11977 }, state => [state.blocks.order]); 11978 11979 /** 11980 * Returns an array containing the clientIds of all descendants of the blocks 11981 * given. Returned ids are ordered first by the order of the ids given, then 11982 * by the order that they appear in the editor. 11983 * 11984 * @param {Object} state Global application state. 11985 * @param {string|string[]} rootIds Client ID(s) for which descendant blocks are to be returned. 11986 * 11987 * @return {Array} Client IDs of descendants. 11988 */ 11989 const getClientIdsOfDescendants = (0,external_wp_data_namespaceObject.createSelector)((state, rootIds) => { 11990 rootIds = Array.isArray(rootIds) ? [...rootIds] : [rootIds]; 11991 const ids = []; 11992 11993 // Add the descendants of the root blocks first. 11994 for (const rootId of rootIds) { 11995 const order = state.blocks.order.get(rootId); 11996 if (order) { 11997 ids.push(...order); 11998 } 11999 } 12000 let index = 0; 12001 12002 // Add the descendants of the descendants, recursively. 12003 while (index < ids.length) { 12004 const id = ids[index]; 12005 const order = state.blocks.order.get(id); 12006 if (order) { 12007 ids.splice(index + 1, 0, ...order); 12008 } 12009 index++; 12010 } 12011 return ids; 12012 }, state => [state.blocks.order]); 12013 12014 /** 12015 * Returns an array containing the clientIds of the top-level blocks and 12016 * their descendants of any depth (for nested blocks). Ids are returned 12017 * in the same order that they appear in the editor. 12018 * 12019 * @param {Object} state Global application state. 12020 * 12021 * @return {Array} ids of top-level and descendant blocks. 12022 */ 12023 const getClientIdsWithDescendants = state => getClientIdsOfDescendants(state, ''); 12024 12025 /** 12026 * Returns the total number of blocks, or the total number of blocks with a specific name in a post. 12027 * The number returned includes nested blocks. 12028 * 12029 * @param {Object} state Global application state. 12030 * @param {?string} blockName Optional block name, if specified only blocks of that type will be counted. 12031 * 12032 * @return {number} Number of blocks in the post, or number of blocks with name equal to blockName. 12033 */ 12034 const getGlobalBlockCount = (0,external_wp_data_namespaceObject.createSelector)((state, blockName) => { 12035 const clientIds = getClientIdsWithDescendants(state); 12036 if (!blockName) { 12037 return clientIds.length; 12038 } 12039 let count = 0; 12040 for (const clientId of clientIds) { 12041 const block = state.blocks.byClientId.get(clientId); 12042 if (block.name === blockName) { 12043 count++; 12044 } 12045 } 12046 return count; 12047 }, state => [state.blocks.order, state.blocks.byClientId]); 12048 12049 /** 12050 * Returns all blocks that match a blockName. Results include nested blocks. 12051 * 12052 * @param {Object} state Global application state. 12053 * @param {string[]} blockName Block name(s) for which clientIds are to be returned. 12054 * 12055 * @return {Array} Array of clientIds of blocks with name equal to blockName. 12056 */ 12057 const getBlocksByName = (0,external_wp_data_namespaceObject.createSelector)((state, blockName) => { 12058 if (!blockName) { 12059 return selectors_EMPTY_ARRAY; 12060 } 12061 const blockNames = Array.isArray(blockName) ? blockName : [blockName]; 12062 const clientIds = getClientIdsWithDescendants(state); 12063 const foundBlocks = clientIds.filter(clientId => { 12064 const block = state.blocks.byClientId.get(clientId); 12065 return blockNames.includes(block.name); 12066 }); 12067 return foundBlocks.length > 0 ? foundBlocks : selectors_EMPTY_ARRAY; 12068 }, state => [state.blocks.order, state.blocks.byClientId]); 12069 12070 /** 12071 * Returns all global blocks that match a blockName. Results include nested blocks. 12072 * 12073 * @deprecated 12074 * 12075 * @param {Object} state Global application state. 12076 * @param {string[]} blockName Block name(s) for which clientIds are to be returned. 12077 * 12078 * @return {Array} Array of clientIds of blocks with name equal to blockName. 12079 */ 12080 function __experimentalGetGlobalBlocksByName(state, blockName) { 12081 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__experimentalGetGlobalBlocksByName", { 12082 since: '6.5', 12083 alternative: `wp.data.select( 'core/block-editor' ).getBlocksByName` 12084 }); 12085 return getBlocksByName(state, blockName); 12086 } 12087 12088 /** 12089 * Given an array of block client IDs, returns the corresponding array of block 12090 * objects. 12091 * 12092 * @param {Object} state Editor state. 12093 * @param {string[]} clientIds Client IDs for which blocks are to be returned. 12094 * 12095 * @return {WPBlock[]} Block objects. 12096 */ 12097 const getBlocksByClientId = (0,external_wp_data_namespaceObject.createSelector)((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))); 12098 12099 /** 12100 * Given an array of block client IDs, returns the corresponding array of block 12101 * names. 12102 * 12103 * @param {Object} state Editor state. 12104 * @param {string[]} clientIds Client IDs for which block names are to be returned. 12105 * 12106 * @return {string[]} Block names. 12107 */ 12108 const getBlockNamesByClientId = (0,external_wp_data_namespaceObject.createSelector)((state, clientIds) => getBlocksByClientId(state, clientIds).filter(Boolean).map(block => block.name), (state, clientIds) => getBlocksByClientId(state, clientIds)); 12109 12110 /** 12111 * Returns the number of blocks currently present in the post. 12112 * 12113 * @param {Object} state Editor state. 12114 * @param {?string} rootClientId Optional root client ID of block list. 12115 * 12116 * @return {number} Number of blocks in the post. 12117 */ 12118 function getBlockCount(state, rootClientId) { 12119 return getBlockOrder(state, rootClientId).length; 12120 } 12121 12122 /** 12123 * Returns the current selection start block client ID, attribute key and text 12124 * offset. 12125 * 12126 * @param {Object} state Block editor state. 12127 * 12128 * @return {WPBlockSelection} Selection start information. 12129 */ 12130 function getSelectionStart(state) { 12131 return state.selection.selectionStart; 12132 } 12133 12134 /** 12135 * Returns the current selection end block client ID, attribute key and text 12136 * offset. 12137 * 12138 * @param {Object} state Block editor state. 12139 * 12140 * @return {WPBlockSelection} Selection end information. 12141 */ 12142 function getSelectionEnd(state) { 12143 return state.selection.selectionEnd; 12144 } 12145 12146 /** 12147 * Returns the current block selection start. This value may be null, and it 12148 * may represent either a singular block selection or multi-selection start. 12149 * A selection is singular if its start and end match. 12150 * 12151 * @param {Object} state Global application state. 12152 * 12153 * @return {?string} Client ID of block selection start. 12154 */ 12155 function getBlockSelectionStart(state) { 12156 return state.selection.selectionStart.clientId; 12157 } 12158 12159 /** 12160 * Returns the current block selection end. This value may be null, and it 12161 * may represent either a singular block selection or multi-selection end. 12162 * A selection is singular if its start and end match. 12163 * 12164 * @param {Object} state Global application state. 12165 * 12166 * @return {?string} Client ID of block selection end. 12167 */ 12168 function getBlockSelectionEnd(state) { 12169 return state.selection.selectionEnd.clientId; 12170 } 12171 12172 /** 12173 * Returns the number of blocks currently selected in the post. 12174 * 12175 * @param {Object} state Global application state. 12176 * 12177 * @return {number} Number of blocks selected in the post. 12178 */ 12179 function getSelectedBlockCount(state) { 12180 const multiSelectedBlockCount = getMultiSelectedBlockClientIds(state).length; 12181 if (multiSelectedBlockCount) { 12182 return multiSelectedBlockCount; 12183 } 12184 return state.selection.selectionStart.clientId ? 1 : 0; 12185 } 12186 12187 /** 12188 * Returns true if there is a single selected block, or false otherwise. 12189 * 12190 * @param {Object} state Editor state. 12191 * 12192 * @return {boolean} Whether a single block is selected. 12193 */ 12194 function hasSelectedBlock(state) { 12195 const { 12196 selectionStart, 12197 selectionEnd 12198 } = state.selection; 12199 return !!selectionStart.clientId && selectionStart.clientId === selectionEnd.clientId; 12200 } 12201 12202 /** 12203 * Returns the currently selected block client ID, or null if there is no 12204 * selected block. 12205 * 12206 * @param {Object} state Editor state. 12207 * 12208 * @return {?string} Selected block client ID. 12209 */ 12210 function getSelectedBlockClientId(state) { 12211 const { 12212 selectionStart, 12213 selectionEnd 12214 } = state.selection; 12215 const { 12216 clientId 12217 } = selectionStart; 12218 if (!clientId || clientId !== selectionEnd.clientId) { 12219 return null; 12220 } 12221 return clientId; 12222 } 12223 12224 /** 12225 * Returns the currently selected block, or null if there is no selected block. 12226 * 12227 * @param {Object} state Global application state. 12228 * 12229 * @example 12230 * 12231 *```js 12232 * import { select } from '@wordpress/data' 12233 * import { store as blockEditorStore } from '@wordpress/block-editor' 12234 * 12235 * // Set initial active block client ID 12236 * let activeBlockClientId = null 12237 * 12238 * const getActiveBlockData = () => { 12239 * const activeBlock = select(blockEditorStore).getSelectedBlock() 12240 * 12241 * if (activeBlock && activeBlock.clientId !== activeBlockClientId) { 12242 * activeBlockClientId = activeBlock.clientId 12243 * 12244 * // Get active block name and attributes 12245 * const activeBlockName = activeBlock.name 12246 * const activeBlockAttributes = activeBlock.attributes 12247 * 12248 * // Log active block name and attributes 12249 * console.log(activeBlockName, activeBlockAttributes) 12250 * } 12251 * } 12252 * 12253 * // Subscribe to changes in the editor 12254 * // wp.data.subscribe(() => { 12255 * // getActiveBlockData() 12256 * // }) 12257 * 12258 * // Update active block data on click 12259 * // onclick="getActiveBlockData()" 12260 *``` 12261 * 12262 * @return {?Object} Selected block. 12263 */ 12264 function getSelectedBlock(state) { 12265 const clientId = getSelectedBlockClientId(state); 12266 return clientId ? getBlock(state, clientId) : null; 12267 } 12268 12269 /** 12270 * Given a block client ID, returns the root block from which the block is 12271 * nested, an empty string for top-level blocks, or null if the block does not 12272 * exist. 12273 * 12274 * @param {Object} state Editor state. 12275 * @param {string} clientId Block from which to find root client ID. 12276 * 12277 * @return {?string} Root client ID, if exists 12278 */ 12279 function getBlockRootClientId(state, clientId) { 12280 var _state$blocks$parents; 12281 return (_state$blocks$parents = state.blocks.parents.get(clientId)) !== null && _state$blocks$parents !== void 0 ? _state$blocks$parents : null; 12282 } 12283 12284 /** 12285 * Given a block client ID, returns the list of all its parents from top to bottom. 12286 * 12287 * @param {Object} state Editor state. 12288 * @param {string} clientId Block from which to find root client ID. 12289 * @param {boolean} ascending Order results from bottom to top (true) or top to bottom (false). 12290 * 12291 * @return {Array} ClientIDs of the parent blocks. 12292 */ 12293 const getBlockParents = (0,external_wp_data_namespaceObject.createSelector)((state, clientId, ascending = false) => { 12294 const parents = []; 12295 let current = clientId; 12296 while (current = state.blocks.parents.get(current)) { 12297 parents.push(current); 12298 } 12299 if (!parents.length) { 12300 return selectors_EMPTY_ARRAY; 12301 } 12302 return ascending ? parents : parents.reverse(); 12303 }, state => [state.blocks.parents]); 12304 12305 /** 12306 * Given a block client ID and a block name, returns the list of all its parents 12307 * from top to bottom, filtered by the given name(s). For example, if passed 12308 * 'core/group' as the blockName, it will only return parents which are group 12309 * blocks. If passed `[ 'core/group', 'core/cover']`, as the blockName, it will 12310 * return parents which are group blocks and parents which are cover blocks. 12311 * 12312 * @param {Object} state Editor state. 12313 * @param {string} clientId Block from which to find root client ID. 12314 * @param {string|string[]} blockName Block name(s) to filter. 12315 * @param {boolean} ascending Order results from bottom to top (true) or top to bottom (false). 12316 * 12317 * @return {Array} ClientIDs of the parent blocks. 12318 */ 12319 const getBlockParentsByBlockName = (0,external_wp_data_namespaceObject.createSelector)((state, clientId, blockName, ascending = false) => { 12320 const parents = getBlockParents(state, clientId, ascending); 12321 const hasName = Array.isArray(blockName) ? name => blockName.includes(name) : name => blockName === name; 12322 return parents.filter(id => hasName(getBlockName(state, id))); 12323 }, state => [state.blocks.parents]); 12324 /** 12325 * 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. 12326 * 12327 * @param {Object} state Editor state. 12328 * @param {string} clientId Block from which to find root client ID. 12329 * 12330 * @return {string} Root client ID 12331 */ 12332 function getBlockHierarchyRootClientId(state, clientId) { 12333 let current = clientId; 12334 let parent; 12335 do { 12336 parent = current; 12337 current = state.blocks.parents.get(current); 12338 } while (current); 12339 return parent; 12340 } 12341 12342 /** 12343 * Given a block client ID, returns the lowest common ancestor with selected client ID. 12344 * 12345 * @param {Object} state Editor state. 12346 * @param {string} clientId Block from which to find common ancestor client ID. 12347 * 12348 * @return {string} Common ancestor client ID or undefined 12349 */ 12350 function getLowestCommonAncestorWithSelectedBlock(state, clientId) { 12351 const selectedId = getSelectedBlockClientId(state); 12352 const clientParents = [...getBlockParents(state, clientId), clientId]; 12353 const selectedParents = [...getBlockParents(state, selectedId), selectedId]; 12354 let lowestCommonAncestor; 12355 const maxDepth = Math.min(clientParents.length, selectedParents.length); 12356 for (let index = 0; index < maxDepth; index++) { 12357 if (clientParents[index] === selectedParents[index]) { 12358 lowestCommonAncestor = clientParents[index]; 12359 } else { 12360 break; 12361 } 12362 } 12363 return lowestCommonAncestor; 12364 } 12365 12366 /** 12367 * Returns the client ID of the block adjacent one at the given reference 12368 * startClientId and modifier directionality. Defaults start startClientId to 12369 * the selected block, and direction as next block. Returns null if there is no 12370 * adjacent block. 12371 * 12372 * @param {Object} state Editor state. 12373 * @param {?string} startClientId Optional client ID of block from which to 12374 * search. 12375 * @param {?number} modifier Directionality multiplier (1 next, -1 12376 * previous). 12377 * 12378 * @return {?string} Return the client ID of the block, or null if none exists. 12379 */ 12380 function getAdjacentBlockClientId(state, startClientId, modifier = 1) { 12381 // Default to selected block. 12382 if (startClientId === undefined) { 12383 startClientId = getSelectedBlockClientId(state); 12384 } 12385 12386 // Try multi-selection starting at extent based on modifier. 12387 if (startClientId === undefined) { 12388 if (modifier < 0) { 12389 startClientId = getFirstMultiSelectedBlockClientId(state); 12390 } else { 12391 startClientId = getLastMultiSelectedBlockClientId(state); 12392 } 12393 } 12394 12395 // Validate working start client ID. 12396 if (!startClientId) { 12397 return null; 12398 } 12399 12400 // Retrieve start block root client ID, being careful to allow the falsey 12401 // empty string top-level root by explicitly testing against null. 12402 const rootClientId = getBlockRootClientId(state, startClientId); 12403 if (rootClientId === null) { 12404 return null; 12405 } 12406 const { 12407 order 12408 } = state.blocks; 12409 const orderSet = order.get(rootClientId); 12410 const index = orderSet.indexOf(startClientId); 12411 const nextIndex = index + 1 * modifier; 12412 12413 // Block was first in set and we're attempting to get previous. 12414 if (nextIndex < 0) { 12415 return null; 12416 } 12417 12418 // Block was last in set and we're attempting to get next. 12419 if (nextIndex === orderSet.length) { 12420 return null; 12421 } 12422 12423 // Assume incremented index is within the set. 12424 return orderSet[nextIndex]; 12425 } 12426 12427 /** 12428 * Returns the previous block's client ID from the given reference start ID. 12429 * Defaults start to the selected block. Returns null if there is no previous 12430 * block. 12431 * 12432 * @param {Object} state Editor state. 12433 * @param {?string} startClientId Optional client ID of block from which to 12434 * search. 12435 * 12436 * @return {?string} Adjacent block's client ID, or null if none exists. 12437 */ 12438 function getPreviousBlockClientId(state, startClientId) { 12439 return getAdjacentBlockClientId(state, startClientId, -1); 12440 } 12441 12442 /** 12443 * Returns the next block's client ID from the given reference start ID. 12444 * Defaults start to the selected block. Returns null if there is no next 12445 * block. 12446 * 12447 * @param {Object} state Editor state. 12448 * @param {?string} startClientId Optional client ID of block from which to 12449 * search. 12450 * 12451 * @return {?string} Adjacent block's client ID, or null if none exists. 12452 */ 12453 function getNextBlockClientId(state, startClientId) { 12454 return getAdjacentBlockClientId(state, startClientId, 1); 12455 } 12456 12457 /* eslint-disable jsdoc/valid-types */ 12458 /** 12459 * Returns the initial caret position for the selected block. 12460 * This position is to used to position the caret properly when the selected block changes. 12461 * If the current block is not a RichText, having initial position set to 0 means "focus block" 12462 * 12463 * @param {Object} state Global application state. 12464 * 12465 * @return {0|-1|null} Initial position. 12466 */ 12467 function getSelectedBlocksInitialCaretPosition(state) { 12468 /* eslint-enable jsdoc/valid-types */ 12469 return state.initialPosition; 12470 } 12471 12472 /** 12473 * Returns the current selection set of block client IDs (multiselection or single selection). 12474 * 12475 * @param {Object} state Editor state. 12476 * 12477 * @return {Array} Multi-selected block client IDs. 12478 */ 12479 const getSelectedBlockClientIds = (0,external_wp_data_namespaceObject.createSelector)(state => { 12480 const { 12481 selectionStart, 12482 selectionEnd 12483 } = state.selection; 12484 if (!selectionStart.clientId || !selectionEnd.clientId) { 12485 return selectors_EMPTY_ARRAY; 12486 } 12487 if (selectionStart.clientId === selectionEnd.clientId) { 12488 return [selectionStart.clientId]; 12489 } 12490 12491 // Retrieve root client ID to aid in retrieving relevant nested block 12492 // order, being careful to allow the falsey empty string top-level root 12493 // by explicitly testing against null. 12494 const rootClientId = getBlockRootClientId(state, selectionStart.clientId); 12495 if (rootClientId === null) { 12496 return selectors_EMPTY_ARRAY; 12497 } 12498 const blockOrder = getBlockOrder(state, rootClientId); 12499 const startIndex = blockOrder.indexOf(selectionStart.clientId); 12500 const endIndex = blockOrder.indexOf(selectionEnd.clientId); 12501 if (startIndex > endIndex) { 12502 return blockOrder.slice(endIndex, startIndex + 1); 12503 } 12504 return blockOrder.slice(startIndex, endIndex + 1); 12505 }, state => [state.blocks.order, state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId]); 12506 12507 /** 12508 * Returns the current multi-selection set of block client IDs, or an empty 12509 * array if there is no multi-selection. 12510 * 12511 * @param {Object} state Editor state. 12512 * 12513 * @return {Array} Multi-selected block client IDs. 12514 */ 12515 function getMultiSelectedBlockClientIds(state) { 12516 const { 12517 selectionStart, 12518 selectionEnd 12519 } = state.selection; 12520 if (selectionStart.clientId === selectionEnd.clientId) { 12521 return selectors_EMPTY_ARRAY; 12522 } 12523 return getSelectedBlockClientIds(state); 12524 } 12525 12526 /** 12527 * Returns the current multi-selection set of blocks, or an empty array if 12528 * there is no multi-selection. 12529 * 12530 * @param {Object} state Editor state. 12531 * 12532 * @return {Array} Multi-selected block objects. 12533 */ 12534 const getMultiSelectedBlocks = (0,external_wp_data_namespaceObject.createSelector)(state => { 12535 const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(state); 12536 if (!multiSelectedBlockClientIds.length) { 12537 return selectors_EMPTY_ARRAY; 12538 } 12539 return multiSelectedBlockClientIds.map(clientId => getBlock(state, clientId)); 12540 }, state => [...getSelectedBlockClientIds.getDependants(state), state.blocks.byClientId, state.blocks.order, state.blocks.attributes]); 12541 12542 /** 12543 * Returns the client ID of the first block in the multi-selection set, or null 12544 * if there is no multi-selection. 12545 * 12546 * @param {Object} state Editor state. 12547 * 12548 * @return {?string} First block client ID in the multi-selection set. 12549 */ 12550 function getFirstMultiSelectedBlockClientId(state) { 12551 return getMultiSelectedBlockClientIds(state)[0] || null; 12552 } 12553 12554 /** 12555 * Returns the client ID of the last block in the multi-selection set, or null 12556 * if there is no multi-selection. 12557 * 12558 * @param {Object} state Editor state. 12559 * 12560 * @return {?string} Last block client ID in the multi-selection set. 12561 */ 12562 function getLastMultiSelectedBlockClientId(state) { 12563 const selectedClientIds = getMultiSelectedBlockClientIds(state); 12564 return selectedClientIds[selectedClientIds.length - 1] || null; 12565 } 12566 12567 /** 12568 * Returns true if a multi-selection exists, and the block corresponding to the 12569 * specified client ID is the first block of the multi-selection set, or false 12570 * otherwise. 12571 * 12572 * @param {Object} state Editor state. 12573 * @param {string} clientId Block client ID. 12574 * 12575 * @return {boolean} Whether block is first in multi-selection. 12576 */ 12577 function isFirstMultiSelectedBlock(state, clientId) { 12578 return getFirstMultiSelectedBlockClientId(state) === clientId; 12579 } 12580 12581 /** 12582 * Returns true if the client ID occurs within the block multi-selection, or 12583 * false otherwise. 12584 * 12585 * @param {Object} state Editor state. 12586 * @param {string} clientId Block client ID. 12587 * 12588 * @return {boolean} Whether block is in multi-selection set. 12589 */ 12590 function isBlockMultiSelected(state, clientId) { 12591 return getMultiSelectedBlockClientIds(state).indexOf(clientId) !== -1; 12592 } 12593 12594 /** 12595 * Returns true if an ancestor of the block is multi-selected, or false 12596 * otherwise. 12597 * 12598 * @param {Object} state Editor state. 12599 * @param {string} clientId Block client ID. 12600 * 12601 * @return {boolean} Whether an ancestor of the block is in multi-selection 12602 * set. 12603 */ 12604 const isAncestorMultiSelected = (0,external_wp_data_namespaceObject.createSelector)((state, clientId) => { 12605 let ancestorClientId = clientId; 12606 let isMultiSelected = false; 12607 while (ancestorClientId && !isMultiSelected) { 12608 ancestorClientId = getBlockRootClientId(state, ancestorClientId); 12609 isMultiSelected = isBlockMultiSelected(state, ancestorClientId); 12610 } 12611 return isMultiSelected; 12612 }, state => [state.blocks.order, state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId]); 12613 12614 /** 12615 * Returns the client ID of the block which begins the multi-selection set, or 12616 * null if there is no multi-selection. 12617 * 12618 * This is not necessarily the first client ID in the selection. 12619 * 12620 * @see getFirstMultiSelectedBlockClientId 12621 * 12622 * @param {Object} state Editor state. 12623 * 12624 * @return {?string} Client ID of block beginning multi-selection. 12625 */ 12626 function getMultiSelectedBlocksStartClientId(state) { 12627 const { 12628 selectionStart, 12629 selectionEnd 12630 } = state.selection; 12631 if (selectionStart.clientId === selectionEnd.clientId) { 12632 return null; 12633 } 12634 return selectionStart.clientId || null; 12635 } 12636 12637 /** 12638 * Returns the client ID of the block which ends the multi-selection set, or 12639 * null if there is no multi-selection. 12640 * 12641 * This is not necessarily the last client ID in the selection. 12642 * 12643 * @see getLastMultiSelectedBlockClientId 12644 * 12645 * @param {Object} state Editor state. 12646 * 12647 * @return {?string} Client ID of block ending multi-selection. 12648 */ 12649 function getMultiSelectedBlocksEndClientId(state) { 12650 const { 12651 selectionStart, 12652 selectionEnd 12653 } = state.selection; 12654 if (selectionStart.clientId === selectionEnd.clientId) { 12655 return null; 12656 } 12657 return selectionEnd.clientId || null; 12658 } 12659 12660 /** 12661 * Returns true if the selection is not partial. 12662 * 12663 * @param {Object} state Editor state. 12664 * 12665 * @return {boolean} Whether the selection is mergeable. 12666 */ 12667 function __unstableIsFullySelected(state) { 12668 const selectionAnchor = getSelectionStart(state); 12669 const selectionFocus = getSelectionEnd(state); 12670 return !selectionAnchor.attributeKey && !selectionFocus.attributeKey && typeof selectionAnchor.offset === 'undefined' && typeof selectionFocus.offset === 'undefined'; 12671 } 12672 12673 /** 12674 * Returns true if the selection is collapsed. 12675 * 12676 * @param {Object} state Editor state. 12677 * 12678 * @return {boolean} Whether the selection is collapsed. 12679 */ 12680 function __unstableIsSelectionCollapsed(state) { 12681 const selectionAnchor = getSelectionStart(state); 12682 const selectionFocus = getSelectionEnd(state); 12683 return !!selectionAnchor && !!selectionFocus && selectionAnchor.clientId === selectionFocus.clientId && selectionAnchor.attributeKey === selectionFocus.attributeKey && selectionAnchor.offset === selectionFocus.offset; 12684 } 12685 function __unstableSelectionHasUnmergeableBlock(state) { 12686 return getSelectedBlockClientIds(state).some(clientId => { 12687 const blockName = getBlockName(state, clientId); 12688 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 12689 return !blockType.merge; 12690 }); 12691 } 12692 12693 /** 12694 * Check whether the selection is mergeable. 12695 * 12696 * @param {Object} state Editor state. 12697 * @param {boolean} isForward Whether to merge forwards. 12698 * 12699 * @return {boolean} Whether the selection is mergeable. 12700 */ 12701 function __unstableIsSelectionMergeable(state, isForward) { 12702 const selectionAnchor = getSelectionStart(state); 12703 const selectionFocus = getSelectionEnd(state); 12704 12705 // It's not mergeable if the start and end are within the same block. 12706 if (selectionAnchor.clientId === selectionFocus.clientId) { 12707 return false; 12708 } 12709 12710 // It's not mergeable if there's no rich text selection. 12711 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') { 12712 return false; 12713 } 12714 const anchorRootClientId = getBlockRootClientId(state, selectionAnchor.clientId); 12715 const focusRootClientId = getBlockRootClientId(state, selectionFocus.clientId); 12716 12717 // It's not mergeable if the selection doesn't start and end in the same 12718 // block list. Maybe in the future it should be allowed. 12719 if (anchorRootClientId !== focusRootClientId) { 12720 return false; 12721 } 12722 const blockOrder = getBlockOrder(state, anchorRootClientId); 12723 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 12724 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 12725 12726 // Reassign selection start and end based on order. 12727 let selectionStart, selectionEnd; 12728 if (anchorIndex > focusIndex) { 12729 selectionStart = selectionFocus; 12730 selectionEnd = selectionAnchor; 12731 } else { 12732 selectionStart = selectionAnchor; 12733 selectionEnd = selectionFocus; 12734 } 12735 const targetBlockClientId = isForward ? selectionEnd.clientId : selectionStart.clientId; 12736 const blockToMergeClientId = isForward ? selectionStart.clientId : selectionEnd.clientId; 12737 const targetBlockName = getBlockName(state, targetBlockClientId); 12738 const targetBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlockName); 12739 if (!targetBlockType.merge) { 12740 return false; 12741 } 12742 const blockToMerge = getBlock(state, blockToMergeClientId); 12743 12744 // It's mergeable if the blocks are of the same type. 12745 if (blockToMerge.name === targetBlockName) { 12746 return true; 12747 } 12748 12749 // If the blocks are of a different type, try to transform the block being 12750 // merged into the same type of block. 12751 const blocksToMerge = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blockToMerge, targetBlockName); 12752 return blocksToMerge && blocksToMerge.length; 12753 } 12754 12755 /** 12756 * Get partial selected blocks with their content updated 12757 * based on the selection. 12758 * 12759 * @param {Object} state Editor state. 12760 * 12761 * @return {Object[]} Updated partial selected blocks. 12762 */ 12763 const __unstableGetSelectedBlocksWithPartialSelection = state => { 12764 const selectionAnchor = getSelectionStart(state); 12765 const selectionFocus = getSelectionEnd(state); 12766 if (selectionAnchor.clientId === selectionFocus.clientId) { 12767 return selectors_EMPTY_ARRAY; 12768 } 12769 12770 // Can't split if the selection is not set. 12771 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') { 12772 return selectors_EMPTY_ARRAY; 12773 } 12774 const anchorRootClientId = getBlockRootClientId(state, selectionAnchor.clientId); 12775 const focusRootClientId = getBlockRootClientId(state, selectionFocus.clientId); 12776 12777 // It's not splittable if the selection doesn't start and end in the same 12778 // block list. Maybe in the future it should be allowed. 12779 if (anchorRootClientId !== focusRootClientId) { 12780 return selectors_EMPTY_ARRAY; 12781 } 12782 const blockOrder = getBlockOrder(state, anchorRootClientId); 12783 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 12784 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 12785 12786 // Reassign selection start and end based on order. 12787 const [selectionStart, selectionEnd] = anchorIndex > focusIndex ? [selectionFocus, selectionAnchor] : [selectionAnchor, selectionFocus]; 12788 const blockA = getBlock(state, selectionStart.clientId); 12789 const blockB = getBlock(state, selectionEnd.clientId); 12790 const htmlA = blockA.attributes[selectionStart.attributeKey]; 12791 const htmlB = blockB.attributes[selectionEnd.attributeKey]; 12792 let valueA = (0,external_wp_richText_namespaceObject.create)({ 12793 html: htmlA 12794 }); 12795 let valueB = (0,external_wp_richText_namespaceObject.create)({ 12796 html: htmlB 12797 }); 12798 valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, 0, selectionStart.offset); 12799 valueB = (0,external_wp_richText_namespaceObject.remove)(valueB, selectionEnd.offset, valueB.text.length); 12800 return [{ 12801 ...blockA, 12802 attributes: { 12803 ...blockA.attributes, 12804 [selectionStart.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 12805 value: valueA 12806 }) 12807 } 12808 }, { 12809 ...blockB, 12810 attributes: { 12811 ...blockB.attributes, 12812 [selectionEnd.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 12813 value: valueB 12814 }) 12815 } 12816 }]; 12817 }; 12818 12819 /** 12820 * Returns an array containing all block client IDs in the editor in the order 12821 * they appear. Optionally accepts a root client ID of the block list for which 12822 * the order should be returned, defaulting to the top-level block order. 12823 * 12824 * @param {Object} state Editor state. 12825 * @param {?string} rootClientId Optional root client ID of block list. 12826 * 12827 * @return {Array} Ordered client IDs of editor blocks. 12828 */ 12829 function getBlockOrder(state, rootClientId) { 12830 return state.blocks.order.get(rootClientId || '') || selectors_EMPTY_ARRAY; 12831 } 12832 12833 /** 12834 * Returns the index at which the block corresponding to the specified client 12835 * ID occurs within the block order, or `-1` if the block does not exist. 12836 * 12837 * @param {Object} state Editor state. 12838 * @param {string} clientId Block client ID. 12839 * 12840 * @return {number} Index at which block exists in order. 12841 */ 12842 function getBlockIndex(state, clientId) { 12843 const rootClientId = getBlockRootClientId(state, clientId); 12844 return getBlockOrder(state, rootClientId).indexOf(clientId); 12845 } 12846 12847 /** 12848 * Returns true if the block corresponding to the specified client ID is 12849 * currently selected and no multi-selection exists, or false otherwise. 12850 * 12851 * @param {Object} state Editor state. 12852 * @param {string} clientId Block client ID. 12853 * 12854 * @return {boolean} Whether block is selected and multi-selection exists. 12855 */ 12856 function isBlockSelected(state, clientId) { 12857 const { 12858 selectionStart, 12859 selectionEnd 12860 } = state.selection; 12861 if (selectionStart.clientId !== selectionEnd.clientId) { 12862 return false; 12863 } 12864 return selectionStart.clientId === clientId; 12865 } 12866 12867 /** 12868 * Returns true if one of the block's inner blocks is selected. 12869 * 12870 * @param {Object} state Editor state. 12871 * @param {string} clientId Block client ID. 12872 * @param {boolean} deep Perform a deep check. 12873 * 12874 * @return {boolean} Whether the block has an inner block selected 12875 */ 12876 function hasSelectedInnerBlock(state, clientId, deep = false) { 12877 const selectedBlockClientIds = getSelectedBlockClientIds(state); 12878 if (!selectedBlockClientIds.length) { 12879 return false; 12880 } 12881 if (deep) { 12882 return selectedBlockClientIds.some(id => 12883 // Pass true because we don't care about order and it's more 12884 // performant. 12885 getBlockParents(state, id, true).includes(clientId)); 12886 } 12887 return selectedBlockClientIds.some(id => getBlockRootClientId(state, id) === clientId); 12888 } 12889 12890 /** 12891 * Returns true if one of the block's inner blocks is dragged. 12892 * 12893 * @param {Object} state Editor state. 12894 * @param {string} clientId Block client ID. 12895 * @param {boolean} deep Perform a deep check. 12896 * 12897 * @return {boolean} Whether the block has an inner block dragged 12898 */ 12899 function hasDraggedInnerBlock(state, clientId, deep = false) { 12900 return getBlockOrder(state, clientId).some(innerClientId => isBlockBeingDragged(state, innerClientId) || deep && hasDraggedInnerBlock(state, innerClientId, deep)); 12901 } 12902 12903 /** 12904 * Returns true if the block corresponding to the specified client ID is 12905 * currently selected but isn't the last of the selected blocks. Here "last" 12906 * refers to the block sequence in the document, _not_ the sequence of 12907 * multi-selection, which is why `state.selectionEnd` isn't used. 12908 * 12909 * @param {Object} state Editor state. 12910 * @param {string} clientId Block client ID. 12911 * 12912 * @return {boolean} Whether block is selected and not the last in the 12913 * selection. 12914 */ 12915 function isBlockWithinSelection(state, clientId) { 12916 if (!clientId) { 12917 return false; 12918 } 12919 const clientIds = getMultiSelectedBlockClientIds(state); 12920 const index = clientIds.indexOf(clientId); 12921 return index > -1 && index < clientIds.length - 1; 12922 } 12923 12924 /** 12925 * Returns true if a multi-selection has been made, or false otherwise. 12926 * 12927 * @param {Object} state Editor state. 12928 * 12929 * @return {boolean} Whether multi-selection has been made. 12930 */ 12931 function hasMultiSelection(state) { 12932 const { 12933 selectionStart, 12934 selectionEnd 12935 } = state.selection; 12936 return selectionStart.clientId !== selectionEnd.clientId; 12937 } 12938 12939 /** 12940 * Whether in the process of multi-selecting or not. This flag is only true 12941 * while the multi-selection is being selected (by mouse move), and is false 12942 * once the multi-selection has been settled. 12943 * 12944 * @see hasMultiSelection 12945 * 12946 * @param {Object} state Global application state. 12947 * 12948 * @return {boolean} True if multi-selecting, false if not. 12949 */ 12950 function selectors_isMultiSelecting(state) { 12951 return state.isMultiSelecting; 12952 } 12953 12954 /** 12955 * Selector that returns if multi-selection is enabled or not. 12956 * 12957 * @param {Object} state Global application state. 12958 * 12959 * @return {boolean} True if it should be possible to multi-select blocks, false if multi-selection is disabled. 12960 */ 12961 function selectors_isSelectionEnabled(state) { 12962 return state.isSelectionEnabled; 12963 } 12964 12965 /** 12966 * Returns the block's editing mode, defaulting to "visual" if not explicitly 12967 * assigned. 12968 * 12969 * @param {Object} state Editor state. 12970 * @param {string} clientId Block client ID. 12971 * 12972 * @return {Object} Block editing mode. 12973 */ 12974 function getBlockMode(state, clientId) { 12975 return state.blocksMode[clientId] || 'visual'; 12976 } 12977 12978 /** 12979 * Returns true if the user is typing, or false otherwise. 12980 * 12981 * @param {Object} state Global application state. 12982 * 12983 * @return {boolean} Whether user is typing. 12984 */ 12985 function selectors_isTyping(state) { 12986 return state.isTyping; 12987 } 12988 12989 /** 12990 * Returns true if the user is dragging blocks, or false otherwise. 12991 * 12992 * @param {Object} state Global application state. 12993 * 12994 * @return {boolean} Whether user is dragging blocks. 12995 */ 12996 function isDraggingBlocks(state) { 12997 return !!state.draggedBlocks.length; 12998 } 12999 13000 /** 13001 * Returns the client ids of any blocks being directly dragged. 13002 * 13003 * This does not include children of a parent being dragged. 13004 * 13005 * @param {Object} state Global application state. 13006 * 13007 * @return {string[]} Array of dragged block client ids. 13008 */ 13009 function getDraggedBlockClientIds(state) { 13010 return state.draggedBlocks; 13011 } 13012 13013 /** 13014 * Returns whether the block is being dragged. 13015 * 13016 * Only returns true if the block is being directly dragged, 13017 * not if the block is a child of a parent being dragged. 13018 * See `isAncestorBeingDragged` for child blocks. 13019 * 13020 * @param {Object} state Global application state. 13021 * @param {string} clientId Client id for block to check. 13022 * 13023 * @return {boolean} Whether the block is being dragged. 13024 */ 13025 function isBlockBeingDragged(state, clientId) { 13026 return state.draggedBlocks.includes(clientId); 13027 } 13028 13029 /** 13030 * Returns whether a parent/ancestor of the block is being dragged. 13031 * 13032 * @param {Object} state Global application state. 13033 * @param {string} clientId Client id for block to check. 13034 * 13035 * @return {boolean} Whether the block's ancestor is being dragged. 13036 */ 13037 function isAncestorBeingDragged(state, clientId) { 13038 // Return early if no blocks are being dragged rather than 13039 // the more expensive check for parents. 13040 if (!isDraggingBlocks(state)) { 13041 return false; 13042 } 13043 const parents = getBlockParents(state, clientId); 13044 return parents.some(parentClientId => isBlockBeingDragged(state, parentClientId)); 13045 } 13046 13047 /** 13048 * Returns true if the caret is within formatted text, or false otherwise. 13049 * 13050 * @deprecated 13051 * 13052 * @return {boolean} Whether the caret is within formatted text. 13053 */ 13054 function isCaretWithinFormattedText() { 13055 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).isCaretWithinFormattedText', { 13056 since: '6.1', 13057 version: '6.3' 13058 }); 13059 return false; 13060 } 13061 13062 /** 13063 * Returns the location of the insertion cue. Defaults to the last index. 13064 * 13065 * @param {Object} state Editor state. 13066 * 13067 * @return {Object} Insertion point object with `rootClientId`, `index`. 13068 */ 13069 const getBlockInsertionPoint = (0,external_wp_data_namespaceObject.createSelector)(state => { 13070 let rootClientId, index; 13071 const { 13072 insertionCue, 13073 selection: { 13074 selectionEnd 13075 } 13076 } = state; 13077 if (insertionCue !== null) { 13078 return insertionCue; 13079 } 13080 const { 13081 clientId 13082 } = selectionEnd; 13083 if (clientId) { 13084 rootClientId = getBlockRootClientId(state, clientId) || undefined; 13085 index = getBlockIndex(state, selectionEnd.clientId) + 1; 13086 } else { 13087 index = getBlockOrder(state).length; 13088 } 13089 return { 13090 rootClientId, 13091 index 13092 }; 13093 }, state => [state.insertionCue, state.selection.selectionEnd.clientId, state.blocks.parents, state.blocks.order]); 13094 13095 /** 13096 * Returns true if the block insertion point is visible. 13097 * 13098 * @param {Object} state Global application state. 13099 * 13100 * @return {?boolean} Whether the insertion point is visible or not. 13101 */ 13102 function isBlockInsertionPointVisible(state) { 13103 return state.insertionCue !== null; 13104 } 13105 13106 /** 13107 * Returns whether the blocks matches the template or not. 13108 * 13109 * @param {boolean} state 13110 * @return {?boolean} Whether the template is valid or not. 13111 */ 13112 function isValidTemplate(state) { 13113 return state.template.isValid; 13114 } 13115 13116 /** 13117 * Returns the defined block template 13118 * 13119 * @param {boolean} state 13120 * 13121 * @return {?Array} Block Template. 13122 */ 13123 function getTemplate(state) { 13124 return state.settings.template; 13125 } 13126 13127 /** 13128 * Returns the defined block template lock. Optionally accepts a root block 13129 * client ID as context, otherwise defaulting to the global context. 13130 * 13131 * @param {Object} state Editor state. 13132 * @param {?string} rootClientId Optional block root client ID. 13133 * 13134 * @return {string|false} Block Template Lock 13135 */ 13136 function getTemplateLock(state, rootClientId) { 13137 var _getBlockListSettings; 13138 if (!rootClientId) { 13139 var _state$settings$templ; 13140 return (_state$settings$templ = state.settings.templateLock) !== null && _state$settings$templ !== void 0 ? _state$settings$templ : false; 13141 } 13142 return (_getBlockListSettings = getBlockListSettings(state, rootClientId)?.templateLock) !== null && _getBlockListSettings !== void 0 ? _getBlockListSettings : false; 13143 } 13144 13145 /** 13146 * Determines if the given block type is visible in the inserter. 13147 * Note that this is different than whether a block is allowed to be inserted. 13148 * In some cases, the block is not allowed in a given position but 13149 * it should still be visible in the inserter to be able to add it 13150 * to a different position. 13151 * 13152 * @param {Object} state Editor state. 13153 * @param {string|Object} blockNameOrType The block type object, e.g., the response 13154 * from the block directory; or a string name of 13155 * an installed block type, e.g.' core/paragraph'. 13156 * @param {?string} rootClientId Optional root client ID of block list. 13157 * 13158 * @return {boolean} Whether the given block type is allowed to be inserted. 13159 */ 13160 const isBlockVisibleInTheInserter = (state, blockNameOrType, rootClientId = null) => { 13161 let blockType; 13162 let blockName; 13163 if (blockNameOrType && 'object' === typeof blockNameOrType) { 13164 blockType = blockNameOrType; 13165 blockName = blockNameOrType.name; 13166 } else { 13167 blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockNameOrType); 13168 blockName = blockNameOrType; 13169 } 13170 if (!blockType) { 13171 return false; 13172 } 13173 const { 13174 allowedBlockTypes 13175 } = getSettings(state); 13176 const isBlockAllowedInEditor = checkAllowList(allowedBlockTypes, blockName, true); 13177 if (!isBlockAllowedInEditor) { 13178 return false; 13179 } 13180 13181 // If parent blocks are not visible, child blocks should be hidden too. 13182 const parents = (Array.isArray(blockType.parent) ? blockType.parent : []).concat(Array.isArray(blockType.ancestor) ? blockType.ancestor : []); 13183 if (parents.length > 0) { 13184 // This is an exception to the rule that says that all blocks are visible in the inserter. 13185 // Blocks that require a given parent or ancestor are only visible if we're within that parent. 13186 if (parents.includes('core/post-content')) { 13187 return true; 13188 } 13189 let current = rootClientId; 13190 let hasParent = false; 13191 do { 13192 if (parents.includes(getBlockName(state, current))) { 13193 hasParent = true; 13194 break; 13195 } 13196 current = state.blocks.parents.get(current); 13197 } while (current); 13198 return hasParent; 13199 } 13200 return true; 13201 }; 13202 13203 /** 13204 * Determines if the given block type is allowed to be inserted into the block list. 13205 * This function is not exported and not memoized because using a memoized selector 13206 * inside another memoized selector is just a waste of time. 13207 * 13208 * @param {Object} state Editor state. 13209 * @param {string|Object} blockName The block type object, e.g., the response 13210 * from the block directory; or a string name of 13211 * an installed block type, e.g.' core/paragraph'. 13212 * @param {?string} rootClientId Optional root client ID of block list. 13213 * 13214 * @return {boolean} Whether the given block type is allowed to be inserted. 13215 */ 13216 const canInsertBlockTypeUnmemoized = (state, blockName, rootClientId = null) => { 13217 if (!isBlockVisibleInTheInserter(state, blockName, rootClientId)) { 13218 return false; 13219 } 13220 let blockType; 13221 if (blockName && 'object' === typeof blockName) { 13222 blockType = blockName; 13223 blockName = blockType.name; 13224 } else { 13225 blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 13226 } 13227 const isLocked = !!getTemplateLock(state, rootClientId); 13228 if (isLocked) { 13229 return false; 13230 } 13231 const _isSectionBlock = !!isSectionBlock(state, rootClientId); 13232 if (_isSectionBlock) { 13233 return false; 13234 } 13235 if (getBlockEditingMode(state, rootClientId !== null && rootClientId !== void 0 ? rootClientId : '') === 'disabled') { 13236 return false; 13237 } 13238 const parentBlockListSettings = getBlockListSettings(state, rootClientId); 13239 13240 // The parent block doesn't have settings indicating it doesn't support 13241 // inner blocks, return false. 13242 if (rootClientId && parentBlockListSettings === undefined) { 13243 return false; 13244 } 13245 const parentName = getBlockName(state, rootClientId); 13246 const parentBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(parentName); 13247 13248 // Look at the `blockType.allowedBlocks` field to determine whether this is an allowed child block. 13249 const parentAllowedChildBlocks = parentBlockType?.allowedBlocks; 13250 let hasParentAllowedBlock = checkAllowList(parentAllowedChildBlocks, blockName); 13251 13252 // The `allowedBlocks` block list setting can further limit which blocks are allowed children. 13253 if (hasParentAllowedBlock !== false) { 13254 const parentAllowedBlocks = parentBlockListSettings?.allowedBlocks; 13255 const hasParentListAllowedBlock = checkAllowList(parentAllowedBlocks, blockName); 13256 // Never downgrade the result from `true` to `null` 13257 if (hasParentListAllowedBlock !== null) { 13258 hasParentAllowedBlock = hasParentListAllowedBlock; 13259 } 13260 } 13261 const blockAllowedParentBlocks = blockType.parent; 13262 const hasBlockAllowedParent = checkAllowList(blockAllowedParentBlocks, parentName); 13263 let hasBlockAllowedAncestor = true; 13264 const blockAllowedAncestorBlocks = blockType.ancestor; 13265 if (blockAllowedAncestorBlocks) { 13266 const ancestors = [rootClientId, ...getBlockParents(state, rootClientId)]; 13267 hasBlockAllowedAncestor = ancestors.some(ancestorClientId => checkAllowList(blockAllowedAncestorBlocks, getBlockName(state, ancestorClientId))); 13268 } 13269 const canInsert = hasBlockAllowedAncestor && (hasParentAllowedBlock === null && hasBlockAllowedParent === null || hasParentAllowedBlock === true || hasBlockAllowedParent === true); 13270 if (!canInsert) { 13271 return canInsert; 13272 } 13273 13274 /** 13275 * This filter is an ad-hoc solution to prevent adding template parts inside post content. 13276 * Conceptually, having a filter inside a selector is bad pattern so this code will be 13277 * replaced by a declarative API that doesn't the following drawbacks: 13278 * 13279 * Filters are not reactive: Upon switching between "template mode" and non "template mode", 13280 * the filter and selector won't necessarily be executed again. For now, it doesn't matter much 13281 * because you can't switch between the two modes while the inserter stays open. 13282 * 13283 * Filters are global: Once they're defined, they will affect all editor instances and all registries. 13284 * An ideal API would only affect specific editor instances. 13285 */ 13286 return (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.__unstableCanInsertBlockType', canInsert, blockType, rootClientId, { 13287 // Pass bound selectors of the current registry. If we're in a nested 13288 // context, the data will differ from the one selected from the root 13289 // registry. 13290 getBlock: getBlock.bind(null, state), 13291 getBlockParentsByBlockName: getBlockParentsByBlockName.bind(null, state) 13292 }); 13293 }; 13294 13295 /** 13296 * Determines if the given block type is allowed to be inserted into the block list. 13297 * 13298 * @param {Object} state Editor state. 13299 * @param {string} blockName The name of the block type, e.g.' core/paragraph'. 13300 * @param {?string} rootClientId Optional root client ID of block list. 13301 * 13302 * @return {boolean} Whether the given block type is allowed to be inserted. 13303 */ 13304 const canInsertBlockType = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)(canInsertBlockTypeUnmemoized, (state, blockName, rootClientId) => getInsertBlockTypeDependants(select)(state, rootClientId))); 13305 13306 /** 13307 * Determines if the given blocks are allowed to be inserted into the block 13308 * list. 13309 * 13310 * @param {Object} state Editor state. 13311 * @param {string} clientIds The block client IDs to be inserted. 13312 * @param {?string} rootClientId Optional root client ID of block list. 13313 * 13314 * @return {boolean} Whether the given blocks are allowed to be inserted. 13315 */ 13316 function canInsertBlocks(state, clientIds, rootClientId = null) { 13317 return clientIds.every(id => canInsertBlockType(state, getBlockName(state, id), rootClientId)); 13318 } 13319 13320 /** 13321 * Determines if the given block is allowed to be deleted. 13322 * 13323 * @param {Object} state Editor state. 13324 * @param {string} clientId The block client Id. 13325 * 13326 * @return {boolean} Whether the given block is allowed to be removed. 13327 */ 13328 function canRemoveBlock(state, clientId) { 13329 const attributes = getBlockAttributes(state, clientId); 13330 if (attributes === null) { 13331 return true; 13332 } 13333 if (attributes.lock?.remove !== undefined) { 13334 return !attributes.lock.remove; 13335 } 13336 const rootClientId = getBlockRootClientId(state, clientId); 13337 if (getTemplateLock(state, rootClientId)) { 13338 return false; 13339 } 13340 const isBlockWithinSection = !!getParentSectionBlock(state, clientId); 13341 if (isBlockWithinSection) { 13342 return false; 13343 } 13344 return getBlockEditingMode(state, rootClientId) !== 'disabled'; 13345 } 13346 13347 /** 13348 * Determines if the given blocks are allowed to be removed. 13349 * 13350 * @param {Object} state Editor state. 13351 * @param {string} clientIds The block client IDs to be removed. 13352 * 13353 * @return {boolean} Whether the given blocks are allowed to be removed. 13354 */ 13355 function canRemoveBlocks(state, clientIds) { 13356 return clientIds.every(clientId => canRemoveBlock(state, clientId)); 13357 } 13358 13359 /** 13360 * Determines if the given block is allowed to be moved. 13361 * 13362 * @param {Object} state Editor state. 13363 * @param {string} clientId The block client Id. 13364 * 13365 * @return {boolean} Whether the given block is allowed to be moved. 13366 */ 13367 function canMoveBlock(state, clientId) { 13368 const attributes = getBlockAttributes(state, clientId); 13369 if (attributes === null) { 13370 return true; 13371 } 13372 if (attributes.lock?.move !== undefined) { 13373 return !attributes.lock.move; 13374 } 13375 const rootClientId = getBlockRootClientId(state, clientId); 13376 if (getTemplateLock(state, rootClientId) === 'all') { 13377 return false; 13378 } 13379 return getBlockEditingMode(state, rootClientId) !== 'disabled'; 13380 } 13381 13382 /** 13383 * Determines if the given blocks are allowed to be moved. 13384 * 13385 * @param {Object} state Editor state. 13386 * @param {string} clientIds The block client IDs to be moved. 13387 * 13388 * @return {boolean} Whether the given blocks are allowed to be moved. 13389 */ 13390 function canMoveBlocks(state, clientIds) { 13391 return clientIds.every(clientId => canMoveBlock(state, clientId)); 13392 } 13393 13394 /** 13395 * Determines if the given block is allowed to be edited. 13396 * 13397 * @param {Object} state Editor state. 13398 * @param {string} clientId The block client Id. 13399 * 13400 * @return {boolean} Whether the given block is allowed to be edited. 13401 */ 13402 function canEditBlock(state, clientId) { 13403 const attributes = getBlockAttributes(state, clientId); 13404 if (attributes === null) { 13405 return true; 13406 } 13407 const { 13408 lock 13409 } = attributes; 13410 13411 // When the edit is true, we cannot edit the block. 13412 return !lock?.edit; 13413 } 13414 13415 /** 13416 * Determines if the given block type can be locked/unlocked by a user. 13417 * 13418 * @param {Object} state Editor state. 13419 * @param {(string|Object)} nameOrType Block name or type object. 13420 * 13421 * @return {boolean} Whether a given block type can be locked/unlocked. 13422 */ 13423 function canLockBlockType(state, nameOrType) { 13424 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, 'lock', true)) { 13425 return false; 13426 } 13427 13428 // Use block editor settings as the default value. 13429 return !!state.settings?.canLockBlocks; 13430 } 13431 13432 /** 13433 * Returns information about how recently and frequently a block has been inserted. 13434 * 13435 * @param {Object} state Global application state. 13436 * @param {string} id A string which identifies the insert, e.g. 'core/block/12' 13437 * 13438 * @return {?{ time: number, count: number }} An object containing `time` which is when the last 13439 * insert occurred as a UNIX epoch, and `count` which is 13440 * the number of inserts that have occurred. 13441 */ 13442 function getInsertUsage(state, id) { 13443 var _state$preferences$in; 13444 return (_state$preferences$in = state.preferences.insertUsage?.[id]) !== null && _state$preferences$in !== void 0 ? _state$preferences$in : null; 13445 } 13446 13447 /** 13448 * Returns whether we can show a block type in the inserter 13449 * 13450 * @param {Object} state Global State 13451 * @param {Object} blockType BlockType 13452 * @param {?string} rootClientId Optional root client ID of block list. 13453 * 13454 * @return {boolean} Whether the given block type is allowed to be shown in the inserter. 13455 */ 13456 const canIncludeBlockTypeInInserter = (state, blockType, rootClientId) => { 13457 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'inserter', true)) { 13458 return false; 13459 } 13460 return canInsertBlockTypeUnmemoized(state, blockType.name, rootClientId); 13461 }; 13462 13463 /** 13464 * Return a function to be used to transform a block variation to an inserter item 13465 * 13466 * @param {Object} state Global State 13467 * @param {Object} item Denormalized inserter item 13468 * @return {Function} Function to transform a block variation to inserter item 13469 */ 13470 const getItemFromVariation = (state, item) => variation => { 13471 const variationId = `$item.id}/$variation.name}`; 13472 const { 13473 time, 13474 count = 0 13475 } = getInsertUsage(state, variationId) || {}; 13476 return { 13477 ...item, 13478 id: variationId, 13479 icon: variation.icon || item.icon, 13480 title: variation.title || item.title, 13481 description: variation.description || item.description, 13482 category: variation.category || item.category, 13483 // If `example` is explicitly undefined for the variation, the preview will not be shown. 13484 example: variation.hasOwnProperty('example') ? variation.example : item.example, 13485 initialAttributes: { 13486 ...item.initialAttributes, 13487 ...variation.attributes 13488 }, 13489 innerBlocks: variation.innerBlocks, 13490 keywords: variation.keywords || item.keywords, 13491 frecency: calculateFrecency(time, count) 13492 }; 13493 }; 13494 13495 /** 13496 * Returns the calculated frecency. 13497 * 13498 * 'frecency' is a heuristic (https://en.wikipedia.org/wiki/Frecency) 13499 * that combines block usage frequency and recency. 13500 * 13501 * @param {number} time When the last insert occurred as a UNIX epoch 13502 * @param {number} count The number of inserts that have occurred. 13503 * 13504 * @return {number} The calculated frecency. 13505 */ 13506 const calculateFrecency = (time, count) => { 13507 if (!time) { 13508 return count; 13509 } 13510 // The selector is cached, which means Date.now() is the last time that the 13511 // relevant state changed. This suits our needs. 13512 const duration = Date.now() - time; 13513 switch (true) { 13514 case duration < MILLISECONDS_PER_HOUR: 13515 return count * 4; 13516 case duration < MILLISECONDS_PER_DAY: 13517 return count * 2; 13518 case duration < MILLISECONDS_PER_WEEK: 13519 return count / 2; 13520 default: 13521 return count / 4; 13522 } 13523 }; 13524 13525 /** 13526 * Returns a function that accepts a block type and builds an item to be shown 13527 * in a specific context. It's used for building items for Inserter and available 13528 * block Transforms list. 13529 * 13530 * @param {Object} state Editor state. 13531 * @param {Object} options Options object for handling the building of a block type. 13532 * @param {string} options.buildScope The scope for which the item is going to be used. 13533 * @return {Function} Function returns an item to be shown in a specific context (Inserter|Transforms list). 13534 */ 13535 const buildBlockTypeItem = (state, { 13536 buildScope = 'inserter' 13537 }) => blockType => { 13538 const id = blockType.name; 13539 let isDisabled = false; 13540 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType.name, 'multiple', true)) { 13541 isDisabled = getBlocksByClientId(state, getClientIdsWithDescendants(state)).some(({ 13542 name 13543 }) => name === blockType.name); 13544 } 13545 const { 13546 time, 13547 count = 0 13548 } = getInsertUsage(state, id) || {}; 13549 const blockItemBase = { 13550 id, 13551 name: blockType.name, 13552 title: blockType.title, 13553 icon: blockType.icon, 13554 isDisabled, 13555 frecency: calculateFrecency(time, count) 13556 }; 13557 if (buildScope === 'transform') { 13558 return blockItemBase; 13559 } 13560 const inserterVariations = (0,external_wp_blocks_namespaceObject.getBlockVariations)(blockType.name, 'inserter'); 13561 return { 13562 ...blockItemBase, 13563 initialAttributes: {}, 13564 description: blockType.description, 13565 category: blockType.category, 13566 keywords: blockType.keywords, 13567 parent: blockType.parent, 13568 ancestor: blockType.ancestor, 13569 variations: inserterVariations, 13570 example: blockType.example, 13571 utility: 1 // Deprecated. 13572 }; 13573 }; 13574 13575 /** 13576 * Determines the items that appear in the inserter. Includes both static 13577 * items (e.g. a regular block type) and dynamic items (e.g. a reusable block). 13578 * 13579 * Each item object contains what's necessary to display a button in the 13580 * inserter and handle its selection. 13581 * 13582 * The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency) 13583 * that combines block usage frequency and recency. 13584 * 13585 * Items are returned ordered descendingly by their 'utility' and 'frecency'. 13586 * 13587 * @param {Object} state Editor state. 13588 * @param {?string} rootClientId Optional root client ID of block list. 13589 * 13590 * @return {WPEditorInserterItem[]} Items that appear in inserter. 13591 * 13592 * @typedef {Object} WPEditorInserterItem 13593 * @property {string} id Unique identifier for the item. 13594 * @property {string} name The type of block to create. 13595 * @property {Object} initialAttributes Attributes to pass to the newly created block. 13596 * @property {string} title Title of the item, as it appears in the inserter. 13597 * @property {string} icon Dashicon for the item, as it appears in the inserter. 13598 * @property {string} category Block category that the item is associated with. 13599 * @property {string[]} keywords Keywords that can be searched to find this item. 13600 * @property {boolean} isDisabled Whether or not the user should be prevented from inserting 13601 * this item. 13602 * @property {number} frecency Heuristic that combines frequency and recency. 13603 */ 13604 const getInserterItems = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, rootClientId = null, options = DEFAULT_INSERTER_OPTIONS) => { 13605 const buildReusableBlockInserterItem = reusableBlock => { 13606 const icon = !reusableBlock.wp_pattern_sync_status ? { 13607 src: library_symbol, 13608 foreground: 'var(--wp-block-synced-color)' 13609 } : library_symbol; 13610 const id = `core/block/$reusableBlock.id}`; 13611 const { 13612 time, 13613 count = 0 13614 } = getInsertUsage(state, id) || {}; 13615 const frecency = calculateFrecency(time, count); 13616 return { 13617 id, 13618 name: 'core/block', 13619 initialAttributes: { 13620 ref: reusableBlock.id 13621 }, 13622 title: reusableBlock.title?.raw, 13623 icon, 13624 category: 'reusable', 13625 keywords: ['reusable'], 13626 isDisabled: false, 13627 utility: 1, 13628 // Deprecated. 13629 frecency, 13630 content: reusableBlock.content?.raw, 13631 syncStatus: reusableBlock.wp_pattern_sync_status 13632 }; 13633 }; 13634 const syncedPatternInserterItems = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) ? unlock(select(STORE_NAME)).getReusableBlocks().map(buildReusableBlockInserterItem) : []; 13635 const buildBlockTypeInserterItem = buildBlockTypeItem(state, { 13636 buildScope: 'inserter' 13637 }); 13638 let blockTypeInserterItems = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'inserter', true)).map(buildBlockTypeInserterItem); 13639 if (options[isFiltered] !== false) { 13640 blockTypeInserterItems = blockTypeInserterItems.filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)); 13641 } else { 13642 blockTypeInserterItems = blockTypeInserterItems.filter(blockType => isBlockVisibleInTheInserter(state, blockType, rootClientId)).map(blockType => ({ 13643 ...blockType, 13644 isAllowedInCurrentRoot: canIncludeBlockTypeInInserter(state, blockType, rootClientId) 13645 })); 13646 } 13647 const items = blockTypeInserterItems.reduce((accumulator, item) => { 13648 const { 13649 variations = [] 13650 } = item; 13651 // Exclude any block type item that is to be replaced by a default variation. 13652 if (!variations.some(({ 13653 isDefault 13654 }) => isDefault)) { 13655 accumulator.push(item); 13656 } 13657 if (variations.length) { 13658 const variationMapper = getItemFromVariation(state, item); 13659 accumulator.push(...variations.map(variationMapper)); 13660 } 13661 return accumulator; 13662 }, []); 13663 13664 // Ensure core blocks are prioritized in the returned results, 13665 // because third party blocks can be registered earlier than 13666 // the core blocks (usually by using the `init` action), 13667 // thus affecting the display order. 13668 // We don't sort reusable blocks as they are handled differently. 13669 const groupByType = (blocks, block) => { 13670 const { 13671 core, 13672 noncore 13673 } = blocks; 13674 const type = block.name.startsWith('core/') ? core : noncore; 13675 type.push(block); 13676 return blocks; 13677 }; 13678 const { 13679 core: coreItems, 13680 noncore: nonCoreItems 13681 } = items.reduce(groupByType, { 13682 core: [], 13683 noncore: [] 13684 }); 13685 const sortedBlockTypes = [...coreItems, ...nonCoreItems]; 13686 return [...sortedBlockTypes, ...syncedPatternInserterItems]; 13687 }, (state, rootClientId) => [(0,external_wp_blocks_namespaceObject.getBlockTypes)(), unlock(select(STORE_NAME)).getReusableBlocks(), state.blocks.order, state.preferences.insertUsage, ...getInsertBlockTypeDependants(select)(state, rootClientId)])); 13688 13689 /** 13690 * Determines the items that appear in the available block transforms list. 13691 * 13692 * Each item object contains what's necessary to display a menu item in the 13693 * transform list and handle its selection. 13694 * 13695 * The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency) 13696 * that combines block usage frequency and recency. 13697 * 13698 * Items are returned ordered descendingly by their 'frecency'. 13699 * 13700 * @param {Object} state Editor state. 13701 * @param {Object|Object[]} blocks Block object or array objects. 13702 * @param {?string} rootClientId Optional root client ID of block list. 13703 * 13704 * @return {WPEditorTransformItem[]} Items that appear in inserter. 13705 * 13706 * @typedef {Object} WPEditorTransformItem 13707 * @property {string} id Unique identifier for the item. 13708 * @property {string} name The type of block to create. 13709 * @property {string} title Title of the item, as it appears in the inserter. 13710 * @property {string} icon Dashicon for the item, as it appears in the inserter. 13711 * @property {boolean} isDisabled Whether or not the user should be prevented from inserting 13712 * this item. 13713 * @property {number} frecency Heuristic that combines frequency and recency. 13714 */ 13715 const getBlockTransformItems = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, blocks, rootClientId = null) => { 13716 const normalizedBlocks = Array.isArray(blocks) ? blocks : [blocks]; 13717 const buildBlockTypeTransformItem = buildBlockTypeItem(state, { 13718 buildScope: 'transform' 13719 }); 13720 const blockTypeTransformItems = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)).map(buildBlockTypeTransformItem); 13721 const itemsByName = Object.fromEntries(Object.entries(blockTypeTransformItems).map(([, value]) => [value.name, value])); 13722 const possibleTransforms = (0,external_wp_blocks_namespaceObject.getPossibleBlockTransformations)(normalizedBlocks).reduce((accumulator, block) => { 13723 if (itemsByName[block?.name]) { 13724 accumulator.push(itemsByName[block.name]); 13725 } 13726 return accumulator; 13727 }, []); 13728 return orderBy(possibleTransforms, block => itemsByName[block.name].frecency, 'desc'); 13729 }, (state, blocks, rootClientId) => [(0,external_wp_blocks_namespaceObject.getBlockTypes)(), state.preferences.insertUsage, ...getInsertBlockTypeDependants(select)(state, rootClientId)])); 13730 13731 /** 13732 * Determines whether there are items to show in the inserter. 13733 * 13734 * @param {Object} state Editor state. 13735 * @param {?string} rootClientId Optional root client ID of block list. 13736 * 13737 * @return {boolean} Items that appear in inserter. 13738 */ 13739 const hasInserterItems = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, rootClientId = null) => { 13740 const hasBlockType = (0,external_wp_blocks_namespaceObject.getBlockTypes)().some(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)); 13741 if (hasBlockType) { 13742 return true; 13743 } 13744 const hasReusableBlock = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) && unlock(select(STORE_NAME)).getReusableBlocks().length > 0; 13745 return hasReusableBlock; 13746 }); 13747 13748 /** 13749 * Returns the list of allowed inserter blocks for inner blocks children. 13750 * 13751 * @param {Object} state Editor state. 13752 * @param {?string} rootClientId Optional root client ID of block list. 13753 * 13754 * @return {Array?} The list of allowed block types. 13755 */ 13756 const getAllowedBlocks = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, rootClientId = null) => { 13757 if (!rootClientId) { 13758 return; 13759 } 13760 const blockTypes = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)); 13761 const hasReusableBlock = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) && unlock(select(STORE_NAME)).getReusableBlocks().length > 0; 13762 if (hasReusableBlock) { 13763 blockTypes.push('core/block'); 13764 } 13765 return blockTypes; 13766 }, (state, rootClientId) => [(0,external_wp_blocks_namespaceObject.getBlockTypes)(), unlock(select(STORE_NAME)).getReusableBlocks(), ...getInsertBlockTypeDependants(select)(state, rootClientId)])); 13767 const __experimentalGetAllowedBlocks = (0,external_wp_data_namespaceObject.createSelector)((state, rootClientId = null) => { 13768 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetAllowedBlocks', { 13769 alternative: 'wp.data.select( "core/block-editor" ).getAllowedBlocks', 13770 since: '6.2', 13771 version: '6.4' 13772 }); 13773 return getAllowedBlocks(state, rootClientId); 13774 }, (state, rootClientId) => getAllowedBlocks.getDependants(state, rootClientId)); 13775 13776 /** 13777 * Returns the block to be directly inserted by the block appender. 13778 * 13779 * @param {Object} state Editor state. 13780 * @param {?string} rootClientId Optional root client ID of block list. 13781 * 13782 * @return {WPDirectInsertBlock|undefined} The block type to be directly inserted. 13783 * 13784 * @typedef {Object} WPDirectInsertBlock 13785 * @property {string} name The type of block. 13786 * @property {?Object} attributes Attributes to pass to the newly created block. 13787 * @property {?Array<string>} attributesToCopy Attributes to be copied from adjacent blocks when inserted. 13788 */ 13789 function getDirectInsertBlock(state, rootClientId = null) { 13790 var _state$blockListSetti; 13791 if (!rootClientId) { 13792 return; 13793 } 13794 const { 13795 defaultBlock, 13796 directInsert 13797 } = (_state$blockListSetti = state.blockListSettings[rootClientId]) !== null && _state$blockListSetti !== void 0 ? _state$blockListSetti : {}; 13798 if (!defaultBlock || !directInsert) { 13799 return; 13800 } 13801 return defaultBlock; 13802 } 13803 function __experimentalGetDirectInsertBlock(state, rootClientId = null) { 13804 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetDirectInsertBlock', { 13805 alternative: 'wp.data.select( "core/block-editor" ).getDirectInsertBlock', 13806 since: '6.3', 13807 version: '6.4' 13808 }); 13809 return getDirectInsertBlock(state, rootClientId); 13810 } 13811 const __experimentalGetParsedPattern = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, patternName) => { 13812 const pattern = unlock(select(STORE_NAME)).getPatternBySlug(patternName); 13813 return pattern ? getParsedPattern(pattern) : null; 13814 }); 13815 const getAllowedPatternsDependants = select => (state, rootClientId) => [...getAllPatternsDependants(select)(state), ...getInsertBlockTypeDependants(select)(state, rootClientId)]; 13816 const patternsWithParsedBlocks = new WeakMap(); 13817 function enhancePatternWithParsedBlocks(pattern) { 13818 let enhancedPattern = patternsWithParsedBlocks.get(pattern); 13819 if (!enhancedPattern) { 13820 enhancedPattern = { 13821 ...pattern, 13822 get blocks() { 13823 return getParsedPattern(pattern).blocks; 13824 } 13825 }; 13826 patternsWithParsedBlocks.set(pattern, enhancedPattern); 13827 } 13828 return enhancedPattern; 13829 } 13830 13831 /** 13832 * Returns the list of allowed patterns for inner blocks children. 13833 * 13834 * @param {Object} state Editor state. 13835 * @param {?string} rootClientId Optional target root client ID. 13836 * 13837 * @return {Array?} The list of allowed patterns. 13838 */ 13839 const __experimentalGetAllowedPatterns = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => { 13840 return (0,external_wp_data_namespaceObject.createSelector)((state, rootClientId = null, options = DEFAULT_INSERTER_OPTIONS) => { 13841 const { 13842 getAllPatterns 13843 } = unlock(select(STORE_NAME)); 13844 const patterns = getAllPatterns(); 13845 const { 13846 allowedBlockTypes 13847 } = getSettings(state); 13848 const parsedPatterns = patterns.filter(({ 13849 inserter = true 13850 }) => !!inserter).map(enhancePatternWithParsedBlocks); 13851 const availableParsedPatterns = parsedPatterns.filter(pattern => checkAllowListRecursive(getGrammar(pattern), allowedBlockTypes)); 13852 const patternsAllowed = availableParsedPatterns.filter(pattern => getGrammar(pattern).every(({ 13853 blockName: name 13854 }) => options[isFiltered] !== false ? canInsertBlockType(state, name, rootClientId) : isBlockVisibleInTheInserter(state, name, rootClientId))); 13855 return patternsAllowed; 13856 }, getAllowedPatternsDependants(select)); 13857 }); 13858 13859 /** 13860 * Returns the list of patterns based on their declared `blockTypes` 13861 * and a block's name. 13862 * Patterns can use `blockTypes` to integrate in work flows like 13863 * suggesting appropriate patterns in a Placeholder state(during insertion) 13864 * or blocks transformations. 13865 * 13866 * @param {Object} state Editor state. 13867 * @param {string|string[]} blockNames Block's name or array of block names to find matching patterns. 13868 * @param {?string} rootClientId Optional target root client ID. 13869 * 13870 * @return {Array} The list of matched block patterns based on declared `blockTypes` and block name. 13871 */ 13872 const getPatternsByBlockTypes = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, blockNames, rootClientId = null) => { 13873 if (!blockNames) { 13874 return selectors_EMPTY_ARRAY; 13875 } 13876 const patterns = select(STORE_NAME).__experimentalGetAllowedPatterns(rootClientId); 13877 const normalizedBlockNames = Array.isArray(blockNames) ? blockNames : [blockNames]; 13878 const filteredPatterns = patterns.filter(pattern => pattern?.blockTypes?.some?.(blockName => normalizedBlockNames.includes(blockName))); 13879 if (filteredPatterns.length === 0) { 13880 return selectors_EMPTY_ARRAY; 13881 } 13882 return filteredPatterns; 13883 }, (state, blockNames, rootClientId) => getAllowedPatternsDependants(select)(state, rootClientId))); 13884 const __experimentalGetPatternsByBlockTypes = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => { 13885 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetPatternsByBlockTypes', { 13886 alternative: 'wp.data.select( "core/block-editor" ).getPatternsByBlockTypes', 13887 since: '6.2', 13888 version: '6.4' 13889 }); 13890 return select(STORE_NAME).getPatternsByBlockTypes; 13891 }); 13892 13893 /** 13894 * Determines the items that appear in the available pattern transforms list. 13895 * 13896 * For now we only handle blocks without InnerBlocks and take into account 13897 * the `role` property of blocks' attributes for the transformation. 13898 * 13899 * We return the first set of possible eligible block patterns, 13900 * by checking the `blockTypes` property. We still have to recurse through 13901 * block pattern's blocks and try to find matches from the selected blocks. 13902 * Now this happens in the consumer to avoid heavy operations in the selector. 13903 * 13904 * @param {Object} state Editor state. 13905 * @param {Object[]} blocks The selected blocks. 13906 * @param {?string} rootClientId Optional root client ID of block list. 13907 * 13908 * @return {WPBlockPattern[]} Items that are eligible for a pattern transformation. 13909 */ 13910 const __experimentalGetPatternTransformItems = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, blocks, rootClientId = null) => { 13911 if (!blocks) { 13912 return selectors_EMPTY_ARRAY; 13913 } 13914 /** 13915 * For now we only handle blocks without InnerBlocks and take into account 13916 * the `role` property of blocks' attributes for the transformation. 13917 * Note that the blocks have been retrieved through `getBlock`, which doesn't 13918 * return the inner blocks of an inner block controller, so we still need 13919 * to check for this case too. 13920 */ 13921 if (blocks.some(({ 13922 clientId, 13923 innerBlocks 13924 }) => innerBlocks.length || areInnerBlocksControlled(state, clientId))) { 13925 return selectors_EMPTY_ARRAY; 13926 } 13927 13928 // Create a Set of the selected block names that is used in patterns filtering. 13929 const selectedBlockNames = Array.from(new Set(blocks.map(({ 13930 name 13931 }) => name))); 13932 /** 13933 * Here we will return first set of possible eligible block patterns, 13934 * by checking the `blockTypes` property. We still have to recurse through 13935 * block pattern's blocks and try to find matches from the selected blocks. 13936 * Now this happens in the consumer to avoid heavy operations in the selector. 13937 */ 13938 return select(STORE_NAME).getPatternsByBlockTypes(selectedBlockNames, rootClientId); 13939 }, (state, blocks, rootClientId) => getAllowedPatternsDependants(select)(state, rootClientId))); 13940 13941 /** 13942 * Returns the Block List settings of a block, if any exist. 13943 * 13944 * @param {Object} state Editor state. 13945 * @param {?string} clientId Block client ID. 13946 * 13947 * @return {?Object} Block settings of the block if set. 13948 */ 13949 function getBlockListSettings(state, clientId) { 13950 return state.blockListSettings[clientId]; 13951 } 13952 13953 /** 13954 * Returns the editor settings. 13955 * 13956 * @param {Object} state Editor state. 13957 * 13958 * @return {Object} The editor settings object. 13959 */ 13960 function getSettings(state) { 13961 return state.settings; 13962 } 13963 13964 /** 13965 * Returns true if the most recent block change is be considered persistent, or 13966 * false otherwise. A persistent change is one committed by BlockEditorProvider 13967 * via its `onChange` callback, in addition to `onInput`. 13968 * 13969 * @param {Object} state Block editor state. 13970 * 13971 * @return {boolean} Whether the most recent block change was persistent. 13972 */ 13973 function isLastBlockChangePersistent(state) { 13974 return state.blocks.isPersistentChange; 13975 } 13976 13977 /** 13978 * Returns the block list settings for an array of blocks, if any exist. 13979 * 13980 * @param {Object} state Editor state. 13981 * @param {Array} clientIds Block client IDs. 13982 * 13983 * @return {Object} An object where the keys are client ids and the values are 13984 * a block list setting object. 13985 */ 13986 const __experimentalGetBlockListSettingsForBlocks = (0,external_wp_data_namespaceObject.createSelector)((state, clientIds = []) => { 13987 return clientIds.reduce((blockListSettingsForBlocks, clientId) => { 13988 if (!state.blockListSettings[clientId]) { 13989 return blockListSettingsForBlocks; 13990 } 13991 return { 13992 ...blockListSettingsForBlocks, 13993 [clientId]: state.blockListSettings[clientId] 13994 }; 13995 }, {}); 13996 }, state => [state.blockListSettings]); 13997 13998 /** 13999 * Returns the title of a given reusable block 14000 * 14001 * @param {Object} state Global application state. 14002 * @param {number|string} ref The shared block's ID. 14003 * 14004 * @return {string} The reusable block saved title. 14005 */ 14006 const __experimentalGetReusableBlockTitle = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (0,external_wp_data_namespaceObject.createSelector)((state, ref) => { 14007 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__experimentalGetReusableBlockTitle", { 14008 since: '6.6', 14009 version: '6.8' 14010 }); 14011 const reusableBlock = unlock(select(STORE_NAME)).getReusableBlocks().find(block => block.id === ref); 14012 if (!reusableBlock) { 14013 return null; 14014 } 14015 return reusableBlock.title?.raw; 14016 }, () => [unlock(select(STORE_NAME)).getReusableBlocks()])); 14017 14018 /** 14019 * Returns true if the most recent block change is be considered ignored, or 14020 * false otherwise. An ignored change is one not to be committed by 14021 * BlockEditorProvider, neither via `onChange` nor `onInput`. 14022 * 14023 * @param {Object} state Block editor state. 14024 * 14025 * @return {boolean} Whether the most recent block change was ignored. 14026 */ 14027 function __unstableIsLastBlockChangeIgnored(state) { 14028 // TODO: Removal Plan: Changes incurred by RECEIVE_BLOCKS should not be 14029 // ignored if in-fact they result in a change in blocks state. The current 14030 // need to ignore changes not a result of user interaction should be 14031 // accounted for in the refactoring of reusable blocks as occurring within 14032 // their own separate block editor / state (#7119). 14033 return state.blocks.isIgnoredChange; 14034 } 14035 14036 /** 14037 * Returns the block attributes changed as a result of the last dispatched 14038 * action. 14039 * 14040 * @param {Object} state Block editor state. 14041 * 14042 * @return {Object<string,Object>} Subsets of block attributes changed, keyed 14043 * by block client ID. 14044 */ 14045 function __experimentalGetLastBlockAttributeChanges(state) { 14046 return state.lastBlockAttributesChange; 14047 } 14048 14049 /** 14050 * Returns whether the navigation mode is enabled. 14051 * 14052 * @param {Object} state Editor state. 14053 * 14054 * @return {boolean} Is navigation mode enabled. 14055 */ 14056 function isNavigationMode(state) { 14057 return __unstableGetEditorMode(state) === 'navigation'; 14058 } 14059 14060 /** 14061 * Returns the current editor mode. 14062 * 14063 * @param {Object} state Editor state. 14064 * 14065 * @return {string} the editor mode. 14066 */ 14067 const __unstableGetEditorMode = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => state => { 14068 var _state$settings$edito; 14069 if (!window?.__experimentalEditorWriteMode) { 14070 return 'edit'; 14071 } 14072 return (_state$settings$edito = state.settings.editorTool) !== null && _state$settings$edito !== void 0 ? _state$settings$edito : select(external_wp_preferences_namespaceObject.store).get('core', 'editorTool'); 14073 }); 14074 14075 /** 14076 * Returns whether block moving mode is enabled. 14077 * 14078 * @deprecated 14079 */ 14080 function hasBlockMovingClientId() { 14081 external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).hasBlockMovingClientId', { 14082 since: '6.7', 14083 hint: 'Block moving mode feature has been removed' 14084 }); 14085 return false; 14086 } 14087 14088 /** 14089 * Returns true if the last change was an automatic change, false otherwise. 14090 * 14091 * @param {Object} state Global application state. 14092 * 14093 * @return {boolean} Whether the last change was automatic. 14094 */ 14095 function didAutomaticChange(state) { 14096 return !!state.automaticChangeStatus; 14097 } 14098 14099 /** 14100 * Returns true if the current highlighted block matches the block clientId. 14101 * 14102 * @param {Object} state Global application state. 14103 * @param {string} clientId The block to check. 14104 * 14105 * @return {boolean} Whether the block is currently highlighted. 14106 */ 14107 function isBlockHighlighted(state, clientId) { 14108 return state.highlightedBlock === clientId; 14109 } 14110 14111 /** 14112 * Checks if a given block has controlled inner blocks. 14113 * 14114 * @param {Object} state Global application state. 14115 * @param {string} clientId The block to check. 14116 * 14117 * @return {boolean} True if the block has controlled inner blocks. 14118 */ 14119 function areInnerBlocksControlled(state, clientId) { 14120 return !!state.blocks.controlledInnerBlocks[clientId]; 14121 } 14122 14123 /** 14124 * Returns the clientId for the first 'active' block of a given array of block names. 14125 * A block is 'active' if it (or a child) is the selected block. 14126 * Returns the first match moving up the DOM from the selected block. 14127 * 14128 * @param {Object} state Global application state. 14129 * @param {string[]} validBlocksNames The names of block types to check for. 14130 * 14131 * @return {string} The matching block's clientId. 14132 */ 14133 const __experimentalGetActiveBlockIdByBlockNames = (0,external_wp_data_namespaceObject.createSelector)((state, validBlockNames) => { 14134 if (!validBlockNames.length) { 14135 return null; 14136 } 14137 // Check if selected block is a valid entity area. 14138 const selectedBlockClientId = getSelectedBlockClientId(state); 14139 if (validBlockNames.includes(getBlockName(state, selectedBlockClientId))) { 14140 return selectedBlockClientId; 14141 } 14142 // Check if first selected block is a child of a valid entity area. 14143 const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(state); 14144 const entityAreaParents = getBlockParentsByBlockName(state, selectedBlockClientId || multiSelectedBlockClientIds[0], validBlockNames); 14145 if (entityAreaParents) { 14146 // Last parent closest/most interior. 14147 return entityAreaParents[entityAreaParents.length - 1]; 14148 } 14149 return null; 14150 }, (state, validBlockNames) => [state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId, validBlockNames]); 14151 14152 /** 14153 * Tells if the block with the passed clientId was just inserted. 14154 * 14155 * @param {Object} state Global application state. 14156 * @param {Object} clientId Client Id of the block. 14157 * @param {?string} source Optional insertion source of the block. 14158 * @return {boolean} True if the block matches the last block inserted from the specified source. 14159 */ 14160 function wasBlockJustInserted(state, clientId, source) { 14161 const { 14162 lastBlockInserted 14163 } = state; 14164 return lastBlockInserted.clientIds?.includes(clientId) && lastBlockInserted.source === source; 14165 } 14166 14167 /** 14168 * Tells if the block is visible on the canvas or not. 14169 * 14170 * @param {Object} state Global application state. 14171 * @param {Object} clientId Client Id of the block. 14172 * @return {boolean} True if the block is visible. 14173 */ 14174 function isBlockVisible(state, clientId) { 14175 var _state$blockVisibilit; 14176 return (_state$blockVisibilit = state.blockVisibility?.[clientId]) !== null && _state$blockVisibilit !== void 0 ? _state$blockVisibilit : true; 14177 } 14178 14179 /** 14180 * Returns the currently hovered block. 14181 * 14182 * @param {Object} state Global application state. 14183 * @return {Object} Client Id of the hovered block. 14184 */ 14185 function getHoveredBlockClientId(state) { 14186 return state.hoveredBlockClientId; 14187 } 14188 14189 /** 14190 * Returns the list of all hidden blocks. 14191 * 14192 * @param {Object} state Global application state. 14193 * @return {[string]} List of hidden blocks. 14194 */ 14195 const __unstableGetVisibleBlocks = (0,external_wp_data_namespaceObject.createSelector)(state => { 14196 const visibleBlocks = new Set(Object.keys(state.blockVisibility).filter(key => state.blockVisibility[key])); 14197 if (visibleBlocks.size === 0) { 14198 return EMPTY_SET; 14199 } 14200 return visibleBlocks; 14201 }, state => [state.blockVisibility]); 14202 function __unstableHasActiveBlockOverlayActive(state, clientId) { 14203 // Prevent overlay on blocks with a non-default editing mode. If the mode is 14204 // 'disabled' then the overlay is redundant since the block can't be 14205 // selected. If the mode is 'contentOnly' then the overlay is redundant 14206 // since there will be no controls to interact with once selected. 14207 if (getBlockEditingMode(state, clientId) !== 'default') { 14208 return false; 14209 } 14210 14211 // If the block editing is locked, the block overlay is always active. 14212 if (!canEditBlock(state, clientId)) { 14213 return true; 14214 } 14215 14216 // In zoom-out mode, the block overlay is always active for section level blocks. 14217 if (isZoomOut(state)) { 14218 const sectionRootClientId = getSectionRootClientId(state); 14219 if (sectionRootClientId) { 14220 const sectionClientIds = getBlockOrder(state, sectionRootClientId); 14221 if (sectionClientIds?.includes(clientId)) { 14222 return true; 14223 } 14224 } else if (clientId && !getBlockRootClientId(state, clientId)) { 14225 return true; 14226 } 14227 } 14228 14229 // In navigation mode, the block overlay is active when the block is not 14230 // selected (and doesn't contain a selected child). The same behavior is 14231 // also enabled in all modes for blocks that have controlled children 14232 // (reusable block, template part, navigation), unless explicitly disabled 14233 // with `supports.__experimentalDisableBlockOverlay`. 14234 const blockSupportDisable = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(getBlockName(state, clientId), '__experimentalDisableBlockOverlay', false); 14235 const shouldEnableIfUnselected = blockSupportDisable ? false : areInnerBlocksControlled(state, clientId); 14236 return shouldEnableIfUnselected && !isBlockSelected(state, clientId) && !hasSelectedInnerBlock(state, clientId, true); 14237 } 14238 function __unstableIsWithinBlockOverlay(state, clientId) { 14239 let parent = state.blocks.parents.get(clientId); 14240 while (!!parent) { 14241 if (__unstableHasActiveBlockOverlayActive(state, parent)) { 14242 return true; 14243 } 14244 parent = state.blocks.parents.get(parent); 14245 } 14246 return false; 14247 } 14248 14249 /** 14250 * @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode 14251 */ 14252 14253 /** 14254 * Returns the block editing mode for a given block. 14255 * 14256 * The mode can be one of three options: 14257 * 14258 * - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be 14259 * selected. 14260 * - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the 14261 * toolbar, the block movers, block settings. 14262 * - `'default'`: Allows editing the block as normal. 14263 * 14264 * Blocks can set a mode using the `useBlockEditingMode` hook. 14265 * 14266 * The mode is inherited by all of the block's inner blocks, unless they have 14267 * their own mode. 14268 * 14269 * A template lock can also set a mode. If the template lock is `'contentOnly'`, 14270 * the block's mode is overridden to `'contentOnly'` if the block has a content 14271 * role attribute, or `'disabled'` otherwise. 14272 * 14273 * @see useBlockEditingMode 14274 * 14275 * @param {Object} state Global application state. 14276 * @param {string} clientId The block client ID, or `''` for the root container. 14277 * 14278 * @return {BlockEditingMode} The block editing mode. One of `'disabled'`, 14279 * `'contentOnly'`, or `'default'`. 14280 */ 14281 const getBlockEditingMode = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientId = '') => { 14282 // Some selectors that call this provide `null` as the default 14283 // rootClientId, but the default rootClientId is actually `''`. 14284 if (clientId === null) { 14285 clientId = ''; 14286 } 14287 const isNavMode = isNavigationMode(state); 14288 14289 // If the editor is currently not in navigation mode, check if the clientId 14290 // has an editing mode set in the regular derived map. 14291 // There may be an editing mode set here for synced patterns or in zoomed out 14292 // mode. 14293 if (!isNavMode && state.derivedBlockEditingModes?.has(clientId)) { 14294 return state.derivedBlockEditingModes.get(clientId); 14295 } 14296 14297 // If the editor *is* in navigation mode, the block editing mode states 14298 // are stored in the derivedNavModeBlockEditingModes map. 14299 if (isNavMode && state.derivedNavModeBlockEditingModes?.has(clientId)) { 14300 return state.derivedNavModeBlockEditingModes.get(clientId); 14301 } 14302 14303 // In normal mode, consider that an explicitly set editing mode takes over. 14304 const blockEditingMode = state.blockEditingModes.get(clientId); 14305 if (blockEditingMode) { 14306 return blockEditingMode; 14307 } 14308 14309 // In normal mode, top level is default mode. 14310 if (clientId === '') { 14311 return 'default'; 14312 } 14313 const rootClientId = getBlockRootClientId(state, clientId); 14314 const templateLock = getTemplateLock(state, rootClientId); 14315 // If the parent of the block is contentOnly locked, check whether it's a content block. 14316 if (templateLock === 'contentOnly') { 14317 const name = getBlockName(state, clientId); 14318 const { 14319 hasContentRoleAttribute 14320 } = unlock(select(external_wp_blocks_namespaceObject.store)); 14321 const isContent = hasContentRoleAttribute(name); 14322 return isContent ? 'contentOnly' : 'disabled'; 14323 } 14324 return 'default'; 14325 }); 14326 14327 /** 14328 * Indicates if a block is ungroupable. 14329 * A block is ungroupable if it is a single grouping block with inner blocks. 14330 * If a block has an `ungroup` transform, it is also ungroupable, without the 14331 * requirement of being the default grouping block. 14332 * Additionally a block can only be ungrouped if it has inner blocks and can 14333 * be removed. 14334 * 14335 * @param {Object} state Global application state. 14336 * @param {string} clientId Client Id of the block. If not passed the selected block's client id will be used. 14337 * @return {boolean} True if the block is ungroupable. 14338 */ 14339 const isUngroupable = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientId = '') => { 14340 const _clientId = clientId || getSelectedBlockClientId(state); 14341 if (!_clientId) { 14342 return false; 14343 } 14344 const { 14345 getGroupingBlockName 14346 } = select(external_wp_blocks_namespaceObject.store); 14347 const block = getBlock(state, _clientId); 14348 const groupingBlockName = getGroupingBlockName(); 14349 const _isUngroupable = block && (block.name === groupingBlockName || (0,external_wp_blocks_namespaceObject.getBlockType)(block.name)?.transforms?.ungroup) && !!block.innerBlocks.length; 14350 return _isUngroupable && canRemoveBlock(state, _clientId); 14351 }); 14352 14353 /** 14354 * Indicates if the provided blocks(by client ids) are groupable. 14355 * We need to have at least one block, have a grouping block name set and 14356 * be able to remove these blocks. 14357 * 14358 * @param {Object} state Global application state. 14359 * @param {string[]} clientIds Block client ids. If not passed the selected blocks client ids will be used. 14360 * @return {boolean} True if the blocks are groupable. 14361 */ 14362 const isGroupable = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientIds = selectors_EMPTY_ARRAY) => { 14363 const { 14364 getGroupingBlockName 14365 } = select(external_wp_blocks_namespaceObject.store); 14366 const groupingBlockName = getGroupingBlockName(); 14367 const _clientIds = clientIds?.length ? clientIds : getSelectedBlockClientIds(state); 14368 const rootClientId = _clientIds?.length ? getBlockRootClientId(state, _clientIds[0]) : undefined; 14369 const groupingBlockAvailable = canInsertBlockType(state, groupingBlockName, rootClientId); 14370 const _isGroupable = groupingBlockAvailable && _clientIds.length; 14371 return _isGroupable && canRemoveBlocks(state, _clientIds); 14372 }); 14373 14374 /** 14375 * DO-NOT-USE in production. 14376 * This selector is created for internal/experimental only usage and may be 14377 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 14378 * 14379 * @deprecated 14380 * 14381 * @param {Object} state Global application state. 14382 * @param {Object} clientId Client Id of the block. 14383 * 14384 * @return {?string} Client ID of the ancestor block that is content locking the block. 14385 */ 14386 const __unstableGetContentLockingParent = (state, clientId) => { 14387 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetContentLockingParent", { 14388 since: '6.1', 14389 version: '6.7' 14390 }); 14391 return getContentLockingParent(state, clientId); 14392 }; 14393 14394 /** 14395 * DO-NOT-USE in production. 14396 * This selector is created for internal/experimental only usage and may be 14397 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 14398 * 14399 * @deprecated 14400 * 14401 * @param {Object} state Global application state. 14402 */ 14403 function __unstableGetTemporarilyEditingAsBlocks(state) { 14404 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetTemporarilyEditingAsBlocks", { 14405 since: '6.1', 14406 version: '6.7' 14407 }); 14408 return getTemporarilyEditingAsBlocks(state); 14409 } 14410 14411 /** 14412 * DO-NOT-USE in production. 14413 * This selector is created for internal/experimental only usage and may be 14414 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 14415 * 14416 * @deprecated 14417 * 14418 * @param {Object} state Global application state. 14419 */ 14420 function __unstableGetTemporarilyEditingFocusModeToRevert(state) { 14421 external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetTemporarilyEditingFocusModeToRevert", { 14422 since: '6.5', 14423 version: '6.7' 14424 }); 14425 return getTemporarilyEditingFocusModeToRevert(state); 14426 } 14427 14428 ;// external ["wp","a11y"] 14429 const external_wp_a11y_namespaceObject = window["wp"]["a11y"]; 14430 ;// ./node_modules/@wordpress/block-editor/build-module/store/private-actions.js 14431 /** 14432 * WordPress dependencies 14433 */ 14434 14435 14436 14437 14438 14439 /** 14440 * Internal dependencies 14441 */ 14442 14443 14444 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14445 14446 /** 14447 * A list of private/experimental block editor settings that 14448 * should not become a part of the WordPress public API. 14449 * BlockEditorProvider will remove these settings from the 14450 * settings object it receives. 14451 * 14452 * @see https://github.com/WordPress/gutenberg/pull/46131 14453 */ 14454 const privateSettings = ['inserterMediaCategories', 'blockInspectorAnimation', 'mediaSideload']; 14455 14456 /** 14457 * Action that updates the block editor settings and 14458 * conditionally preserves the experimental ones. 14459 * 14460 * @param {Object} settings Updated settings 14461 * @param {Object} options Options object. 14462 * @param {boolean} options.stripExperimentalSettings Whether to strip experimental settings. 14463 * @param {boolean} options.reset Whether to reset the settings. 14464 * @return {Object} Action object 14465 */ 14466 function __experimentalUpdateSettings(settings, { 14467 stripExperimentalSettings = false, 14468 reset = false 14469 } = {}) { 14470 let incomingSettings = settings; 14471 if (Object.hasOwn(incomingSettings, '__unstableIsPreviewMode')) { 14472 external_wp_deprecated_default()("__unstableIsPreviewMode argument in wp.data.dispatch('core/block-editor').updateSettings", { 14473 since: '6.8', 14474 alternative: 'isPreviewMode' 14475 }); 14476 incomingSettings = { 14477 ...incomingSettings 14478 }; 14479 incomingSettings.isPreviewMode = incomingSettings.__unstableIsPreviewMode; 14480 delete incomingSettings.__unstableIsPreviewMode; 14481 } 14482 let cleanSettings = incomingSettings; 14483 14484 // There are no plugins in the mobile apps, so there is no 14485 // need to strip the experimental settings: 14486 if (stripExperimentalSettings && external_wp_element_namespaceObject.Platform.OS === 'web') { 14487 cleanSettings = {}; 14488 for (const key in incomingSettings) { 14489 if (!privateSettings.includes(key)) { 14490 cleanSettings[key] = incomingSettings[key]; 14491 } 14492 } 14493 } 14494 return { 14495 type: 'UPDATE_SETTINGS', 14496 settings: cleanSettings, 14497 reset 14498 }; 14499 } 14500 14501 /** 14502 * Hides the block interface (eg. toolbar, outline, etc.) 14503 * 14504 * @return {Object} Action object. 14505 */ 14506 function hideBlockInterface() { 14507 return { 14508 type: 'HIDE_BLOCK_INTERFACE' 14509 }; 14510 } 14511 14512 /** 14513 * Shows the block interface (eg. toolbar, outline, etc.) 14514 * 14515 * @return {Object} Action object. 14516 */ 14517 function showBlockInterface() { 14518 return { 14519 type: 'SHOW_BLOCK_INTERFACE' 14520 }; 14521 } 14522 14523 /** 14524 * Yields action objects used in signalling that the blocks corresponding to 14525 * the set of specified client IDs are to be removed. 14526 * 14527 * Compared to `removeBlocks`, this private interface exposes an additional 14528 * parameter; see `forceRemove`. 14529 * 14530 * @param {string|string[]} clientIds Client IDs of blocks to remove. 14531 * @param {boolean} selectPrevious True if the previous block 14532 * or the immediate parent 14533 * (if no previous block exists) 14534 * should be selected 14535 * when a block is removed. 14536 * @param {boolean} forceRemove Whether to force the operation, 14537 * bypassing any checks for certain 14538 * block types. 14539 */ 14540 const privateRemoveBlocks = (clientIds, selectPrevious = true, forceRemove = false) => ({ 14541 select, 14542 dispatch, 14543 registry 14544 }) => { 14545 if (!clientIds || !clientIds.length) { 14546 return; 14547 } 14548 clientIds = castArray(clientIds); 14549 const canRemoveBlocks = select.canRemoveBlocks(clientIds); 14550 if (!canRemoveBlocks) { 14551 return; 14552 } 14553 14554 // In certain editing contexts, we'd like to prevent accidental removal 14555 // of important blocks. For example, in the site editor, the Query Loop 14556 // block is deemed important. In such cases, we'll ask the user for 14557 // confirmation that they intended to remove such block(s). However, 14558 // the editor instance is responsible for presenting those confirmation 14559 // prompts to the user. Any instance opting into removal prompts must 14560 // register using `setBlockRemovalRules()`. 14561 // 14562 // @see https://github.com/WordPress/gutenberg/pull/51145 14563 const rules = !forceRemove && select.getBlockRemovalRules(); 14564 if (rules) { 14565 function flattenBlocks(blocks) { 14566 const result = []; 14567 const stack = [...blocks]; 14568 while (stack.length) { 14569 const { 14570 innerBlocks, 14571 ...block 14572 } = stack.shift(); 14573 stack.push(...innerBlocks); 14574 result.push(block); 14575 } 14576 return result; 14577 } 14578 const blockList = clientIds.map(select.getBlock); 14579 const flattenedBlocks = flattenBlocks(blockList); 14580 14581 // Find the first message and use it. 14582 let message; 14583 for (const rule of rules) { 14584 message = rule.callback(flattenedBlocks); 14585 if (message) { 14586 dispatch(displayBlockRemovalPrompt(clientIds, selectPrevious, message)); 14587 return; 14588 } 14589 } 14590 } 14591 if (selectPrevious) { 14592 dispatch.selectPreviousBlock(clientIds[0], selectPrevious); 14593 } 14594 14595 // We're batching these two actions because an extra `undo/redo` step can 14596 // be created, based on whether we insert a default block or not. 14597 registry.batch(() => { 14598 dispatch({ 14599 type: 'REMOVE_BLOCKS', 14600 clientIds 14601 }); 14602 // To avoid a focus loss when removing the last block, assure there is 14603 // always a default block if the last of the blocks have been removed. 14604 dispatch(ensureDefaultBlock()); 14605 }); 14606 }; 14607 14608 /** 14609 * Action which will insert a default block insert action if there 14610 * are no other blocks at the root of the editor. This action should be used 14611 * in actions which may result in no blocks remaining in the editor (removal, 14612 * replacement, etc). 14613 */ 14614 const ensureDefaultBlock = () => ({ 14615 select, 14616 dispatch 14617 }) => { 14618 // To avoid a focus loss when removing the last block, assure there is 14619 // always a default block if the last of the blocks have been removed. 14620 const count = select.getBlockCount(); 14621 if (count > 0) { 14622 return; 14623 } 14624 14625 // If there's an custom appender, don't insert default block. 14626 // We have to remember to manually move the focus elsewhere to 14627 // prevent it from being lost though. 14628 const { 14629 __unstableHasCustomAppender 14630 } = select.getSettings(); 14631 if (__unstableHasCustomAppender) { 14632 return; 14633 } 14634 dispatch.insertDefaultBlock(); 14635 }; 14636 14637 /** 14638 * Returns an action object used in signalling that a block removal prompt must 14639 * be displayed. 14640 * 14641 * Contrast with `setBlockRemovalRules`. 14642 * 14643 * @param {string|string[]} clientIds Client IDs of blocks to remove. 14644 * @param {boolean} selectPrevious True if the previous block or the 14645 * immediate parent (if no previous 14646 * block exists) should be selected 14647 * when a block is removed. 14648 * @param {string} message Message to display in the prompt. 14649 * 14650 * @return {Object} Action object. 14651 */ 14652 function displayBlockRemovalPrompt(clientIds, selectPrevious, message) { 14653 return { 14654 type: 'DISPLAY_BLOCK_REMOVAL_PROMPT', 14655 clientIds, 14656 selectPrevious, 14657 message 14658 }; 14659 } 14660 14661 /** 14662 * Returns an action object used in signalling that a block removal prompt must 14663 * be cleared, either be cause the user has confirmed or canceled the request 14664 * for removal. 14665 * 14666 * @return {Object} Action object. 14667 */ 14668 function clearBlockRemovalPrompt() { 14669 return { 14670 type: 'CLEAR_BLOCK_REMOVAL_PROMPT' 14671 }; 14672 } 14673 14674 /** 14675 * Returns an action object used to set up any rules that a block editor may 14676 * provide in order to prevent a user from accidentally removing certain 14677 * blocks. These rules are then used to display a confirmation prompt to the 14678 * user. For instance, in the Site Editor, the Query Loop block is important 14679 * enough to warrant such confirmation. 14680 * 14681 * IMPORTANT: Registering rules implicitly signals to the `privateRemoveBlocks` 14682 * action that the editor will be responsible for displaying block removal 14683 * prompts and confirming deletions. This action is meant to be used by 14684 * component `BlockRemovalWarningModal` only. 14685 * 14686 * The data is a record whose keys are block types (e.g. 'core/query') and 14687 * whose values are the explanation to be shown to users (e.g. 'Query Loop 14688 * displays a list of posts or pages.'). 14689 * 14690 * Contrast with `displayBlockRemovalPrompt`. 14691 * 14692 * @param {Record<string,string>|false} rules Block removal rules. 14693 * @return {Object} Action object. 14694 */ 14695 function setBlockRemovalRules(rules = false) { 14696 return { 14697 type: 'SET_BLOCK_REMOVAL_RULES', 14698 rules 14699 }; 14700 } 14701 14702 /** 14703 * Sets the client ID of the block settings menu that is currently open. 14704 * 14705 * @param {?string} clientId The block client ID. 14706 * @return {Object} Action object. 14707 */ 14708 function setOpenedBlockSettingsMenu(clientId) { 14709 return { 14710 type: 'SET_OPENED_BLOCK_SETTINGS_MENU', 14711 clientId 14712 }; 14713 } 14714 function setStyleOverride(id, style) { 14715 return { 14716 type: 'SET_STYLE_OVERRIDE', 14717 id, 14718 style 14719 }; 14720 } 14721 function deleteStyleOverride(id) { 14722 return { 14723 type: 'DELETE_STYLE_OVERRIDE', 14724 id 14725 }; 14726 } 14727 14728 /** 14729 * Action that sets the element that had focus when focus leaves the editor canvas. 14730 * 14731 * @param {Object} lastFocus The last focused element. 14732 * 14733 * 14734 * @return {Object} Action object. 14735 */ 14736 function setLastFocus(lastFocus = null) { 14737 return { 14738 type: 'LAST_FOCUS', 14739 lastFocus 14740 }; 14741 } 14742 14743 /** 14744 * Action that stops temporarily editing as blocks. 14745 * 14746 * @param {string} clientId The block's clientId. 14747 */ 14748 function stopEditingAsBlocks(clientId) { 14749 return ({ 14750 select, 14751 dispatch, 14752 registry 14753 }) => { 14754 const focusModeToRevert = unlock(registry.select(store)).getTemporarilyEditingFocusModeToRevert(); 14755 dispatch.__unstableMarkNextChangeAsNotPersistent(); 14756 dispatch.updateBlockAttributes(clientId, { 14757 templateLock: 'contentOnly' 14758 }); 14759 dispatch.updateBlockListSettings(clientId, { 14760 ...select.getBlockListSettings(clientId), 14761 templateLock: 'contentOnly' 14762 }); 14763 dispatch.updateSettings({ 14764 focusMode: focusModeToRevert 14765 }); 14766 dispatch.__unstableSetTemporarilyEditingAsBlocks(); 14767 }; 14768 } 14769 14770 /** 14771 * Returns an action object used in signalling that the user has begun to drag. 14772 * 14773 * @return {Object} Action object. 14774 */ 14775 function startDragging() { 14776 return { 14777 type: 'START_DRAGGING' 14778 }; 14779 } 14780 14781 /** 14782 * Returns an action object used in signalling that the user has stopped dragging. 14783 * 14784 * @return {Object} Action object. 14785 */ 14786 function stopDragging() { 14787 return { 14788 type: 'STOP_DRAGGING' 14789 }; 14790 } 14791 14792 /** 14793 * @param {string|null} clientId The block's clientId, or `null` to clear. 14794 * 14795 * @return {Object} Action object. 14796 */ 14797 function expandBlock(clientId) { 14798 return { 14799 type: 'SET_BLOCK_EXPANDED_IN_LIST_VIEW', 14800 clientId 14801 }; 14802 } 14803 14804 /** 14805 * @param {Object} value 14806 * @param {string} value.rootClientId The root client ID to insert at. 14807 * @param {number} value.index The index to insert at. 14808 * 14809 * @return {Object} Action object. 14810 */ 14811 function setInsertionPoint(value) { 14812 return { 14813 type: 'SET_INSERTION_POINT', 14814 value 14815 }; 14816 } 14817 14818 /** 14819 * Temporarily modify/unlock the content-only block for editions. 14820 * 14821 * @param {string} clientId The client id of the block. 14822 */ 14823 const modifyContentLockBlock = clientId => ({ 14824 select, 14825 dispatch 14826 }) => { 14827 dispatch.selectBlock(clientId); 14828 dispatch.__unstableMarkNextChangeAsNotPersistent(); 14829 dispatch.updateBlockAttributes(clientId, { 14830 templateLock: undefined 14831 }); 14832 dispatch.updateBlockListSettings(clientId, { 14833 ...select.getBlockListSettings(clientId), 14834 templateLock: false 14835 }); 14836 const focusModeToRevert = select.getSettings().focusMode; 14837 dispatch.updateSettings({ 14838 focusMode: true 14839 }); 14840 dispatch.__unstableSetTemporarilyEditingAsBlocks(clientId, focusModeToRevert); 14841 }; 14842 14843 /** 14844 * Sets the zoom level. 14845 * 14846 * @param {number} zoom the new zoom level 14847 * @return {Object} Action object. 14848 */ 14849 const setZoomLevel = (zoom = 100) => ({ 14850 select, 14851 dispatch 14852 }) => { 14853 // When switching to zoom-out mode, we need to select the parent section 14854 if (zoom !== 100) { 14855 const firstSelectedClientId = select.getBlockSelectionStart(); 14856 const sectionRootClientId = select.getSectionRootClientId(); 14857 if (firstSelectedClientId) { 14858 let sectionClientId; 14859 if (sectionRootClientId) { 14860 const sectionClientIds = select.getBlockOrder(sectionRootClientId); 14861 14862 // If the selected block is a section block, use it. 14863 if (sectionClientIds?.includes(firstSelectedClientId)) { 14864 sectionClientId = firstSelectedClientId; 14865 } else { 14866 // If the selected block is not a section block, find 14867 // the parent section that contains the selected block. 14868 sectionClientId = select.getBlockParents(firstSelectedClientId).find(parent => sectionClientIds.includes(parent)); 14869 } 14870 } else { 14871 sectionClientId = select.getBlockHierarchyRootClientId(firstSelectedClientId); 14872 } 14873 if (sectionClientId) { 14874 dispatch.selectBlock(sectionClientId); 14875 } else { 14876 dispatch.clearSelectedBlock(); 14877 } 14878 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in zoom-out mode.')); 14879 } 14880 } 14881 dispatch({ 14882 type: 'SET_ZOOM_LEVEL', 14883 zoom 14884 }); 14885 }; 14886 14887 /** 14888 * Resets the Zoom state. 14889 * @return {Object} Action object. 14890 */ 14891 function resetZoomLevel() { 14892 return { 14893 type: 'RESET_ZOOM_LEVEL' 14894 }; 14895 } 14896 14897 ;// external ["wp","notices"] 14898 const external_wp_notices_namespaceObject = window["wp"]["notices"]; 14899 ;// ./node_modules/@wordpress/block-editor/build-module/utils/selection.js 14900 /** 14901 * WordPress dependencies 14902 */ 14903 14904 14905 /** 14906 * A robust way to retain selection position through various 14907 * transforms is to insert a special character at the position and 14908 * then recover it. 14909 */ 14910 const START_OF_SELECTED_AREA = '\u0086'; 14911 14912 /** 14913 * Retrieve the block attribute that contains the selection position. 14914 * 14915 * @param {Object} blockAttributes Block attributes. 14916 * @return {string|void} The name of the block attribute that was previously selected. 14917 */ 14918 function retrieveSelectedAttribute(blockAttributes) { 14919 if (!blockAttributes) { 14920 return; 14921 } 14922 return Object.keys(blockAttributes).find(name => { 14923 const value = blockAttributes[name]; 14924 return (typeof value === 'string' || value instanceof external_wp_richText_namespaceObject.RichTextData) && 14925 // To do: refactor this to use rich text's selection instead, so we 14926 // no longer have to use on this hack inserting a special character. 14927 value.toString().indexOf(START_OF_SELECTED_AREA) !== -1; 14928 }); 14929 } 14930 function findRichTextAttributeKey(blockType) { 14931 for (const [key, value] of Object.entries(blockType.attributes)) { 14932 if (value.source === 'rich-text' || value.source === 'html') { 14933 return key; 14934 } 14935 } 14936 } 14937 14938 ;// ./node_modules/@wordpress/block-editor/build-module/store/actions.js 14939 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ 14940 /** 14941 * WordPress dependencies 14942 */ 14943 14944 14945 14946 14947 14948 14949 14950 14951 /** 14952 * Internal dependencies 14953 */ 14954 14955 14956 14957 /** @typedef {import('../components/use-on-block-drop/types').WPDropOperation} WPDropOperation */ 14958 14959 const actions_castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14960 14961 /** 14962 * Action that resets blocks state to the specified array of blocks, taking precedence 14963 * over any other content reflected as an edit in state. 14964 * 14965 * @param {Array} blocks Array of blocks. 14966 */ 14967 const resetBlocks = blocks => ({ 14968 dispatch 14969 }) => { 14970 dispatch({ 14971 type: 'RESET_BLOCKS', 14972 blocks 14973 }); 14974 dispatch(validateBlocksToTemplate(blocks)); 14975 }; 14976 14977 /** 14978 * Block validity is a function of blocks state (at the point of a 14979 * reset) and the template setting. As a compromise to its placement 14980 * across distinct parts of state, it is implemented here as a side 14981 * effect of the block reset action. 14982 * 14983 * @param {Array} blocks Array of blocks. 14984 */ 14985 const validateBlocksToTemplate = blocks => ({ 14986 select, 14987 dispatch 14988 }) => { 14989 const template = select.getTemplate(); 14990 const templateLock = select.getTemplateLock(); 14991 14992 // Unlocked templates are considered always valid because they act 14993 // as default values only. 14994 const isBlocksValidToTemplate = !template || templateLock !== 'all' || (0,external_wp_blocks_namespaceObject.doBlocksMatchTemplate)(blocks, template); 14995 14996 // Update if validity has changed. 14997 const isValidTemplate = select.isValidTemplate(); 14998 if (isBlocksValidToTemplate !== isValidTemplate) { 14999 dispatch.setTemplateValidity(isBlocksValidToTemplate); 15000 return isBlocksValidToTemplate; 15001 } 15002 }; 15003 15004 /** 15005 * A block selection object. 15006 * 15007 * @typedef {Object} WPBlockSelection 15008 * 15009 * @property {string} clientId A block client ID. 15010 * @property {string} attributeKey A block attribute key. 15011 * @property {number} offset An attribute value offset, based on the rich 15012 * text value. See `wp.richText.create`. 15013 */ 15014 15015 /** 15016 * A selection object. 15017 * 15018 * @typedef {Object} WPSelection 15019 * 15020 * @property {WPBlockSelection} start The selection start. 15021 * @property {WPBlockSelection} end The selection end. 15022 */ 15023 15024 /* eslint-disable jsdoc/valid-types */ 15025 /** 15026 * Returns an action object used in signalling that selection state should be 15027 * reset to the specified selection. 15028 * 15029 * @param {WPBlockSelection} selectionStart The selection start. 15030 * @param {WPBlockSelection} selectionEnd The selection end. 15031 * @param {0|-1|null} initialPosition Initial block position. 15032 * 15033 * @return {Object} Action object. 15034 */ 15035 function resetSelection(selectionStart, selectionEnd, initialPosition) { 15036 /* eslint-enable jsdoc/valid-types */ 15037 return { 15038 type: 'RESET_SELECTION', 15039 selectionStart, 15040 selectionEnd, 15041 initialPosition 15042 }; 15043 } 15044 15045 /** 15046 * Returns an action object used in signalling that blocks have been received. 15047 * Unlike resetBlocks, these should be appended to the existing known set, not 15048 * replacing. 15049 * 15050 * @deprecated 15051 * 15052 * @param {Object[]} blocks Array of block objects. 15053 * 15054 * @return {Object} Action object. 15055 */ 15056 function receiveBlocks(blocks) { 15057 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).receiveBlocks', { 15058 since: '5.9', 15059 alternative: 'resetBlocks or insertBlocks' 15060 }); 15061 return { 15062 type: 'RECEIVE_BLOCKS', 15063 blocks 15064 }; 15065 } 15066 15067 /** 15068 * Action that updates attributes of multiple blocks with the specified client IDs. 15069 * 15070 * @param {string|string[]} clientIds Block client IDs. 15071 * @param {Object} attributes Block attributes to be merged. Should be keyed by clientIds if 15072 * uniqueByBlock is true. 15073 * @param {boolean} uniqueByBlock true if each block in clientIds array has a unique set of attributes 15074 * @return {Object} Action object. 15075 */ 15076 function updateBlockAttributes(clientIds, attributes, uniqueByBlock = false) { 15077 return { 15078 type: 'UPDATE_BLOCK_ATTRIBUTES', 15079 clientIds: actions_castArray(clientIds), 15080 attributes, 15081 uniqueByBlock 15082 }; 15083 } 15084 15085 /** 15086 * Action that updates the block with the specified client ID. 15087 * 15088 * @param {string} clientId Block client ID. 15089 * @param {Object} updates Block attributes to be merged. 15090 * 15091 * @return {Object} Action object. 15092 */ 15093 function updateBlock(clientId, updates) { 15094 return { 15095 type: 'UPDATE_BLOCK', 15096 clientId, 15097 updates 15098 }; 15099 } 15100 15101 /* eslint-disable jsdoc/valid-types */ 15102 /** 15103 * Returns an action object used in signalling that the block with the 15104 * specified client ID has been selected, optionally accepting a position 15105 * value reflecting its selection directionality. An initialPosition of -1 15106 * reflects a reverse selection. 15107 * 15108 * @param {string} clientId Block client ID. 15109 * @param {0|-1|null} initialPosition Optional initial position. Pass as -1 to 15110 * reflect reverse selection. 15111 * 15112 * @return {Object} Action object. 15113 */ 15114 function selectBlock(clientId, initialPosition = 0) { 15115 /* eslint-enable jsdoc/valid-types */ 15116 return { 15117 type: 'SELECT_BLOCK', 15118 initialPosition, 15119 clientId 15120 }; 15121 } 15122 15123 /** 15124 * Returns an action object used in signalling that the block with the 15125 * specified client ID has been hovered. 15126 * 15127 * @param {string} clientId Block client ID. 15128 * 15129 * @return {Object} Action object. 15130 */ 15131 function hoverBlock(clientId) { 15132 return { 15133 type: 'HOVER_BLOCK', 15134 clientId 15135 }; 15136 } 15137 15138 /** 15139 * Yields action objects used in signalling that the block preceding the given 15140 * clientId (or optionally, its first parent from bottom to top) 15141 * should be selected. 15142 * 15143 * @param {string} clientId Block client ID. 15144 * @param {boolean} fallbackToParent If true, select the first parent if there is no previous block. 15145 */ 15146 const selectPreviousBlock = (clientId, fallbackToParent = false) => ({ 15147 select, 15148 dispatch 15149 }) => { 15150 const previousBlockClientId = select.getPreviousBlockClientId(clientId); 15151 if (previousBlockClientId) { 15152 dispatch.selectBlock(previousBlockClientId, -1); 15153 } else if (fallbackToParent) { 15154 const firstParentClientId = select.getBlockRootClientId(clientId); 15155 if (firstParentClientId) { 15156 dispatch.selectBlock(firstParentClientId, -1); 15157 } 15158 } 15159 }; 15160 15161 /** 15162 * Yields action objects used in signalling that the block following the given 15163 * clientId should be selected. 15164 * 15165 * @param {string} clientId Block client ID. 15166 */ 15167 const selectNextBlock = clientId => ({ 15168 select, 15169 dispatch 15170 }) => { 15171 const nextBlockClientId = select.getNextBlockClientId(clientId); 15172 if (nextBlockClientId) { 15173 dispatch.selectBlock(nextBlockClientId); 15174 } 15175 }; 15176 15177 /** 15178 * Action that starts block multi-selection. 15179 * 15180 * @return {Object} Action object. 15181 */ 15182 function startMultiSelect() { 15183 return { 15184 type: 'START_MULTI_SELECT' 15185 }; 15186 } 15187 15188 /** 15189 * Action that stops block multi-selection. 15190 * 15191 * @return {Object} Action object. 15192 */ 15193 function stopMultiSelect() { 15194 return { 15195 type: 'STOP_MULTI_SELECT' 15196 }; 15197 } 15198 15199 /** 15200 * Action that changes block multi-selection. 15201 * 15202 * @param {string} start First block of the multi selection. 15203 * @param {string} end Last block of the multiselection. 15204 * @param {number|null} __experimentalInitialPosition Optional initial position. Pass as null to skip focus within editor canvas. 15205 */ 15206 const multiSelect = (start, end, __experimentalInitialPosition = 0) => ({ 15207 select, 15208 dispatch 15209 }) => { 15210 const startBlockRootClientId = select.getBlockRootClientId(start); 15211 const endBlockRootClientId = select.getBlockRootClientId(end); 15212 15213 // Only allow block multi-selections at the same level. 15214 if (startBlockRootClientId !== endBlockRootClientId) { 15215 return; 15216 } 15217 dispatch({ 15218 type: 'MULTI_SELECT', 15219 start, 15220 end, 15221 initialPosition: __experimentalInitialPosition 15222 }); 15223 const blockCount = select.getSelectedBlockCount(); 15224 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: number of selected blocks */ 15225 (0,external_wp_i18n_namespaceObject._n)('%s block selected.', '%s blocks selected.', blockCount), blockCount), 'assertive'); 15226 }; 15227 15228 /** 15229 * Action that clears the block selection. 15230 * 15231 * @return {Object} Action object. 15232 */ 15233 function clearSelectedBlock() { 15234 return { 15235 type: 'CLEAR_SELECTED_BLOCK' 15236 }; 15237 } 15238 15239 /** 15240 * Action that enables or disables block selection. 15241 * 15242 * @param {boolean} [isSelectionEnabled=true] Whether block selection should 15243 * be enabled. 15244 * 15245 * @return {Object} Action object. 15246 */ 15247 function toggleSelection(isSelectionEnabled = true) { 15248 return { 15249 type: 'TOGGLE_SELECTION', 15250 isSelectionEnabled 15251 }; 15252 } 15253 15254 /* eslint-disable jsdoc/valid-types */ 15255 /** 15256 * Action that replaces given blocks with one or more replacement blocks. 15257 * 15258 * @param {(string|string[])} clientIds Block client ID(s) to replace. 15259 * @param {(Object|Object[])} blocks Replacement block(s). 15260 * @param {number} indexToSelect Index of replacement block to select. 15261 * @param {0|-1|null} initialPosition Index of caret after in the selected block after the operation. 15262 * @param {?Object} meta Optional Meta values to be passed to the action object. 15263 * 15264 * @return {Object} Action object. 15265 */ 15266 const replaceBlocks = (clientIds, blocks, indexToSelect, initialPosition = 0, meta) => ({ 15267 select, 15268 dispatch, 15269 registry 15270 }) => { 15271 /* eslint-enable jsdoc/valid-types */ 15272 clientIds = actions_castArray(clientIds); 15273 blocks = actions_castArray(blocks); 15274 const rootClientId = select.getBlockRootClientId(clientIds[0]); 15275 // Replace is valid if the new blocks can be inserted in the root block. 15276 for (let index = 0; index < blocks.length; index++) { 15277 const block = blocks[index]; 15278 const canInsertBlock = select.canInsertBlockType(block.name, rootClientId); 15279 if (!canInsertBlock) { 15280 return; 15281 } 15282 } 15283 // We're batching these two actions because an extra `undo/redo` step can 15284 // be created, based on whether we insert a default block or not. 15285 registry.batch(() => { 15286 dispatch({ 15287 type: 'REPLACE_BLOCKS', 15288 clientIds, 15289 blocks, 15290 time: Date.now(), 15291 indexToSelect, 15292 initialPosition, 15293 meta 15294 }); 15295 // To avoid a focus loss when removing the last block, assure there is 15296 // always a default block if the last of the blocks have been removed. 15297 dispatch.ensureDefaultBlock(); 15298 }); 15299 }; 15300 15301 /** 15302 * Action that replaces a single block with one or more replacement blocks. 15303 * 15304 * @param {(string|string[])} clientId Block client ID to replace. 15305 * @param {(Object|Object[])} block Replacement block(s). 15306 * 15307 * @return {Object} Action object. 15308 */ 15309 function replaceBlock(clientId, block) { 15310 return replaceBlocks(clientId, block); 15311 } 15312 15313 /** 15314 * Higher-order action creator which, given the action type to dispatch creates 15315 * an action creator for managing block movement. 15316 * 15317 * @param {string} type Action type to dispatch. 15318 * 15319 * @return {Function} Action creator. 15320 */ 15321 const createOnMove = type => (clientIds, rootClientId) => ({ 15322 select, 15323 dispatch 15324 }) => { 15325 // If one of the blocks is locked or the parent is locked, we cannot move any block. 15326 const canMoveBlocks = select.canMoveBlocks(clientIds); 15327 if (!canMoveBlocks) { 15328 return; 15329 } 15330 dispatch({ 15331 type, 15332 clientIds: actions_castArray(clientIds), 15333 rootClientId 15334 }); 15335 }; 15336 const moveBlocksDown = createOnMove('MOVE_BLOCKS_DOWN'); 15337 const moveBlocksUp = createOnMove('MOVE_BLOCKS_UP'); 15338 15339 /** 15340 * Action that moves given blocks to a new position. 15341 * 15342 * @param {?string} clientIds The client IDs of the blocks. 15343 * @param {?string} fromRootClientId Root client ID source. 15344 * @param {?string} toRootClientId Root client ID destination. 15345 * @param {number} index The index to move the blocks to. 15346 */ 15347 const moveBlocksToPosition = (clientIds, fromRootClientId = '', toRootClientId = '', index) => ({ 15348 select, 15349 dispatch 15350 }) => { 15351 const canMoveBlocks = select.canMoveBlocks(clientIds); 15352 15353 // If one of the blocks is locked or the parent is locked, we cannot move any block. 15354 if (!canMoveBlocks) { 15355 return; 15356 } 15357 15358 // If moving inside the same root block the move is always possible. 15359 if (fromRootClientId !== toRootClientId) { 15360 const canRemoveBlocks = select.canRemoveBlocks(clientIds); 15361 15362 // If we're moving to another block, it means we're deleting blocks from 15363 // the original block, so we need to check if removing is possible. 15364 if (!canRemoveBlocks) { 15365 return; 15366 } 15367 const canInsertBlocks = select.canInsertBlocks(clientIds, toRootClientId); 15368 15369 // 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. 15370 if (!canInsertBlocks) { 15371 return; 15372 } 15373 } 15374 dispatch({ 15375 type: 'MOVE_BLOCKS_TO_POSITION', 15376 fromRootClientId, 15377 toRootClientId, 15378 clientIds, 15379 index 15380 }); 15381 }; 15382 15383 /** 15384 * Action that moves given block to a new position. 15385 * 15386 * @param {?string} clientId The client ID of the block. 15387 * @param {?string} fromRootClientId Root client ID source. 15388 * @param {?string} toRootClientId Root client ID destination. 15389 * @param {number} index The index to move the block to. 15390 */ 15391 function moveBlockToPosition(clientId, fromRootClientId = '', toRootClientId = '', index) { 15392 return moveBlocksToPosition([clientId], fromRootClientId, toRootClientId, index); 15393 } 15394 15395 /** 15396 * Action that inserts a single block, optionally at a specific index respective a root block list. 15397 * 15398 * Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if 15399 * a templateLock is active on the block list. 15400 * 15401 * @param {Object} block Block object to insert. 15402 * @param {?number} index Index at which block should be inserted. 15403 * @param {?string} rootClientId Optional root client ID of block list on which to insert. 15404 * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true. 15405 * @param {?Object} meta Optional Meta values to be passed to the action object. 15406 * 15407 * @return {Object} Action object. 15408 */ 15409 function insertBlock(block, index, rootClientId, updateSelection, meta) { 15410 return insertBlocks([block], index, rootClientId, updateSelection, 0, meta); 15411 } 15412 15413 /* eslint-disable jsdoc/valid-types */ 15414 /** 15415 * Action that inserts an array of blocks, optionally at a specific index respective a root block list. 15416 * 15417 * Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if 15418 * a templateLock is active on the block list. 15419 * 15420 * @param {Object[]} blocks Block objects to insert. 15421 * @param {?number} index Index at which block should be inserted. 15422 * @param {?string} rootClientId Optional root client ID of block list on which to insert. 15423 * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true. 15424 * @param {0|-1|null} initialPosition Initial focus position. Setting it to null prevent focusing the inserted block. 15425 * @param {?Object} meta Optional Meta values to be passed to the action object. 15426 * 15427 * @return {Object} Action object. 15428 */ 15429 const insertBlocks = (blocks, index, rootClientId, updateSelection = true, initialPosition = 0, meta) => ({ 15430 select, 15431 dispatch 15432 }) => { 15433 /* eslint-enable jsdoc/valid-types */ 15434 if (initialPosition !== null && typeof initialPosition === 'object') { 15435 meta = initialPosition; 15436 initialPosition = 0; 15437 external_wp_deprecated_default()("meta argument in wp.data.dispatch('core/block-editor')", { 15438 since: '5.8', 15439 hint: 'The meta argument is now the 6th argument of the function' 15440 }); 15441 } 15442 blocks = actions_castArray(blocks); 15443 const allowedBlocks = []; 15444 for (const block of blocks) { 15445 const isValid = select.canInsertBlockType(block.name, rootClientId); 15446 if (isValid) { 15447 allowedBlocks.push(block); 15448 } 15449 } 15450 if (allowedBlocks.length) { 15451 dispatch({ 15452 type: 'INSERT_BLOCKS', 15453 blocks: allowedBlocks, 15454 index, 15455 rootClientId, 15456 time: Date.now(), 15457 updateSelection, 15458 initialPosition: updateSelection ? initialPosition : null, 15459 meta 15460 }); 15461 } 15462 }; 15463 15464 /** 15465 * Action that shows the insertion point. 15466 * 15467 * @param {?string} rootClientId Optional root client ID of block list on 15468 * which to insert. 15469 * @param {?number} index Index at which block should be inserted. 15470 * @param {?Object} __unstableOptions Additional options. 15471 * @property {boolean} __unstableWithInserter Whether or not to show an inserter button. 15472 * @property {WPDropOperation} operation The operation to perform when applied, 15473 * either 'insert' or 'replace' for now. 15474 * 15475 * @return {Object} Action object. 15476 */ 15477 function showInsertionPoint(rootClientId, index, __unstableOptions = {}) { 15478 const { 15479 __unstableWithInserter, 15480 operation, 15481 nearestSide 15482 } = __unstableOptions; 15483 return { 15484 type: 'SHOW_INSERTION_POINT', 15485 rootClientId, 15486 index, 15487 __unstableWithInserter, 15488 operation, 15489 nearestSide 15490 }; 15491 } 15492 /** 15493 * Action that hides the insertion point. 15494 */ 15495 const hideInsertionPoint = () => ({ 15496 select, 15497 dispatch 15498 }) => { 15499 if (!select.isBlockInsertionPointVisible()) { 15500 return; 15501 } 15502 dispatch({ 15503 type: 'HIDE_INSERTION_POINT' 15504 }); 15505 }; 15506 15507 /** 15508 * Action that resets the template validity. 15509 * 15510 * @param {boolean} isValid template validity flag. 15511 * 15512 * @return {Object} Action object. 15513 */ 15514 function setTemplateValidity(isValid) { 15515 return { 15516 type: 'SET_TEMPLATE_VALIDITY', 15517 isValid 15518 }; 15519 } 15520 15521 /** 15522 * Action that synchronizes the template with the list of blocks. 15523 * 15524 * @return {Object} Action object. 15525 */ 15526 const synchronizeTemplate = () => ({ 15527 select, 15528 dispatch 15529 }) => { 15530 dispatch({ 15531 type: 'SYNCHRONIZE_TEMPLATE' 15532 }); 15533 const blocks = select.getBlocks(); 15534 const template = select.getTemplate(); 15535 const updatedBlockList = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(blocks, template); 15536 dispatch.resetBlocks(updatedBlockList); 15537 }; 15538 15539 /** 15540 * Delete the current selection. 15541 * 15542 * @param {boolean} isForward 15543 */ 15544 const __unstableDeleteSelection = isForward => ({ 15545 registry, 15546 select, 15547 dispatch 15548 }) => { 15549 const selectionAnchor = select.getSelectionStart(); 15550 const selectionFocus = select.getSelectionEnd(); 15551 if (selectionAnchor.clientId === selectionFocus.clientId) { 15552 return; 15553 } 15554 15555 // It's not mergeable if there's no rich text selection. 15556 if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') { 15557 return false; 15558 } 15559 const anchorRootClientId = select.getBlockRootClientId(selectionAnchor.clientId); 15560 const focusRootClientId = select.getBlockRootClientId(selectionFocus.clientId); 15561 15562 // It's not mergeable if the selection doesn't start and end in the same 15563 // block list. Maybe in the future it should be allowed. 15564 if (anchorRootClientId !== focusRootClientId) { 15565 return; 15566 } 15567 const blockOrder = select.getBlockOrder(anchorRootClientId); 15568 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 15569 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 15570 15571 // Reassign selection start and end based on order. 15572 let selectionStart, selectionEnd; 15573 if (anchorIndex > focusIndex) { 15574 selectionStart = selectionFocus; 15575 selectionEnd = selectionAnchor; 15576 } else { 15577 selectionStart = selectionAnchor; 15578 selectionEnd = selectionFocus; 15579 } 15580 const targetSelection = isForward ? selectionEnd : selectionStart; 15581 const targetBlock = select.getBlock(targetSelection.clientId); 15582 const targetBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlock.name); 15583 if (!targetBlockType.merge) { 15584 return; 15585 } 15586 const selectionA = selectionStart; 15587 const selectionB = selectionEnd; 15588 const blockA = select.getBlock(selectionA.clientId); 15589 const blockB = select.getBlock(selectionB.clientId); 15590 const htmlA = blockA.attributes[selectionA.attributeKey]; 15591 const htmlB = blockB.attributes[selectionB.attributeKey]; 15592 let valueA = (0,external_wp_richText_namespaceObject.create)({ 15593 html: htmlA 15594 }); 15595 let valueB = (0,external_wp_richText_namespaceObject.create)({ 15596 html: htmlB 15597 }); 15598 valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, selectionA.offset, valueA.text.length); 15599 valueB = (0,external_wp_richText_namespaceObject.insert)(valueB, START_OF_SELECTED_AREA, 0, selectionB.offset); 15600 15601 // Clone the blocks so we don't manipulate the original. 15602 const cloneA = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockA, { 15603 [selectionA.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15604 value: valueA 15605 }) 15606 }); 15607 const cloneB = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockB, { 15608 [selectionB.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15609 value: valueB 15610 }) 15611 }); 15612 const followingBlock = isForward ? cloneA : cloneB; 15613 15614 // We can only merge blocks with similar types 15615 // thus, we transform the block to merge first 15616 const blocksWithTheSameType = blockA.name === blockB.name ? [followingBlock] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(followingBlock, targetBlockType.name); 15617 15618 // If the block types can not match, do nothing 15619 if (!blocksWithTheSameType || !blocksWithTheSameType.length) { 15620 return; 15621 } 15622 let updatedAttributes; 15623 if (isForward) { 15624 const blockToMerge = blocksWithTheSameType.pop(); 15625 updatedAttributes = targetBlockType.merge(blockToMerge.attributes, cloneB.attributes); 15626 } else { 15627 const blockToMerge = blocksWithTheSameType.shift(); 15628 updatedAttributes = targetBlockType.merge(cloneA.attributes, blockToMerge.attributes); 15629 } 15630 const newAttributeKey = retrieveSelectedAttribute(updatedAttributes); 15631 const convertedHtml = updatedAttributes[newAttributeKey]; 15632 const convertedValue = (0,external_wp_richText_namespaceObject.create)({ 15633 html: convertedHtml 15634 }); 15635 const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA); 15636 const newValue = (0,external_wp_richText_namespaceObject.remove)(convertedValue, newOffset, newOffset + 1); 15637 const newHtml = (0,external_wp_richText_namespaceObject.toHTMLString)({ 15638 value: newValue 15639 }); 15640 updatedAttributes[newAttributeKey] = newHtml; 15641 const selectedBlockClientIds = select.getSelectedBlockClientIds(); 15642 const replacement = [...(isForward ? blocksWithTheSameType : []), { 15643 // Preserve the original client ID. 15644 ...targetBlock, 15645 attributes: { 15646 ...targetBlock.attributes, 15647 ...updatedAttributes 15648 } 15649 }, ...(isForward ? [] : blocksWithTheSameType)]; 15650 registry.batch(() => { 15651 dispatch.selectionChange(targetBlock.clientId, newAttributeKey, newOffset, newOffset); 15652 dispatch.replaceBlocks(selectedBlockClientIds, replacement, 0, 15653 // If we don't pass the `indexToSelect` it will default to the last block. 15654 select.getSelectedBlocksInitialCaretPosition()); 15655 }); 15656 }; 15657 15658 /** 15659 * Split the current selection. 15660 * @param {?Array} blocks 15661 */ 15662 const __unstableSplitSelection = (blocks = []) => ({ 15663 registry, 15664 select, 15665 dispatch 15666 }) => { 15667 const selectionAnchor = select.getSelectionStart(); 15668 const selectionFocus = select.getSelectionEnd(); 15669 const anchorRootClientId = select.getBlockRootClientId(selectionAnchor.clientId); 15670 const focusRootClientId = select.getBlockRootClientId(selectionFocus.clientId); 15671 15672 // It's not splittable if the selection doesn't start and end in the same 15673 // block list. Maybe in the future it should be allowed. 15674 if (anchorRootClientId !== focusRootClientId) { 15675 return; 15676 } 15677 const blockOrder = select.getBlockOrder(anchorRootClientId); 15678 const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId); 15679 const focusIndex = blockOrder.indexOf(selectionFocus.clientId); 15680 15681 // Reassign selection start and end based on order. 15682 let selectionStart, selectionEnd; 15683 if (anchorIndex > focusIndex) { 15684 selectionStart = selectionFocus; 15685 selectionEnd = selectionAnchor; 15686 } else { 15687 selectionStart = selectionAnchor; 15688 selectionEnd = selectionFocus; 15689 } 15690 const selectionA = selectionStart; 15691 const selectionB = selectionEnd; 15692 const blockA = select.getBlock(selectionA.clientId); 15693 const blockB = select.getBlock(selectionB.clientId); 15694 const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name); 15695 const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name); 15696 const attributeKeyA = typeof selectionA.attributeKey === 'string' ? selectionA.attributeKey : findRichTextAttributeKey(blockAType); 15697 const attributeKeyB = typeof selectionB.attributeKey === 'string' ? selectionB.attributeKey : findRichTextAttributeKey(blockBType); 15698 const blockAttributes = select.getBlockAttributes(selectionA.clientId); 15699 const bindings = blockAttributes?.metadata?.bindings; 15700 15701 // If the attribute is bound, don't split the selection and insert a new block instead. 15702 if (bindings?.[attributeKeyA]) { 15703 // Show warning if user tries to insert a block into another block with bindings. 15704 if (blocks.length) { 15705 const { 15706 createWarningNotice 15707 } = registry.dispatch(external_wp_notices_namespaceObject.store); 15708 createWarningNotice((0,external_wp_i18n_namespaceObject.__)("Blocks can't be inserted into other blocks with bindings"), { 15709 type: 'snackbar' 15710 }); 15711 return; 15712 } 15713 dispatch.insertAfterBlock(selectionA.clientId); 15714 return; 15715 } 15716 15717 // Can't split if the selection is not set. 15718 if (!attributeKeyA || !attributeKeyB || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') { 15719 return; 15720 } 15721 15722 // We can do some short-circuiting if the selection is collapsed. 15723 if (selectionA.clientId === selectionB.clientId && attributeKeyA === attributeKeyB && selectionA.offset === selectionB.offset) { 15724 // If an unmodified default block is selected, replace it. We don't 15725 // want to be converting into a default block. 15726 if (blocks.length) { 15727 if ((0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blockA)) { 15728 dispatch.replaceBlocks([selectionA.clientId], blocks, blocks.length - 1, -1); 15729 return; 15730 } 15731 } 15732 15733 // If selection is at the start or end, we can simply insert an 15734 // empty block, provided this block has no inner blocks. 15735 else if (!select.getBlockOrder(selectionA.clientId).length) { 15736 function createEmpty() { 15737 const defaultBlockName = (0,external_wp_blocks_namespaceObject.getDefaultBlockName)(); 15738 return select.canInsertBlockType(defaultBlockName, anchorRootClientId) ? (0,external_wp_blocks_namespaceObject.createBlock)(defaultBlockName) : (0,external_wp_blocks_namespaceObject.createBlock)(select.getBlockName(selectionA.clientId)); 15739 } 15740 const length = blockAttributes[attributeKeyA].length; 15741 if (selectionA.offset === 0 && length) { 15742 dispatch.insertBlocks([createEmpty()], select.getBlockIndex(selectionA.clientId), anchorRootClientId, false); 15743 return; 15744 } 15745 if (selectionA.offset === length) { 15746 dispatch.insertBlocks([createEmpty()], select.getBlockIndex(selectionA.clientId) + 1, anchorRootClientId); 15747 return; 15748 } 15749 } 15750 } 15751 const htmlA = blockA.attributes[attributeKeyA]; 15752 const htmlB = blockB.attributes[attributeKeyB]; 15753 let valueA = (0,external_wp_richText_namespaceObject.create)({ 15754 html: htmlA 15755 }); 15756 let valueB = (0,external_wp_richText_namespaceObject.create)({ 15757 html: htmlB 15758 }); 15759 valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, selectionA.offset, valueA.text.length); 15760 valueB = (0,external_wp_richText_namespaceObject.remove)(valueB, 0, selectionB.offset); 15761 let head = { 15762 // Preserve the original client ID. 15763 ...blockA, 15764 // If both start and end are the same, should only copy innerBlocks 15765 // once. 15766 innerBlocks: blockA.clientId === blockB.clientId ? [] : blockA.innerBlocks, 15767 attributes: { 15768 ...blockA.attributes, 15769 [attributeKeyA]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15770 value: valueA 15771 }) 15772 } 15773 }; 15774 let tail = { 15775 ...blockB, 15776 // Only preserve the original client ID if the end is different. 15777 clientId: blockA.clientId === blockB.clientId ? (0,external_wp_blocks_namespaceObject.createBlock)(blockB.name).clientId : blockB.clientId, 15778 attributes: { 15779 ...blockB.attributes, 15780 [attributeKeyB]: (0,external_wp_richText_namespaceObject.toHTMLString)({ 15781 value: valueB 15782 }) 15783 } 15784 }; 15785 15786 // When splitting a block, attempt to convert the tail block to the 15787 // default block type. For example, when splitting a heading block, the 15788 // tail block will be converted to a paragraph block. Note that for 15789 // blocks such as a list item and button, this will be skipped because 15790 // the default block type cannot be inserted. 15791 const defaultBlockName = (0,external_wp_blocks_namespaceObject.getDefaultBlockName)(); 15792 if ( 15793 // A block is only split when the selection is within the same 15794 // block. 15795 blockA.clientId === blockB.clientId && defaultBlockName && tail.name !== defaultBlockName && select.canInsertBlockType(defaultBlockName, anchorRootClientId)) { 15796 const switched = (0,external_wp_blocks_namespaceObject.switchToBlockType)(tail, defaultBlockName); 15797 if (switched?.length === 1) { 15798 tail = switched[0]; 15799 } 15800 } 15801 if (!blocks.length) { 15802 dispatch.replaceBlocks(select.getSelectedBlockClientIds(), [head, tail]); 15803 return; 15804 } 15805 let selection; 15806 const output = []; 15807 const clonedBlocks = [...blocks]; 15808 const firstBlock = clonedBlocks.shift(); 15809 const headType = (0,external_wp_blocks_namespaceObject.getBlockType)(head.name); 15810 const firstBlocks = headType.merge && firstBlock.name === headType.name ? [firstBlock] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(firstBlock, headType.name); 15811 if (firstBlocks?.length) { 15812 const first = firstBlocks.shift(); 15813 head = { 15814 ...head, 15815 attributes: { 15816 ...head.attributes, 15817 ...headType.merge(head.attributes, first.attributes) 15818 } 15819 }; 15820 output.push(head); 15821 selection = { 15822 clientId: head.clientId, 15823 attributeKey: attributeKeyA, 15824 offset: (0,external_wp_richText_namespaceObject.create)({ 15825 html: head.attributes[attributeKeyA] 15826 }).text.length 15827 }; 15828 clonedBlocks.unshift(...firstBlocks); 15829 } else { 15830 if (!(0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(head)) { 15831 output.push(head); 15832 } 15833 output.push(firstBlock); 15834 } 15835 const lastBlock = clonedBlocks.pop(); 15836 const tailType = (0,external_wp_blocks_namespaceObject.getBlockType)(tail.name); 15837 if (clonedBlocks.length) { 15838 output.push(...clonedBlocks); 15839 } 15840 if (lastBlock) { 15841 const lastBlocks = tailType.merge && tailType.name === lastBlock.name ? [lastBlock] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(lastBlock, tailType.name); 15842 if (lastBlocks?.length) { 15843 const last = lastBlocks.pop(); 15844 output.push({ 15845 ...tail, 15846 attributes: { 15847 ...tail.attributes, 15848 ...tailType.merge(last.attributes, tail.attributes) 15849 } 15850 }); 15851 output.push(...lastBlocks); 15852 selection = { 15853 clientId: tail.clientId, 15854 attributeKey: attributeKeyB, 15855 offset: (0,external_wp_richText_namespaceObject.create)({ 15856 html: last.attributes[attributeKeyB] 15857 }).text.length 15858 }; 15859 } else { 15860 output.push(lastBlock); 15861 if (!(0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(tail)) { 15862 output.push(tail); 15863 } 15864 } 15865 } else if (!(0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(tail)) { 15866 output.push(tail); 15867 } 15868 registry.batch(() => { 15869 dispatch.replaceBlocks(select.getSelectedBlockClientIds(), output, output.length - 1, 0); 15870 if (selection) { 15871 dispatch.selectionChange(selection.clientId, selection.attributeKey, selection.offset, selection.offset); 15872 } 15873 }); 15874 }; 15875 15876 /** 15877 * Expand the selection to cover the entire blocks, removing partial selection. 15878 */ 15879 const __unstableExpandSelection = () => ({ 15880 select, 15881 dispatch 15882 }) => { 15883 const selectionAnchor = select.getSelectionStart(); 15884 const selectionFocus = select.getSelectionEnd(); 15885 dispatch.selectionChange({ 15886 start: { 15887 clientId: selectionAnchor.clientId 15888 }, 15889 end: { 15890 clientId: selectionFocus.clientId 15891 } 15892 }); 15893 }; 15894 15895 /** 15896 * Action that merges two blocks. 15897 * 15898 * @param {string} firstBlockClientId Client ID of the first block to merge. 15899 * @param {string} secondBlockClientId Client ID of the second block to merge. 15900 */ 15901 const mergeBlocks = (firstBlockClientId, secondBlockClientId) => ({ 15902 registry, 15903 select, 15904 dispatch 15905 }) => { 15906 const clientIdA = firstBlockClientId; 15907 const clientIdB = secondBlockClientId; 15908 const blockA = select.getBlock(clientIdA); 15909 const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name); 15910 if (!blockAType) { 15911 return; 15912 } 15913 const blockB = select.getBlock(clientIdB); 15914 if (!blockAType.merge && (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockA.name, '__experimentalOnMerge')) { 15915 // If there's no merge function defined, attempt merging inner 15916 // blocks. 15917 const blocksWithTheSameType = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blockB, blockAType.name); 15918 // Only focus the previous block if it's not mergeable. 15919 if (blocksWithTheSameType?.length !== 1) { 15920 dispatch.selectBlock(blockA.clientId); 15921 return; 15922 } 15923 const [blockWithSameType] = blocksWithTheSameType; 15924 if (blockWithSameType.innerBlocks.length < 1) { 15925 dispatch.selectBlock(blockA.clientId); 15926 return; 15927 } 15928 registry.batch(() => { 15929 dispatch.insertBlocks(blockWithSameType.innerBlocks, undefined, clientIdA); 15930 dispatch.removeBlock(clientIdB); 15931 dispatch.selectBlock(blockWithSameType.innerBlocks[0].clientId); 15932 15933 // Attempt to merge the next block if it's the same type and 15934 // same attributes. This is useful when merging a paragraph into 15935 // a list, and the next block is also a list. If we don't merge, 15936 // it looks like one list, but it's actually two lists. The same 15937 // applies to other blocks such as a group with the same 15938 // attributes. 15939 const nextBlockClientId = select.getNextBlockClientId(clientIdA); 15940 if (nextBlockClientId && select.getBlockName(clientIdA) === select.getBlockName(nextBlockClientId)) { 15941 const rootAttributes = select.getBlockAttributes(clientIdA); 15942 const previousRootAttributes = select.getBlockAttributes(nextBlockClientId); 15943 if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) { 15944 dispatch.moveBlocksToPosition(select.getBlockOrder(nextBlockClientId), nextBlockClientId, clientIdA); 15945 dispatch.removeBlock(nextBlockClientId, false); 15946 } 15947 } 15948 }); 15949 return; 15950 } 15951 if ((0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blockA)) { 15952 dispatch.removeBlock(clientIdA, select.isBlockSelected(clientIdA)); 15953 return; 15954 } 15955 if ((0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blockB)) { 15956 dispatch.removeBlock(clientIdB, select.isBlockSelected(clientIdB)); 15957 return; 15958 } 15959 if (!blockAType.merge) { 15960 dispatch.selectBlock(blockA.clientId); 15961 return; 15962 } 15963 const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name); 15964 const { 15965 clientId, 15966 attributeKey, 15967 offset 15968 } = select.getSelectionStart(); 15969 const selectedBlockType = clientId === clientIdA ? blockAType : blockBType; 15970 const attributeDefinition = selectedBlockType.attributes[attributeKey]; 15971 const canRestoreTextSelection = (clientId === clientIdA || clientId === clientIdB) && attributeKey !== undefined && offset !== undefined && 15972 // We cannot restore text selection if the RichText identifier 15973 // is not a defined block attribute key. This can be the case if the 15974 // fallback instance ID is used to store selection (and no RichText 15975 // identifier is set), or when the identifier is wrong. 15976 !!attributeDefinition; 15977 if (!attributeDefinition) { 15978 if (typeof attributeKey === 'number') { 15979 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}`); 15980 } else { 15981 window.console.error('The RichText identifier prop does not match any attributes defined by the block.'); 15982 } 15983 } 15984 15985 // Clone the blocks so we don't insert the character in a "live" block. 15986 const cloneA = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockA); 15987 const cloneB = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockB); 15988 if (canRestoreTextSelection) { 15989 const selectedBlock = clientId === clientIdA ? cloneA : cloneB; 15990 const html = selectedBlock.attributes[attributeKey]; 15991 const value = (0,external_wp_richText_namespaceObject.insert)((0,external_wp_richText_namespaceObject.create)({ 15992 html 15993 }), START_OF_SELECTED_AREA, offset, offset); 15994 selectedBlock.attributes[attributeKey] = (0,external_wp_richText_namespaceObject.toHTMLString)({ 15995 value 15996 }); 15997 } 15998 15999 // We can only merge blocks with similar types 16000 // thus, we transform the block to merge first. 16001 const blocksWithTheSameType = blockA.name === blockB.name ? [cloneB] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(cloneB, blockA.name); 16002 16003 // If the block types can not match, do nothing. 16004 if (!blocksWithTheSameType || !blocksWithTheSameType.length) { 16005 return; 16006 } 16007 16008 // Calling the merge to update the attributes and remove the block to be merged. 16009 const updatedAttributes = blockAType.merge(cloneA.attributes, blocksWithTheSameType[0].attributes); 16010 if (canRestoreTextSelection) { 16011 const newAttributeKey = retrieveSelectedAttribute(updatedAttributes); 16012 const convertedHtml = updatedAttributes[newAttributeKey]; 16013 const convertedValue = (0,external_wp_richText_namespaceObject.create)({ 16014 html: convertedHtml 16015 }); 16016 const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA); 16017 const newValue = (0,external_wp_richText_namespaceObject.remove)(convertedValue, newOffset, newOffset + 1); 16018 const newHtml = (0,external_wp_richText_namespaceObject.toHTMLString)({ 16019 value: newValue 16020 }); 16021 updatedAttributes[newAttributeKey] = newHtml; 16022 dispatch.selectionChange(blockA.clientId, newAttributeKey, newOffset, newOffset); 16023 } 16024 dispatch.replaceBlocks([blockA.clientId, blockB.clientId], [{ 16025 ...blockA, 16026 attributes: { 16027 ...blockA.attributes, 16028 ...updatedAttributes 16029 } 16030 }, ...blocksWithTheSameType.slice(1)], 0 // If we don't pass the `indexToSelect` it will default to the last block. 16031 ); 16032 }; 16033 16034 /** 16035 * Yields action objects used in signalling that the blocks corresponding to 16036 * the set of specified client IDs are to be removed. 16037 * 16038 * @param {string|string[]} clientIds Client IDs of blocks to remove. 16039 * @param {boolean} selectPrevious True if the previous block 16040 * or the immediate parent 16041 * (if no previous block exists) 16042 * should be selected 16043 * when a block is removed. 16044 */ 16045 const removeBlocks = (clientIds, selectPrevious = true) => privateRemoveBlocks(clientIds, selectPrevious); 16046 16047 /** 16048 * Returns an action object used in signalling that the block with the 16049 * specified client ID is to be removed. 16050 * 16051 * @param {string} clientId Client ID of block to remove. 16052 * @param {boolean} selectPrevious True if the previous block should be 16053 * selected when a block is removed. 16054 * 16055 * @return {Object} Action object. 16056 */ 16057 function removeBlock(clientId, selectPrevious) { 16058 return removeBlocks([clientId], selectPrevious); 16059 } 16060 16061 /* eslint-disable jsdoc/valid-types */ 16062 /** 16063 * Returns an action object used in signalling that the inner blocks with the 16064 * specified client ID should be replaced. 16065 * 16066 * @param {string} rootClientId Client ID of the block whose InnerBlocks will re replaced. 16067 * @param {Object[]} blocks Block objects to insert as new InnerBlocks 16068 * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to false. 16069 * @param {0|-1|null} initialPosition Initial block position. 16070 * @return {Object} Action object. 16071 */ 16072 function replaceInnerBlocks(rootClientId, blocks, updateSelection = false, initialPosition = 0) { 16073 /* eslint-enable jsdoc/valid-types */ 16074 return { 16075 type: 'REPLACE_INNER_BLOCKS', 16076 rootClientId, 16077 blocks, 16078 updateSelection, 16079 initialPosition: updateSelection ? initialPosition : null, 16080 time: Date.now() 16081 }; 16082 } 16083 16084 /** 16085 * Returns an action object used to toggle the block editing mode between 16086 * visual and HTML modes. 16087 * 16088 * @param {string} clientId Block client ID. 16089 * 16090 * @return {Object} Action object. 16091 */ 16092 function toggleBlockMode(clientId) { 16093 return { 16094 type: 'TOGGLE_BLOCK_MODE', 16095 clientId 16096 }; 16097 } 16098 16099 /** 16100 * Returns an action object used in signalling that the user has begun to type. 16101 * 16102 * @return {Object} Action object. 16103 */ 16104 function startTyping() { 16105 return { 16106 type: 'START_TYPING' 16107 }; 16108 } 16109 16110 /** 16111 * Returns an action object used in signalling that the user has stopped typing. 16112 * 16113 * @return {Object} Action object. 16114 */ 16115 function stopTyping() { 16116 return { 16117 type: 'STOP_TYPING' 16118 }; 16119 } 16120 16121 /** 16122 * Returns an action object used in signalling that the user has begun to drag blocks. 16123 * 16124 * @param {string[]} clientIds An array of client ids being dragged 16125 * 16126 * @return {Object} Action object. 16127 */ 16128 function startDraggingBlocks(clientIds = []) { 16129 return { 16130 type: 'START_DRAGGING_BLOCKS', 16131 clientIds 16132 }; 16133 } 16134 16135 /** 16136 * Returns an action object used in signalling that the user has stopped dragging blocks. 16137 * 16138 * @return {Object} Action object. 16139 */ 16140 function stopDraggingBlocks() { 16141 return { 16142 type: 'STOP_DRAGGING_BLOCKS' 16143 }; 16144 } 16145 16146 /** 16147 * Returns an action object used in signalling that the caret has entered formatted text. 16148 * 16149 * @deprecated 16150 * 16151 * @return {Object} Action object. 16152 */ 16153 function enterFormattedText() { 16154 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).enterFormattedText', { 16155 since: '6.1', 16156 version: '6.3' 16157 }); 16158 return { 16159 type: 'DO_NOTHING' 16160 }; 16161 } 16162 16163 /** 16164 * Returns an action object used in signalling that the user caret has exited formatted text. 16165 * 16166 * @deprecated 16167 * 16168 * @return {Object} Action object. 16169 */ 16170 function exitFormattedText() { 16171 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).exitFormattedText', { 16172 since: '6.1', 16173 version: '6.3' 16174 }); 16175 return { 16176 type: 'DO_NOTHING' 16177 }; 16178 } 16179 16180 /** 16181 * Action that changes the position of the user caret. 16182 * 16183 * @param {string|WPSelection} clientId The selected block client ID. 16184 * @param {string} attributeKey The selected block attribute key. 16185 * @param {number} startOffset The start offset. 16186 * @param {number} endOffset The end offset. 16187 * 16188 * @return {Object} Action object. 16189 */ 16190 function selectionChange(clientId, attributeKey, startOffset, endOffset) { 16191 if (typeof clientId === 'string') { 16192 return { 16193 type: 'SELECTION_CHANGE', 16194 clientId, 16195 attributeKey, 16196 startOffset, 16197 endOffset 16198 }; 16199 } 16200 return { 16201 type: 'SELECTION_CHANGE', 16202 ...clientId 16203 }; 16204 } 16205 16206 /** 16207 * Action that adds a new block of the default type to the block list. 16208 * 16209 * @param {?Object} attributes Optional attributes of the block to assign. 16210 * @param {?string} rootClientId Optional root client ID of block list on which 16211 * to append. 16212 * @param {?number} index Optional index where to insert the default block. 16213 */ 16214 const insertDefaultBlock = (attributes, rootClientId, index) => ({ 16215 dispatch 16216 }) => { 16217 // Abort if there is no default block type (if it has been unregistered). 16218 const defaultBlockName = (0,external_wp_blocks_namespaceObject.getDefaultBlockName)(); 16219 if (!defaultBlockName) { 16220 return; 16221 } 16222 const block = (0,external_wp_blocks_namespaceObject.createBlock)(defaultBlockName, attributes); 16223 return dispatch.insertBlock(block, index, rootClientId); 16224 }; 16225 16226 /** 16227 * @typedef {Object< string, Object >} SettingsByClientId 16228 */ 16229 16230 /** 16231 * Action that changes the nested settings of the given block(s). 16232 * 16233 * @param {string | SettingsByClientId} clientId Client ID of the block whose 16234 * nested setting are being 16235 * received, or object of settings 16236 * by client ID. 16237 * @param {Object} settings Object with the new settings 16238 * for the nested block. 16239 * 16240 * @return {Object} Action object 16241 */ 16242 function updateBlockListSettings(clientId, settings) { 16243 return { 16244 type: 'UPDATE_BLOCK_LIST_SETTINGS', 16245 clientId, 16246 settings 16247 }; 16248 } 16249 16250 /** 16251 * Action that updates the block editor settings. 16252 * 16253 * @param {Object} settings Updated settings 16254 * 16255 * @return {Object} Action object 16256 */ 16257 function updateSettings(settings) { 16258 return __experimentalUpdateSettings(settings, { 16259 stripExperimentalSettings: true 16260 }); 16261 } 16262 16263 /** 16264 * Action that signals that a temporary reusable block has been saved 16265 * in order to switch its temporary id with the real id. 16266 * 16267 * @param {string} id Reusable block's id. 16268 * @param {string} updatedId Updated block's id. 16269 * 16270 * @return {Object} Action object. 16271 */ 16272 function __unstableSaveReusableBlock(id, updatedId) { 16273 return { 16274 type: 'SAVE_REUSABLE_BLOCK_SUCCESS', 16275 id, 16276 updatedId 16277 }; 16278 } 16279 16280 /** 16281 * Action that marks the last block change explicitly as persistent. 16282 * 16283 * @return {Object} Action object. 16284 */ 16285 function __unstableMarkLastChangeAsPersistent() { 16286 return { 16287 type: 'MARK_LAST_CHANGE_AS_PERSISTENT' 16288 }; 16289 } 16290 16291 /** 16292 * Action that signals that the next block change should be marked explicitly as not persistent. 16293 * 16294 * @return {Object} Action object. 16295 */ 16296 function __unstableMarkNextChangeAsNotPersistent() { 16297 return { 16298 type: 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT' 16299 }; 16300 } 16301 16302 /** 16303 * Action that marks the last block change as an automatic change, meaning it was not 16304 * performed by the user, and can be undone using the `Escape` and `Backspace` keys. 16305 * This action must be called after the change was made, and any actions that are a 16306 * consequence of it, so it is recommended to be called at the next idle period to ensure all 16307 * selection changes have been recorded. 16308 */ 16309 const __unstableMarkAutomaticChange = () => ({ 16310 dispatch 16311 }) => { 16312 dispatch({ 16313 type: 'MARK_AUTOMATIC_CHANGE' 16314 }); 16315 const { 16316 requestIdleCallback = cb => setTimeout(cb, 100) 16317 } = window; 16318 requestIdleCallback(() => { 16319 dispatch({ 16320 type: 'MARK_AUTOMATIC_CHANGE_FINAL' 16321 }); 16322 }); 16323 }; 16324 16325 /** 16326 * Action that enables or disables the navigation mode. 16327 * 16328 * @param {boolean} isNavigationMode Enable/Disable navigation mode. 16329 */ 16330 const setNavigationMode = (isNavigationMode = true) => ({ 16331 dispatch 16332 }) => { 16333 dispatch.__unstableSetEditorMode(isNavigationMode ? 'navigation' : 'edit'); 16334 }; 16335 16336 /** 16337 * Action that sets the editor mode 16338 * 16339 * @param {string} mode Editor mode 16340 */ 16341 const __unstableSetEditorMode = mode => ({ 16342 registry 16343 }) => { 16344 registry.dispatch(external_wp_preferences_namespaceObject.store).set('core', 'editorTool', mode); 16345 if (mode === 'navigation') { 16346 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in Write mode.')); 16347 } else if (mode === 'edit') { 16348 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in Design mode.')); 16349 } 16350 }; 16351 16352 /** 16353 * Set the block moving client ID. 16354 * 16355 * @deprecated 16356 * 16357 * @return {Object} Action object. 16358 */ 16359 function setBlockMovingClientId() { 16360 external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).setBlockMovingClientId', { 16361 since: '6.7', 16362 hint: 'Block moving mode feature has been removed' 16363 }); 16364 return { 16365 type: 'DO_NOTHING' 16366 }; 16367 } 16368 16369 /** 16370 * Action that duplicates a list of blocks. 16371 * 16372 * @param {string[]} clientIds 16373 * @param {boolean} updateSelection 16374 */ 16375 const duplicateBlocks = (clientIds, updateSelection = true) => ({ 16376 select, 16377 dispatch 16378 }) => { 16379 if (!clientIds || !clientIds.length) { 16380 return; 16381 } 16382 16383 // Return early if blocks don't exist. 16384 const blocks = select.getBlocksByClientId(clientIds); 16385 if (blocks.some(block => !block)) { 16386 return; 16387 } 16388 16389 // Return early if blocks don't support multiple usage. 16390 const blockNames = blocks.map(block => block.name); 16391 if (blockNames.some(blockName => !(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'multiple', true))) { 16392 return; 16393 } 16394 const rootClientId = select.getBlockRootClientId(clientIds[0]); 16395 const clientIdsArray = actions_castArray(clientIds); 16396 const lastSelectedIndex = select.getBlockIndex(clientIdsArray[clientIdsArray.length - 1]); 16397 const clonedBlocks = blocks.map(block => (0,external_wp_blocks_namespaceObject.__experimentalCloneSanitizedBlock)(block)); 16398 dispatch.insertBlocks(clonedBlocks, lastSelectedIndex + 1, rootClientId, updateSelection); 16399 if (clonedBlocks.length > 1 && updateSelection) { 16400 dispatch.multiSelect(clonedBlocks[0].clientId, clonedBlocks[clonedBlocks.length - 1].clientId); 16401 } 16402 return clonedBlocks.map(block => block.clientId); 16403 }; 16404 16405 /** 16406 * Action that inserts a default block before a given block. 16407 * 16408 * @param {string} clientId 16409 */ 16410 const insertBeforeBlock = clientId => ({ 16411 select, 16412 dispatch 16413 }) => { 16414 if (!clientId) { 16415 return; 16416 } 16417 const rootClientId = select.getBlockRootClientId(clientId); 16418 const isLocked = select.getTemplateLock(rootClientId); 16419 if (isLocked) { 16420 return; 16421 } 16422 const blockIndex = select.getBlockIndex(clientId); 16423 const directInsertBlock = rootClientId ? select.getDirectInsertBlock(rootClientId) : null; 16424 if (!directInsertBlock) { 16425 return dispatch.insertDefaultBlock({}, rootClientId, blockIndex); 16426 } 16427 const copiedAttributes = {}; 16428 if (directInsertBlock.attributesToCopy) { 16429 const attributes = select.getBlockAttributes(clientId); 16430 directInsertBlock.attributesToCopy.forEach(key => { 16431 if (attributes[key]) { 16432 copiedAttributes[key] = attributes[key]; 16433 } 16434 }); 16435 } 16436 const block = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, { 16437 ...directInsertBlock.attributes, 16438 ...copiedAttributes 16439 }); 16440 return dispatch.insertBlock(block, blockIndex, rootClientId); 16441 }; 16442 16443 /** 16444 * Action that inserts a default block after a given block. 16445 * 16446 * @param {string} clientId 16447 */ 16448 const insertAfterBlock = clientId => ({ 16449 select, 16450 dispatch 16451 }) => { 16452 if (!clientId) { 16453 return; 16454 } 16455 const rootClientId = select.getBlockRootClientId(clientId); 16456 const isLocked = select.getTemplateLock(rootClientId); 16457 if (isLocked) { 16458 return; 16459 } 16460 const blockIndex = select.getBlockIndex(clientId); 16461 const directInsertBlock = rootClientId ? select.getDirectInsertBlock(rootClientId) : null; 16462 if (!directInsertBlock) { 16463 return dispatch.insertDefaultBlock({}, rootClientId, blockIndex + 1); 16464 } 16465 const copiedAttributes = {}; 16466 if (directInsertBlock.attributesToCopy) { 16467 const attributes = select.getBlockAttributes(clientId); 16468 directInsertBlock.attributesToCopy.forEach(key => { 16469 if (attributes[key]) { 16470 copiedAttributes[key] = attributes[key]; 16471 } 16472 }); 16473 } 16474 const block = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, { 16475 ...directInsertBlock.attributes, 16476 ...copiedAttributes 16477 }); 16478 return dispatch.insertBlock(block, blockIndex + 1, rootClientId); 16479 }; 16480 16481 /** 16482 * Action that toggles the highlighted block state. 16483 * 16484 * @param {string} clientId The block's clientId. 16485 * @param {boolean} isHighlighted The highlight state. 16486 */ 16487 function toggleBlockHighlight(clientId, isHighlighted) { 16488 return { 16489 type: 'TOGGLE_BLOCK_HIGHLIGHT', 16490 clientId, 16491 isHighlighted 16492 }; 16493 } 16494 16495 /** 16496 * Action that "flashes" the block with a given `clientId` by rhythmically highlighting it. 16497 * 16498 * @param {string} clientId Target block client ID. 16499 */ 16500 const flashBlock = clientId => async ({ 16501 dispatch 16502 }) => { 16503 dispatch(toggleBlockHighlight(clientId, true)); 16504 await new Promise(resolve => setTimeout(resolve, 150)); 16505 dispatch(toggleBlockHighlight(clientId, false)); 16506 }; 16507 16508 /** 16509 * Action that sets whether a block has controlled inner blocks. 16510 * 16511 * @param {string} clientId The block's clientId. 16512 * @param {boolean} hasControlledInnerBlocks True if the block's inner blocks are controlled. 16513 */ 16514 function setHasControlledInnerBlocks(clientId, hasControlledInnerBlocks) { 16515 return { 16516 type: 'SET_HAS_CONTROLLED_INNER_BLOCKS', 16517 hasControlledInnerBlocks, 16518 clientId 16519 }; 16520 } 16521 16522 /** 16523 * Action that sets whether given blocks are visible on the canvas. 16524 * 16525 * @param {Record<string,boolean>} updates For each block's clientId, its new visibility setting. 16526 */ 16527 function setBlockVisibility(updates) { 16528 return { 16529 type: 'SET_BLOCK_VISIBILITY', 16530 updates 16531 }; 16532 } 16533 16534 /** 16535 * Action that sets whether a block is being temporarily edited as blocks. 16536 * 16537 * DO-NOT-USE in production. 16538 * This action is created for internal/experimental only usage and may be 16539 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 16540 * 16541 * @param {?string} temporarilyEditingAsBlocks The block's clientId being temporarily edited as blocks. 16542 * @param {?string} focusModeToRevert The focus mode to revert after temporarily edit as blocks finishes. 16543 */ 16544 function __unstableSetTemporarilyEditingAsBlocks(temporarilyEditingAsBlocks, focusModeToRevert) { 16545 return { 16546 type: 'SET_TEMPORARILY_EDITING_AS_BLOCKS', 16547 temporarilyEditingAsBlocks, 16548 focusModeToRevert 16549 }; 16550 } 16551 16552 /** 16553 * Interface for inserter media requests. 16554 * 16555 * @typedef {Object} InserterMediaRequest 16556 * @property {number} per_page How many items to fetch per page. 16557 * @property {string} search The search term to use for filtering the results. 16558 */ 16559 16560 /** 16561 * Interface for inserter media responses. Any media resource should 16562 * map their response to this interface, in order to create the core 16563 * WordPress media blocks (image, video, audio). 16564 * 16565 * @typedef {Object} InserterMediaItem 16566 * @property {string} title The title of the media item. 16567 * @property {string} url The source url of the media item. 16568 * @property {string} [previewUrl] The preview source url of the media item to display in the media list. 16569 * @property {number} [id] The WordPress id of the media item. 16570 * @property {number|string} [sourceId] The id of the media item from external source. 16571 * @property {string} [alt] The alt text of the media item. 16572 * @property {string} [caption] The caption of the media item. 16573 */ 16574 16575 /** 16576 * Registers a new inserter media category. Once registered, the media category is 16577 * available in the inserter's media tab. 16578 * 16579 * The following interfaces are used: 16580 * 16581 * _Type Definition_ 16582 * 16583 * - _InserterMediaRequest_ `Object`: Interface for inserter media requests. 16584 * 16585 * _Properties_ 16586 * 16587 * - _per_page_ `number`: How many items to fetch per page. 16588 * - _search_ `string`: The search term to use for filtering the results. 16589 * 16590 * _Type Definition_ 16591 * 16592 * - _InserterMediaItem_ `Object`: Interface for inserter media responses. Any media resource should 16593 * map their response to this interface, in order to create the core 16594 * WordPress media blocks (image, video, audio). 16595 * 16596 * _Properties_ 16597 * 16598 * - _title_ `string`: The title of the media item. 16599 * - _url_ `string: The source url of the media item. 16600 * - _previewUrl_ `[string]`: The preview source url of the media item to display in the media list. 16601 * - _id_ `[number]`: The WordPress id of the media item. 16602 * - _sourceId_ `[number|string]`: The id of the media item from external source. 16603 * - _alt_ `[string]`: The alt text of the media item. 16604 * - _caption_ `[string]`: The caption of the media item. 16605 * 16606 * @param {InserterMediaCategory} category The inserter media category to register. 16607 * 16608 * @example 16609 * ```js 16610 * 16611 * wp.data.dispatch('core/block-editor').registerInserterMediaCategory( { 16612 * name: 'openverse', 16613 * labels: { 16614 * name: 'Openverse', 16615 * search_items: 'Search Openverse', 16616 * }, 16617 * mediaType: 'image', 16618 * async fetch( query = {} ) { 16619 * const defaultArgs = { 16620 * mature: false, 16621 * excluded_source: 'flickr,inaturalist,wikimedia', 16622 * license: 'pdm,cc0', 16623 * }; 16624 * const finalQuery = { ...query, ...defaultArgs }; 16625 * // Sometimes you might need to map the supported request params according to `InserterMediaRequest`. 16626 * // interface. In this example the `search` query param is named `q`. 16627 * const mapFromInserterMediaRequest = { 16628 * per_page: 'page_size', 16629 * search: 'q', 16630 * }; 16631 * const url = new URL( 'https://api.openverse.org/v1/images/' ); 16632 * Object.entries( finalQuery ).forEach( ( [ key, value ] ) => { 16633 * const queryKey = mapFromInserterMediaRequest[ key ] || key; 16634 * url.searchParams.set( queryKey, value ); 16635 * } ); 16636 * const response = await window.fetch( url, { 16637 * headers: { 16638 * 'User-Agent': 'WordPress/inserter-media-fetch', 16639 * }, 16640 * } ); 16641 * const jsonResponse = await response.json(); 16642 * const results = jsonResponse.results; 16643 * return results.map( ( result ) => ( { 16644 * ...result, 16645 * // If your response result includes an `id` prop that you want to access later, it should 16646 * // be mapped to `InserterMediaItem`'s `sourceId` prop. This can be useful if you provide 16647 * // a report URL getter. 16648 * // Additionally you should always clear the `id` value of your response results because 16649 * // it is used to identify WordPress media items. 16650 * sourceId: result.id, 16651 * id: undefined, 16652 * caption: result.caption, 16653 * previewUrl: result.thumbnail, 16654 * } ) ); 16655 * }, 16656 * getReportUrl: ( { sourceId } ) => 16657 * `https://wordpress.org/openverse/image/${ sourceId }/report/`, 16658 * isExternalResource: true, 16659 * } ); 16660 * ``` 16661 * 16662 * @typedef {Object} InserterMediaCategory Interface for inserter media category. 16663 * @property {string} name The name of the media category, that should be unique among all media categories. 16664 * @property {Object} labels Labels for the media category. 16665 * @property {string} labels.name General name of the media category. It's used in the inserter media items list. 16666 * @property {string} [labels.search_items='Search'] Label for searching items. Default is ‘Search Posts’ / ‘Search Pages’. 16667 * @property {('image'|'audio'|'video')} mediaType The media type of the media category. 16668 * @property {(InserterMediaRequest) => Promise<InserterMediaItem[]>} fetch The function to fetch media items for the category. 16669 * @property {(InserterMediaItem) => string} [getReportUrl] If the media category supports reporting media items, this function should return 16670 * the report url for the media item. It accepts the `InserterMediaItem` as an argument. 16671 * @property {boolean} [isExternalResource] If the media category is an external resource, this should be set to true. 16672 * This is used to avoid making a request to the external resource when the user 16673 */ 16674 const registerInserterMediaCategory = category => ({ 16675 select, 16676 dispatch 16677 }) => { 16678 if (!category || typeof category !== 'object') { 16679 console.error('Category should be an `InserterMediaCategory` object.'); 16680 return; 16681 } 16682 if (!category.name) { 16683 console.error('Category should have a `name` that should be unique among all media categories.'); 16684 return; 16685 } 16686 if (!category.labels?.name) { 16687 console.error('Category should have a `labels.name`.'); 16688 return; 16689 } 16690 if (!['image', 'audio', 'video'].includes(category.mediaType)) { 16691 console.error('Category should have `mediaType` property that is one of `image|audio|video`.'); 16692 return; 16693 } 16694 if (!category.fetch || typeof category.fetch !== 'function') { 16695 console.error('Category should have a `fetch` function defined with the following signature `(InserterMediaRequest) => Promise<InserterMediaItem[]>`.'); 16696 return; 16697 } 16698 const registeredInserterMediaCategories = select.getRegisteredInserterMediaCategories(); 16699 if (registeredInserterMediaCategories.some(({ 16700 name 16701 }) => name === category.name)) { 16702 console.error(`A category is already registered with the same name: "$category.name}".`); 16703 return; 16704 } 16705 if (registeredInserterMediaCategories.some(({ 16706 labels: { 16707 name 16708 } = {} 16709 }) => name === category.labels?.name)) { 16710 console.error(`A category is already registered with the same labels.name: "$category.labels.name}".`); 16711 return; 16712 } 16713 // `inserterMediaCategories` is a private block editor setting, which means it cannot 16714 // be updated through the public `updateSettings` action. We preserve this setting as 16715 // private, so extenders can only add new inserter media categories and don't have any 16716 // control over the core media categories. 16717 dispatch({ 16718 type: 'REGISTER_INSERTER_MEDIA_CATEGORY', 16719 category: { 16720 ...category, 16721 isExternalResource: true 16722 } 16723 }); 16724 }; 16725 16726 /** 16727 * @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode 16728 */ 16729 16730 /** 16731 * Sets the block editing mode for a given block. 16732 * 16733 * @see useBlockEditingMode 16734 * 16735 * @param {string} clientId The block client ID, or `''` for the root container. 16736 * @param {BlockEditingMode} mode The block editing mode. One of `'disabled'`, 16737 * `'contentOnly'`, or `'default'`. 16738 * 16739 * @return {Object} Action object. 16740 */ 16741 function setBlockEditingMode(clientId = '', mode) { 16742 return { 16743 type: 'SET_BLOCK_EDITING_MODE', 16744 clientId, 16745 mode 16746 }; 16747 } 16748 16749 /** 16750 * Clears the block editing mode for a given block. 16751 * 16752 * @see useBlockEditingMode 16753 * 16754 * @param {string} clientId The block client ID, or `''` for the root container. 16755 * 16756 * @return {Object} Action object. 16757 */ 16758 function unsetBlockEditingMode(clientId = '') { 16759 return { 16760 type: 'UNSET_BLOCK_EDITING_MODE', 16761 clientId 16762 }; 16763 } 16764 16765 ;// ./node_modules/@wordpress/block-editor/build-module/store/index.js 16766 /** 16767 * WordPress dependencies 16768 */ 16769 16770 16771 /** 16772 * Internal dependencies 16773 */ 16774 16775 16776 16777 16778 16779 16780 16781 16782 /** 16783 * Block editor data store configuration. 16784 * 16785 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore 16786 */ 16787 const storeConfig = { 16788 reducer: reducer, 16789 selectors: selectors_namespaceObject, 16790 actions: actions_namespaceObject 16791 }; 16792 16793 /** 16794 * Store definition for the block editor namespace. 16795 * 16796 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 16797 */ 16798 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 16799 ...storeConfig, 16800 persist: ['preferences'] 16801 }); 16802 16803 // We will be able to use the `register` function once we switch 16804 // the "preferences" persistence to use the new preferences package. 16805 const registeredStore = (0,external_wp_data_namespaceObject.registerStore)(STORE_NAME, { 16806 ...storeConfig, 16807 persist: ['preferences'] 16808 }); 16809 unlock(registeredStore).registerPrivateActions(private_actions_namespaceObject); 16810 unlock(registeredStore).registerPrivateSelectors(private_selectors_namespaceObject); 16811 16812 // TODO: Remove once we switch to the `register` function (see above). 16813 // 16814 // Until then, private functions also need to be attached to the original 16815 // `store` descriptor in order to avoid unit tests failing, which could happen 16816 // when tests create new registries in which they register stores. 16817 // 16818 // @see https://github.com/WordPress/gutenberg/pull/51145#discussion_r1239999590 16819 unlock(store).registerPrivateActions(private_actions_namespaceObject); 16820 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 16821 16822 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-settings/index.js 16823 /** 16824 * WordPress dependencies 16825 */ 16826 16827 16828 16829 /** 16830 * Internal dependencies 16831 */ 16832 16833 16834 16835 16836 /** 16837 * Hook that retrieves the given settings for the block instance in use. 16838 * 16839 * It looks up the settings first in the block instance hierarchy. 16840 * If none are found, it'll look them up in the block editor settings. 16841 * 16842 * @param {string[]} paths The paths to the settings. 16843 * @return {any[]} Returns the values defined for the settings. 16844 * @example 16845 * ```js 16846 * const [ fixed, sticky ] = useSettings( 'position.fixed', 'position.sticky' ); 16847 * ``` 16848 */ 16849 function use_settings_useSettings(...paths) { 16850 const { 16851 clientId = null 16852 } = useBlockEditContext(); 16853 return (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getBlockSettings(clientId, ...paths), [clientId, ...paths]); 16854 } 16855 16856 /** 16857 * Hook that retrieves the given setting for the block instance in use. 16858 * 16859 * It looks up the setting first in the block instance hierarchy. 16860 * If none is found, it'll look it up in the block editor settings. 16861 * 16862 * @deprecated 6.5.0 Use useSettings instead. 16863 * 16864 * @param {string} path The path to the setting. 16865 * @return {any} Returns the value defined for the setting. 16866 * @example 16867 * ```js 16868 * const isEnabled = useSetting( 'typography.dropCap' ); 16869 * ``` 16870 */ 16871 function useSetting(path) { 16872 external_wp_deprecated_default()('wp.blockEditor.useSetting', { 16873 since: '6.5', 16874 alternative: 'wp.blockEditor.useSettings', 16875 note: 'The new useSettings function can retrieve multiple settings at once, with better performance.' 16876 }); 16877 const [value] = use_settings_useSettings(path); 16878 return value; 16879 } 16880 16881 ;// external ["wp","styleEngine"] 16882 const external_wp_styleEngine_namespaceObject = window["wp"]["styleEngine"]; 16883 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/fluid-utils.js 16884 /** 16885 * The fluid utilities must match the backend equivalent. 16886 * See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php 16887 * --------------------------------------------------------------- 16888 */ 16889 16890 // Defaults. 16891 const DEFAULT_MAXIMUM_VIEWPORT_WIDTH = '1600px'; 16892 const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '320px'; 16893 const DEFAULT_SCALE_FACTOR = 1; 16894 const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN = 0.25; 16895 const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX = 0.75; 16896 const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px'; 16897 16898 /** 16899 * Computes a fluid font-size value that uses clamp(). A minimum and maximum 16900 * font size OR a single font size can be specified. 16901 * 16902 * If a single font size is specified, it is scaled up and down using a logarithmic scale. 16903 * 16904 * @example 16905 * ```js 16906 * // Calculate fluid font-size value from a minimum and maximum value. 16907 * const fontSize = getComputedFluidTypographyValue( { 16908 * minimumFontSize: '20px', 16909 * maximumFontSize: '45px' 16910 * } ); 16911 * // Calculate fluid font-size value from a single font size. 16912 * const fontSize = getComputedFluidTypographyValue( { 16913 * fontSize: '30px', 16914 * } ); 16915 * ``` 16916 * 16917 * @param {Object} args 16918 * @param {?string} args.minimumViewportWidth Minimum viewport size from which type will have fluidity. Optional if fontSize is specified. 16919 * @param {?string} args.maximumViewportWidth Maximum size up to which type will have fluidity. Optional if fontSize is specified. 16920 * @param {string|number} [args.fontSize] Size to derive maximumFontSize and minimumFontSize from, if necessary. Optional if minimumFontSize and maximumFontSize are specified. 16921 * @param {?string} args.maximumFontSize Maximum font size for any clamp() calculation. Optional. 16922 * @param {?string} args.minimumFontSize Minimum font size for any clamp() calculation. Optional. 16923 * @param {?number} args.scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional. 16924 * @param {?string} args.minimumFontSizeLimit The smallest a calculated font size may be. Optional. 16925 * 16926 * @return {string|null} A font-size value using clamp(). 16927 */ 16928 function getComputedFluidTypographyValue({ 16929 minimumFontSize, 16930 maximumFontSize, 16931 fontSize, 16932 minimumViewportWidth = DEFAULT_MINIMUM_VIEWPORT_WIDTH, 16933 maximumViewportWidth = DEFAULT_MAXIMUM_VIEWPORT_WIDTH, 16934 scaleFactor = DEFAULT_SCALE_FACTOR, 16935 minimumFontSizeLimit 16936 }) { 16937 // Validate incoming settings and set defaults. 16938 minimumFontSizeLimit = !!getTypographyValueAndUnit(minimumFontSizeLimit) ? minimumFontSizeLimit : DEFAULT_MINIMUM_FONT_SIZE_LIMIT; 16939 16940 /* 16941 * Calculates missing minimumFontSize and maximumFontSize from 16942 * defaultFontSize if provided. 16943 */ 16944 if (fontSize) { 16945 // Parses default font size. 16946 const fontSizeParsed = getTypographyValueAndUnit(fontSize); 16947 16948 // Protect against invalid units. 16949 if (!fontSizeParsed?.unit) { 16950 return null; 16951 } 16952 16953 // Parses the minimum font size limit, so we can perform checks using it. 16954 const minimumFontSizeLimitParsed = getTypographyValueAndUnit(minimumFontSizeLimit, { 16955 coerceTo: fontSizeParsed.unit 16956 }); 16957 16958 // Don't enforce minimum font size if a font size has explicitly set a min and max value. 16959 if (!!minimumFontSizeLimitParsed?.value && !minimumFontSize && !maximumFontSize) { 16960 /* 16961 * If a minimum size was not passed to this function 16962 * and the user-defined font size is lower than $minimum_font_size_limit, 16963 * do not calculate a fluid value. 16964 */ 16965 if (fontSizeParsed?.value <= minimumFontSizeLimitParsed?.value) { 16966 return null; 16967 } 16968 } 16969 16970 // If no fluid max font size is available use the incoming value. 16971 if (!maximumFontSize) { 16972 maximumFontSize = `$fontSizeParsed.value}$fontSizeParsed.unit}`; 16973 } 16974 16975 /* 16976 * If no minimumFontSize is provided, create one using 16977 * the given font size multiplied by the min font size scale factor. 16978 */ 16979 if (!minimumFontSize) { 16980 const fontSizeValueInPx = fontSizeParsed.unit === 'px' ? fontSizeParsed.value : fontSizeParsed.value * 16; 16981 16982 /* 16983 * The scale factor is a multiplier that affects how quickly the curve will move towards the minimum, 16984 * that is, how quickly the size factor reaches 0 given increasing font size values. 16985 * For a - b * log2(), lower values of b will make the curve move towards the minimum faster. 16986 * The scale factor is constrained between min and max values. 16987 */ 16988 const minimumFontSizeFactor = Math.min(Math.max(1 - 0.075 * Math.log2(fontSizeValueInPx), DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN), DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX); 16989 16990 // Calculates the minimum font size. 16991 const calculatedMinimumFontSize = roundToPrecision(fontSizeParsed.value * minimumFontSizeFactor, 3); 16992 16993 // Only use calculated min font size if it's > $minimum_font_size_limit value. 16994 if (!!minimumFontSizeLimitParsed?.value && calculatedMinimumFontSize < minimumFontSizeLimitParsed?.value) { 16995 minimumFontSize = `$minimumFontSizeLimitParsed.value}$minimumFontSizeLimitParsed.unit}`; 16996 } else { 16997 minimumFontSize = `$calculatedMinimumFontSize}$fontSizeParsed.unit}`; 16998 } 16999 } 17000 } 17001 17002 // Grab the minimum font size and normalize it in order to use the value for calculations. 17003 const minimumFontSizeParsed = getTypographyValueAndUnit(minimumFontSize); 17004 17005 // We get a 'preferred' unit to keep units consistent when calculating, 17006 // otherwise the result will not be accurate. 17007 const fontSizeUnit = minimumFontSizeParsed?.unit || 'rem'; 17008 17009 // Grabs the maximum font size and normalize it in order to use the value for calculations. 17010 const maximumFontSizeParsed = getTypographyValueAndUnit(maximumFontSize, { 17011 coerceTo: fontSizeUnit 17012 }); 17013 17014 // Checks for mandatory min and max sizes, and protects against unsupported units. 17015 if (!minimumFontSizeParsed || !maximumFontSizeParsed) { 17016 return null; 17017 } 17018 17019 // Uses rem for accessible fluid target font scaling. 17020 const minimumFontSizeRem = getTypographyValueAndUnit(minimumFontSize, { 17021 coerceTo: 'rem' 17022 }); 17023 17024 // Viewport widths defined for fluid typography. Normalize units 17025 const maximumViewportWidthParsed = getTypographyValueAndUnit(maximumViewportWidth, { 17026 coerceTo: fontSizeUnit 17027 }); 17028 const minimumViewportWidthParsed = getTypographyValueAndUnit(minimumViewportWidth, { 17029 coerceTo: fontSizeUnit 17030 }); 17031 17032 // Protect against unsupported units. 17033 if (!maximumViewportWidthParsed || !minimumViewportWidthParsed || !minimumFontSizeRem) { 17034 return null; 17035 } 17036 17037 // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. 17038 const linearDenominator = maximumViewportWidthParsed.value - minimumViewportWidthParsed.value; 17039 if (!linearDenominator) { 17040 return null; 17041 } 17042 17043 // Build CSS rule. 17044 // Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. 17045 const minViewportWidthOffsetValue = roundToPrecision(minimumViewportWidthParsed.value / 100, 3); 17046 const viewportWidthOffset = roundToPrecision(minViewportWidthOffsetValue, 3) + fontSizeUnit; 17047 const linearFactor = 100 * ((maximumFontSizeParsed.value - minimumFontSizeParsed.value) / linearDenominator); 17048 const linearFactorScaled = roundToPrecision((linearFactor || 1) * scaleFactor, 3); 17049 const fluidTargetFontSize = `$minimumFontSizeRem.value}$minimumFontSizeRem.unit} + ((1vw - $viewportWidthOffset}) * $linearFactorScaled})`; 17050 return `clamp($minimumFontSize}, $fluidTargetFontSize}, $maximumFontSize})`; 17051 } 17052 17053 /** 17054 * Internal method that checks a string for a unit and value and returns an array consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ]. 17055 * A raw font size of `value + unit` is expected. If the value is an integer, it will convert to `value + 'px'`. 17056 * 17057 * @param {string|number} rawValue Raw size value from theme.json. 17058 * @param {Object|undefined} options Calculation options. 17059 * 17060 * @return {{ unit: string, value: number }|null} An object consisting of `'value'` and `'unit'` properties. 17061 */ 17062 function getTypographyValueAndUnit(rawValue, options = {}) { 17063 if (typeof rawValue !== 'string' && typeof rawValue !== 'number') { 17064 return null; 17065 } 17066 17067 // Converts numeric values to pixel values by default. 17068 if (isFinite(rawValue)) { 17069 rawValue = `$rawValue}px`; 17070 } 17071 const { 17072 coerceTo, 17073 rootSizeValue, 17074 acceptableUnits 17075 } = { 17076 coerceTo: '', 17077 // Default browser font size. Later we could inject some JS to compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`. 17078 rootSizeValue: 16, 17079 acceptableUnits: ['rem', 'px', 'em'], 17080 ...options 17081 }; 17082 const acceptableUnitsGroup = acceptableUnits?.join('|'); 17083 const regexUnits = new RegExp(`^(\\d*\\.?\\d+)($acceptableUnitsGroup}){1,1}$`); 17084 const matches = rawValue.match(regexUnits); 17085 17086 // We need a number value and a unit. 17087 if (!matches || matches.length < 3) { 17088 return null; 17089 } 17090 let [, value, unit] = matches; 17091 let returnValue = parseFloat(value); 17092 if ('px' === coerceTo && ('em' === unit || 'rem' === unit)) { 17093 returnValue = returnValue * rootSizeValue; 17094 unit = coerceTo; 17095 } 17096 if ('px' === unit && ('em' === coerceTo || 'rem' === coerceTo)) { 17097 returnValue = returnValue / rootSizeValue; 17098 unit = coerceTo; 17099 } 17100 17101 /* 17102 * No calculation is required if swapping between em and rem yet, 17103 * since we assume a root size value. Later we might like to differentiate between 17104 * :root font size (rem) and parent element font size (em) relativity. 17105 */ 17106 if (('em' === coerceTo || 'rem' === coerceTo) && ('em' === unit || 'rem' === unit)) { 17107 unit = coerceTo; 17108 } 17109 return { 17110 value: roundToPrecision(returnValue, 3), 17111 unit 17112 }; 17113 } 17114 17115 /** 17116 * Returns a value rounded to defined precision. 17117 * Returns `undefined` if the value is not a valid finite number. 17118 * 17119 * @param {number} value Raw value. 17120 * @param {number} digits The number of digits to appear after the decimal point 17121 * 17122 * @return {number|undefined} Value rounded to standard precision. 17123 */ 17124 function roundToPrecision(value, digits = 3) { 17125 const base = Math.pow(10, digits); 17126 return Number.isFinite(value) ? parseFloat(Math.round(value * base) / base) : undefined; 17127 } 17128 17129 ;// ./node_modules/@wordpress/block-editor/build-module/utils/format-font-style.js 17130 /** 17131 * WordPress dependencies 17132 */ 17133 17134 17135 /** 17136 * Formats font styles to human readable names. 17137 * 17138 * @param {string} fontStyle font style string 17139 * @return {Object} new object with formatted font style 17140 */ 17141 function formatFontStyle(fontStyle) { 17142 if (!fontStyle) { 17143 return {}; 17144 } 17145 if (typeof fontStyle === 'object') { 17146 return fontStyle; 17147 } 17148 let name; 17149 switch (fontStyle) { 17150 case 'normal': 17151 name = (0,external_wp_i18n_namespaceObject._x)('Regular', 'font style'); 17152 break; 17153 case 'italic': 17154 name = (0,external_wp_i18n_namespaceObject._x)('Italic', 'font style'); 17155 break; 17156 case 'oblique': 17157 name = (0,external_wp_i18n_namespaceObject._x)('Oblique', 'font style'); 17158 break; 17159 default: 17160 name = fontStyle; 17161 break; 17162 } 17163 return { 17164 name, 17165 value: fontStyle 17166 }; 17167 } 17168 17169 ;// ./node_modules/@wordpress/block-editor/build-module/utils/format-font-weight.js 17170 /** 17171 * WordPress dependencies 17172 */ 17173 17174 17175 /** 17176 * Formats font weights to human readable names. 17177 * 17178 * @param {string} fontWeight font weight string 17179 * @return {Object} new object with formatted font weight 17180 */ 17181 function formatFontWeight(fontWeight) { 17182 if (!fontWeight) { 17183 return {}; 17184 } 17185 if (typeof fontWeight === 'object') { 17186 return fontWeight; 17187 } 17188 let name; 17189 switch (fontWeight) { 17190 case 'normal': 17191 case '400': 17192 name = (0,external_wp_i18n_namespaceObject._x)('Regular', 'font weight'); 17193 break; 17194 case 'bold': 17195 case '700': 17196 name = (0,external_wp_i18n_namespaceObject._x)('Bold', 'font weight'); 17197 break; 17198 case '100': 17199 name = (0,external_wp_i18n_namespaceObject._x)('Thin', 'font weight'); 17200 break; 17201 case '200': 17202 name = (0,external_wp_i18n_namespaceObject._x)('Extra Light', 'font weight'); 17203 break; 17204 case '300': 17205 name = (0,external_wp_i18n_namespaceObject._x)('Light', 'font weight'); 17206 break; 17207 case '500': 17208 name = (0,external_wp_i18n_namespaceObject._x)('Medium', 'font weight'); 17209 break; 17210 case '600': 17211 name = (0,external_wp_i18n_namespaceObject._x)('Semi Bold', 'font weight'); 17212 break; 17213 case '800': 17214 name = (0,external_wp_i18n_namespaceObject._x)('Extra Bold', 'font weight'); 17215 break; 17216 case '900': 17217 name = (0,external_wp_i18n_namespaceObject._x)('Black', 'font weight'); 17218 break; 17219 case '1000': 17220 name = (0,external_wp_i18n_namespaceObject._x)('Extra Black', 'font weight'); 17221 break; 17222 default: 17223 name = fontWeight; 17224 break; 17225 } 17226 return { 17227 name, 17228 value: fontWeight 17229 }; 17230 } 17231 17232 ;// ./node_modules/@wordpress/block-editor/build-module/utils/get-font-styles-and-weights.js 17233 /** 17234 * WordPress dependencies 17235 */ 17236 17237 17238 /** 17239 * Internal dependencies 17240 */ 17241 17242 17243 const FONT_STYLES = [{ 17244 name: (0,external_wp_i18n_namespaceObject._x)('Regular', 'font style'), 17245 value: 'normal' 17246 }, { 17247 name: (0,external_wp_i18n_namespaceObject._x)('Italic', 'font style'), 17248 value: 'italic' 17249 }]; 17250 const FONT_WEIGHTS = [{ 17251 name: (0,external_wp_i18n_namespaceObject._x)('Thin', 'font weight'), 17252 value: '100' 17253 }, { 17254 name: (0,external_wp_i18n_namespaceObject._x)('Extra Light', 'font weight'), 17255 value: '200' 17256 }, { 17257 name: (0,external_wp_i18n_namespaceObject._x)('Light', 'font weight'), 17258 value: '300' 17259 }, { 17260 name: (0,external_wp_i18n_namespaceObject._x)('Regular', 'font weight'), 17261 value: '400' 17262 }, { 17263 name: (0,external_wp_i18n_namespaceObject._x)('Medium', 'font weight'), 17264 value: '500' 17265 }, { 17266 name: (0,external_wp_i18n_namespaceObject._x)('Semi Bold', 'font weight'), 17267 value: '600' 17268 }, { 17269 name: (0,external_wp_i18n_namespaceObject._x)('Bold', 'font weight'), 17270 value: '700' 17271 }, { 17272 name: (0,external_wp_i18n_namespaceObject._x)('Extra Bold', 'font weight'), 17273 value: '800' 17274 }, { 17275 name: (0,external_wp_i18n_namespaceObject._x)('Black', 'font weight'), 17276 value: '900' 17277 }, { 17278 name: (0,external_wp_i18n_namespaceObject._x)('Extra Black', 'font weight'), 17279 value: '1000' 17280 }]; 17281 17282 /** 17283 * Builds a list of font style and weight options based on font family faces. 17284 * Defaults to the standard font styles and weights if no font family faces are provided. 17285 * 17286 * @param {Array} fontFamilyFaces font family faces array 17287 * @return {Object} new object with combined and separated font style and weight properties 17288 */ 17289 function getFontStylesAndWeights(fontFamilyFaces) { 17290 let fontStyles = []; 17291 let fontWeights = []; 17292 const combinedStyleAndWeightOptions = []; 17293 const isSystemFont = !fontFamilyFaces || fontFamilyFaces?.length === 0; 17294 let isVariableFont = false; 17295 fontFamilyFaces?.forEach(face => { 17296 // Check for variable font by looking for a space in the font weight value. e.g. "100 900" 17297 if ('string' === typeof face.fontWeight && /\s/.test(face.fontWeight.trim())) { 17298 isVariableFont = true; 17299 17300 // Find font weight start and end values. 17301 let [startValue, endValue] = face.fontWeight.split(' '); 17302 startValue = parseInt(startValue.slice(0, 1)); 17303 if (endValue === '1000') { 17304 endValue = 10; 17305 } else { 17306 endValue = parseInt(endValue.slice(0, 1)); 17307 } 17308 17309 // Create font weight options for available variable weights. 17310 for (let i = startValue; i <= endValue; i++) { 17311 const fontWeightValue = `$i.toString()}00`; 17312 if (!fontWeights.some(weight => weight.value === fontWeightValue)) { 17313 fontWeights.push(formatFontWeight(fontWeightValue)); 17314 } 17315 } 17316 } 17317 17318 // Format font style and weight values. 17319 const fontWeight = formatFontWeight('number' === typeof face.fontWeight ? face.fontWeight.toString() : face.fontWeight); 17320 const fontStyle = formatFontStyle(face.fontStyle); 17321 17322 // Create font style and font weight lists without duplicates. 17323 if (fontStyle && Object.keys(fontStyle).length) { 17324 if (!fontStyles.some(style => style.value === fontStyle.value)) { 17325 fontStyles.push(fontStyle); 17326 } 17327 } 17328 if (fontWeight && Object.keys(fontWeight).length) { 17329 if (!fontWeights.some(weight => weight.value === fontWeight.value)) { 17330 if (!isVariableFont) { 17331 fontWeights.push(fontWeight); 17332 } 17333 } 17334 } 17335 }); 17336 17337 // If there is no font weight of 600 or above, then include faux bold as an option. 17338 if (!fontWeights.some(weight => weight.value >= '600')) { 17339 fontWeights.push({ 17340 name: (0,external_wp_i18n_namespaceObject._x)('Bold', 'font weight'), 17341 value: '700' 17342 }); 17343 } 17344 17345 // If there is no italic font style, then include faux italic as an option. 17346 if (!fontStyles.some(style => style.value === 'italic')) { 17347 fontStyles.push({ 17348 name: (0,external_wp_i18n_namespaceObject._x)('Italic', 'font style'), 17349 value: 'italic' 17350 }); 17351 } 17352 17353 // Use default font styles and weights for system fonts. 17354 if (isSystemFont) { 17355 fontStyles = FONT_STYLES; 17356 fontWeights = FONT_WEIGHTS; 17357 } 17358 17359 // Use default styles and weights if there are no available styles or weights from the provided font faces. 17360 fontStyles = fontStyles.length === 0 ? FONT_STYLES : fontStyles; 17361 fontWeights = fontWeights.length === 0 ? FONT_WEIGHTS : fontWeights; 17362 17363 // Generate combined font style and weight options for available fonts. 17364 fontStyles.forEach(({ 17365 name: styleName, 17366 value: styleValue 17367 }) => { 17368 fontWeights.forEach(({ 17369 name: weightName, 17370 value: weightValue 17371 }) => { 17372 const optionName = styleValue === 'normal' ? weightName : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: 1: Font weight name. 2: Font style name. */ 17373 (0,external_wp_i18n_namespaceObject._x)('%1$s %2$s', 'font'), weightName, styleName); 17374 combinedStyleAndWeightOptions.push({ 17375 key: `$styleValue}-$weightValue}`, 17376 name: optionName, 17377 style: { 17378 fontStyle: styleValue, 17379 fontWeight: weightValue 17380 } 17381 }); 17382 }); 17383 }); 17384 return { 17385 fontStyles, 17386 fontWeights, 17387 combinedStyleAndWeightOptions, 17388 isSystemFont, 17389 isVariableFont 17390 }; 17391 } 17392 17393 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/typography-utils.js 17394 /** 17395 * The fluid utilities must match the backend equivalent. 17396 * See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php 17397 * --------------------------------------------------------------- 17398 */ 17399 17400 /** 17401 * Internal dependencies 17402 */ 17403 17404 17405 17406 /** 17407 * @typedef {Object} FluidPreset 17408 * @property {string|undefined} max A maximum font size value. 17409 * @property {?string|undefined} min A minimum font size value. 17410 */ 17411 17412 /** 17413 * @typedef {Object} Preset 17414 * @property {?string|?number} size A default font size. 17415 * @property {string} name A font size name, displayed in the UI. 17416 * @property {string} slug A font size slug 17417 * @property {boolean|FluidPreset|undefined} fluid Specifies the minimum and maximum font size value of a fluid font size. 17418 */ 17419 17420 /** 17421 * @typedef {Object} TypographySettings 17422 * @property {?string} minViewportWidth Minimum viewport size from which type will have fluidity. Optional if size is specified. 17423 * @property {?string} maxViewportWidth Maximum size up to which type will have fluidity. Optional if size is specified. 17424 * @property {?number} scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional. 17425 * @property {?number} minFontSizeFactor How much to scale defaultFontSize by to derive minimumFontSize. Optional. 17426 * @property {?string} minFontSize The smallest a calculated font size may be. Optional. 17427 */ 17428 17429 /** 17430 * Returns a font-size value based on a given font-size preset. 17431 * Takes into account fluid typography parameters and attempts to return a css formula depending on available, valid values. 17432 * 17433 * The Core PHP equivalent is wp_get_typography_font_size_value(). 17434 * 17435 * @param {Preset} preset 17436 * @param {Object} settings 17437 * @param {boolean|TypographySettings} settings.typography.fluid Whether fluid typography is enabled, and, optionally, fluid font size options. 17438 * @param {?Object} settings.typography.layout Layout options. 17439 * 17440 * @return {string|*} A font-size value or the value of preset.size. 17441 */ 17442 function getTypographyFontSizeValue(preset, settings) { 17443 const { 17444 size: defaultSize 17445 } = preset; 17446 17447 /* 17448 * Catch falsy values and 0/'0'. Fluid calculations cannot be performed on `0`. 17449 * Also return early when a preset font size explicitly disables fluid typography with `false`. 17450 */ 17451 if (!defaultSize || '0' === defaultSize || false === preset?.fluid) { 17452 return defaultSize; 17453 } 17454 17455 /* 17456 * Return early when fluid typography is disabled in the settings, and there 17457 * are no local settings to enable it for the individual preset. 17458 * 17459 * If this condition isn't met, either the settings or individual preset settings 17460 * have enabled fluid typography. 17461 */ 17462 if (!isFluidTypographyEnabled(settings?.typography) && !isFluidTypographyEnabled(preset)) { 17463 return defaultSize; 17464 } 17465 let fluidTypographySettings = getFluidTypographyOptionsFromSettings(settings); 17466 fluidTypographySettings = typeof fluidTypographySettings?.fluid === 'object' ? fluidTypographySettings?.fluid : {}; 17467 const fluidFontSizeValue = getComputedFluidTypographyValue({ 17468 minimumFontSize: preset?.fluid?.min, 17469 maximumFontSize: preset?.fluid?.max, 17470 fontSize: defaultSize, 17471 minimumFontSizeLimit: fluidTypographySettings?.minFontSize, 17472 maximumViewportWidth: fluidTypographySettings?.maxViewportWidth, 17473 minimumViewportWidth: fluidTypographySettings?.minViewportWidth 17474 }); 17475 if (!!fluidFontSizeValue) { 17476 return fluidFontSizeValue; 17477 } 17478 return defaultSize; 17479 } 17480 function isFluidTypographyEnabled(typographySettings) { 17481 const fluidSettings = typographySettings?.fluid; 17482 return true === fluidSettings || fluidSettings && typeof fluidSettings === 'object' && Object.keys(fluidSettings).length > 0; 17483 } 17484 17485 /** 17486 * Returns fluid typography settings from theme.json setting object. 17487 * 17488 * @param {Object} settings Theme.json settings 17489 * @param {Object} settings.typography Theme.json typography settings 17490 * @param {Object} settings.layout Theme.json layout settings 17491 * @return {TypographySettings} Fluid typography settings 17492 */ 17493 function getFluidTypographyOptionsFromSettings(settings) { 17494 const typographySettings = settings?.typography; 17495 const layoutSettings = settings?.layout; 17496 const defaultMaxViewportWidth = getTypographyValueAndUnit(layoutSettings?.wideSize) ? layoutSettings?.wideSize : null; 17497 return isFluidTypographyEnabled(typographySettings) && defaultMaxViewportWidth ? { 17498 fluid: { 17499 maxViewportWidth: defaultMaxViewportWidth, 17500 ...typographySettings.fluid 17501 } 17502 } : { 17503 fluid: typographySettings?.fluid 17504 }; 17505 } 17506 17507 /** 17508 * Returns an object of merged font families and the font faces from the selected font family 17509 * based on the theme.json settings object and the currently selected font family. 17510 * 17511 * @param {Object} settings Theme.json settings. 17512 * @param {string} selectedFontFamily Decoded font family string. 17513 * @return {Object} Merged font families and font faces from the selected font family. 17514 */ 17515 function getMergedFontFamiliesAndFontFamilyFaces(settings, selectedFontFamily) { 17516 var _fontFamilies$find$fo; 17517 const fontFamiliesFromSettings = settings?.typography?.fontFamilies; 17518 const fontFamilies = ['default', 'theme', 'custom'].flatMap(key => { 17519 var _fontFamiliesFromSett; 17520 return (_fontFamiliesFromSett = fontFamiliesFromSettings?.[key]) !== null && _fontFamiliesFromSett !== void 0 ? _fontFamiliesFromSett : []; 17521 }); 17522 const fontFamilyFaces = (_fontFamilies$find$fo = fontFamilies.find(family => family.fontFamily === selectedFontFamily)?.fontFace) !== null && _fontFamilies$find$fo !== void 0 ? _fontFamilies$find$fo : []; 17523 return { 17524 fontFamilies, 17525 fontFamilyFaces 17526 }; 17527 } 17528 17529 /** 17530 * Returns the nearest font weight value from the available font weight list based on the new font weight. 17531 * The nearest font weight is the one with the smallest difference from the new font weight. 17532 * 17533 * @param {Array} availableFontWeights Array of available font weights. 17534 * @param {string} newFontWeightValue New font weight value. 17535 * @return {string} Nearest font weight. 17536 */ 17537 function findNearestFontWeight(availableFontWeights, newFontWeightValue) { 17538 newFontWeightValue = 'number' === typeof newFontWeightValue ? newFontWeightValue.toString() : newFontWeightValue; 17539 if (!newFontWeightValue || typeof newFontWeightValue !== 'string') { 17540 return ''; 17541 } 17542 if (!availableFontWeights || availableFontWeights.length === 0) { 17543 return newFontWeightValue; 17544 } 17545 const nearestFontWeight = availableFontWeights?.reduce((nearest, { 17546 value: fw 17547 }) => { 17548 const currentDiff = Math.abs(parseInt(fw) - parseInt(newFontWeightValue)); 17549 const nearestDiff = Math.abs(parseInt(nearest) - parseInt(newFontWeightValue)); 17550 return currentDiff < nearestDiff ? fw : nearest; 17551 }, availableFontWeights[0]?.value); 17552 return nearestFontWeight; 17553 } 17554 17555 /** 17556 * Returns the nearest font style based on the new font style. 17557 * Defaults to an empty string if the new font style is not valid or available. 17558 * 17559 * @param {Array} availableFontStyles Array of available font weights. 17560 * @param {string} newFontStyleValue New font style value. 17561 * @return {string} Nearest font style or an empty string. 17562 */ 17563 function findNearestFontStyle(availableFontStyles, newFontStyleValue) { 17564 if (typeof newFontStyleValue !== 'string' || !newFontStyleValue) { 17565 return ''; 17566 } 17567 const validStyles = ['normal', 'italic', 'oblique']; 17568 if (!validStyles.includes(newFontStyleValue)) { 17569 return ''; 17570 } 17571 if (!availableFontStyles || availableFontStyles.length === 0 || availableFontStyles.find(style => style.value === newFontStyleValue)) { 17572 return newFontStyleValue; 17573 } 17574 if (newFontStyleValue === 'oblique' && !availableFontStyles.find(style => style.value === 'oblique')) { 17575 return 'italic'; 17576 } 17577 return ''; 17578 } 17579 17580 /** 17581 * Returns the nearest font style and weight based on the available font family faces and the new font style and weight. 17582 * 17583 * @param {Array} fontFamilyFaces Array of available font family faces. 17584 * @param {string} fontStyle New font style. Defaults to previous value. 17585 * @param {string} fontWeight New font weight. Defaults to previous value. 17586 * @return {Object} Nearest font style and font weight. 17587 */ 17588 function findNearestStyleAndWeight(fontFamilyFaces, fontStyle, fontWeight) { 17589 let nearestFontStyle = fontStyle; 17590 let nearestFontWeight = fontWeight; 17591 const { 17592 fontStyles, 17593 fontWeights, 17594 combinedStyleAndWeightOptions 17595 } = getFontStylesAndWeights(fontFamilyFaces); 17596 17597 // Check if the new font style and weight are available in the font family faces. 17598 const hasFontStyle = fontStyles?.some(({ 17599 value: fs 17600 }) => fs === fontStyle); 17601 const hasFontWeight = fontWeights?.some(({ 17602 value: fw 17603 }) => fw?.toString() === fontWeight?.toString()); 17604 if (!hasFontStyle) { 17605 /* 17606 * Default to italic if oblique is not available. 17607 * Or find the nearest font style based on the nearest font weight. 17608 */ 17609 nearestFontStyle = fontStyle ? findNearestFontStyle(fontStyles, fontStyle) : combinedStyleAndWeightOptions?.find(option => option.style.fontWeight === findNearestFontWeight(fontWeights, fontWeight))?.style?.fontStyle; 17610 } 17611 if (!hasFontWeight) { 17612 /* 17613 * Find the nearest font weight based on available weights. 17614 * Or find the nearest font weight based on the nearest font style. 17615 */ 17616 nearestFontWeight = fontWeight ? findNearestFontWeight(fontWeights, fontWeight) : combinedStyleAndWeightOptions?.find(option => option.style.fontStyle === (nearestFontStyle || fontStyle))?.style?.fontWeight; 17617 } 17618 return { 17619 nearestFontStyle, 17620 nearestFontWeight 17621 }; 17622 } 17623 17624 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/utils.js 17625 /** 17626 * External dependencies 17627 */ 17628 17629 17630 /** 17631 * WordPress dependencies 17632 */ 17633 17634 17635 17636 /** 17637 * Internal dependencies 17638 */ 17639 17640 17641 17642 /* Supporting data. */ 17643 const ROOT_BLOCK_SELECTOR = 'body'; 17644 const ROOT_CSS_PROPERTIES_SELECTOR = ':root'; 17645 const PRESET_METADATA = [{ 17646 path: ['color', 'palette'], 17647 valueKey: 'color', 17648 cssVarInfix: 'color', 17649 classes: [{ 17650 classSuffix: 'color', 17651 propertyName: 'color' 17652 }, { 17653 classSuffix: 'background-color', 17654 propertyName: 'background-color' 17655 }, { 17656 classSuffix: 'border-color', 17657 propertyName: 'border-color' 17658 }] 17659 }, { 17660 path: ['color', 'gradients'], 17661 valueKey: 'gradient', 17662 cssVarInfix: 'gradient', 17663 classes: [{ 17664 classSuffix: 'gradient-background', 17665 propertyName: 'background' 17666 }] 17667 }, { 17668 path: ['color', 'duotone'], 17669 valueKey: 'colors', 17670 cssVarInfix: 'duotone', 17671 valueFunc: ({ 17672 slug 17673 }) => `url( '#wp-duotone-$slug}' )`, 17674 classes: [] 17675 }, { 17676 path: ['shadow', 'presets'], 17677 valueKey: 'shadow', 17678 cssVarInfix: 'shadow', 17679 classes: [] 17680 }, { 17681 path: ['typography', 'fontSizes'], 17682 valueFunc: (preset, settings) => getTypographyFontSizeValue(preset, settings), 17683 valueKey: 'size', 17684 cssVarInfix: 'font-size', 17685 classes: [{ 17686 classSuffix: 'font-size', 17687 propertyName: 'font-size' 17688 }] 17689 }, { 17690 path: ['typography', 'fontFamilies'], 17691 valueKey: 'fontFamily', 17692 cssVarInfix: 'font-family', 17693 classes: [{ 17694 classSuffix: 'font-family', 17695 propertyName: 'font-family' 17696 }] 17697 }, { 17698 path: ['spacing', 'spacingSizes'], 17699 valueKey: 'size', 17700 cssVarInfix: 'spacing', 17701 valueFunc: ({ 17702 size 17703 }) => size, 17704 classes: [] 17705 }]; 17706 const STYLE_PATH_TO_CSS_VAR_INFIX = { 17707 'color.background': 'color', 17708 'color.text': 'color', 17709 'filter.duotone': 'duotone', 17710 'elements.link.color.text': 'color', 17711 'elements.link.:hover.color.text': 'color', 17712 'elements.link.typography.fontFamily': 'font-family', 17713 'elements.link.typography.fontSize': 'font-size', 17714 'elements.button.color.text': 'color', 17715 'elements.button.color.background': 'color', 17716 'elements.caption.color.text': 'color', 17717 'elements.button.typography.fontFamily': 'font-family', 17718 'elements.button.typography.fontSize': 'font-size', 17719 'elements.heading.color': 'color', 17720 'elements.heading.color.background': 'color', 17721 'elements.heading.typography.fontFamily': 'font-family', 17722 'elements.heading.gradient': 'gradient', 17723 'elements.heading.color.gradient': 'gradient', 17724 'elements.h1.color': 'color', 17725 'elements.h1.color.background': 'color', 17726 'elements.h1.typography.fontFamily': 'font-family', 17727 'elements.h1.color.gradient': 'gradient', 17728 'elements.h2.color': 'color', 17729 'elements.h2.color.background': 'color', 17730 'elements.h2.typography.fontFamily': 'font-family', 17731 'elements.h2.color.gradient': 'gradient', 17732 'elements.h3.color': 'color', 17733 'elements.h3.color.background': 'color', 17734 'elements.h3.typography.fontFamily': 'font-family', 17735 'elements.h3.color.gradient': 'gradient', 17736 'elements.h4.color': 'color', 17737 'elements.h4.color.background': 'color', 17738 'elements.h4.typography.fontFamily': 'font-family', 17739 'elements.h4.color.gradient': 'gradient', 17740 'elements.h5.color': 'color', 17741 'elements.h5.color.background': 'color', 17742 'elements.h5.typography.fontFamily': 'font-family', 17743 'elements.h5.color.gradient': 'gradient', 17744 'elements.h6.color': 'color', 17745 'elements.h6.color.background': 'color', 17746 'elements.h6.typography.fontFamily': 'font-family', 17747 'elements.h6.color.gradient': 'gradient', 17748 'color.gradient': 'gradient', 17749 shadow: 'shadow', 17750 'typography.fontSize': 'font-size', 17751 'typography.fontFamily': 'font-family' 17752 }; 17753 17754 // A static list of block attributes that store global style preset slugs. 17755 const STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = { 17756 'color.background': 'backgroundColor', 17757 'color.text': 'textColor', 17758 'color.gradient': 'gradient', 17759 'typography.fontSize': 'fontSize', 17760 'typography.fontFamily': 'fontFamily' 17761 }; 17762 function useToolsPanelDropdownMenuProps() { 17763 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 17764 return !isMobile ? { 17765 popoverProps: { 17766 placement: 'left-start', 17767 // For non-mobile, inner sidebar width (248px) - button width (24px) - border (1px) + padding (16px) + spacing (20px) 17768 offset: 259 17769 } 17770 } : {}; 17771 } 17772 function findInPresetsBy(features, blockName, presetPath, presetProperty, presetValueValue) { 17773 // Block presets take priority above root level presets. 17774 const orderedPresetsByOrigin = [getValueFromObjectPath(features, ['blocks', blockName, ...presetPath]), getValueFromObjectPath(features, presetPath)]; 17775 for (const presetByOrigin of orderedPresetsByOrigin) { 17776 if (presetByOrigin) { 17777 // Preset origins ordered by priority. 17778 const origins = ['custom', 'theme', 'default']; 17779 for (const origin of origins) { 17780 const presets = presetByOrigin[origin]; 17781 if (presets) { 17782 const presetObject = presets.find(preset => preset[presetProperty] === presetValueValue); 17783 if (presetObject) { 17784 if (presetProperty === 'slug') { 17785 return presetObject; 17786 } 17787 // If there is a highest priority preset with the same slug but different value the preset we found was overwritten and should be ignored. 17788 const highestPresetObjectWithSameSlug = findInPresetsBy(features, blockName, presetPath, 'slug', presetObject.slug); 17789 if (highestPresetObjectWithSameSlug[presetProperty] === presetObject[presetProperty]) { 17790 return presetObject; 17791 } 17792 return undefined; 17793 } 17794 } 17795 } 17796 } 17797 } 17798 } 17799 function getPresetVariableFromValue(features, blockName, variableStylePath, presetPropertyValue) { 17800 if (!presetPropertyValue) { 17801 return presetPropertyValue; 17802 } 17803 const cssVarInfix = STYLE_PATH_TO_CSS_VAR_INFIX[variableStylePath]; 17804 const metadata = PRESET_METADATA.find(data => data.cssVarInfix === cssVarInfix); 17805 if (!metadata) { 17806 // The property doesn't have preset data 17807 // so the value should be returned as it is. 17808 return presetPropertyValue; 17809 } 17810 const { 17811 valueKey, 17812 path 17813 } = metadata; 17814 const presetObject = findInPresetsBy(features, blockName, path, valueKey, presetPropertyValue); 17815 if (!presetObject) { 17816 // Value wasn't found in the presets, 17817 // so it must be a custom value. 17818 return presetPropertyValue; 17819 } 17820 return `var:preset|$cssVarInfix}|$presetObject.slug}`; 17821 } 17822 function getValueFromPresetVariable(features, blockName, variable, [presetType, slug]) { 17823 const metadata = PRESET_METADATA.find(data => data.cssVarInfix === presetType); 17824 if (!metadata) { 17825 return variable; 17826 } 17827 const presetObject = findInPresetsBy(features.settings, blockName, metadata.path, 'slug', slug); 17828 if (presetObject) { 17829 const { 17830 valueKey 17831 } = metadata; 17832 const result = presetObject[valueKey]; 17833 return getValueFromVariable(features, blockName, result); 17834 } 17835 return variable; 17836 } 17837 function getValueFromCustomVariable(features, blockName, variable, path) { 17838 var _getValueFromObjectPa; 17839 const result = (_getValueFromObjectPa = getValueFromObjectPath(features.settings, ['blocks', blockName, 'custom', ...path])) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(features.settings, ['custom', ...path]); 17840 if (!result) { 17841 return variable; 17842 } 17843 // A variable may reference another variable so we need recursion until we find the value. 17844 return getValueFromVariable(features, blockName, result); 17845 } 17846 17847 /** 17848 * Attempts to fetch the value of a theme.json CSS variable. 17849 * 17850 * @param {Object} features GlobalStylesContext config, e.g., user, base or merged. Represents the theme.json tree. 17851 * @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. 17852 * @param {string|*} variable An incoming style value. A CSS var value is expected, but it could be any value. 17853 * @return {string|*|{ref}} The value of the CSS var, if found. If not found, the passed variable argument. 17854 */ 17855 function getValueFromVariable(features, blockName, variable) { 17856 if (!variable || typeof variable !== 'string') { 17857 if (typeof variable?.ref === 'string') { 17858 variable = getValueFromObjectPath(features, variable.ref); 17859 // Presence of another ref indicates a reference to another dynamic value. 17860 // Pointing to another dynamic value is not supported. 17861 if (!variable || !!variable?.ref) { 17862 return variable; 17863 } 17864 } else { 17865 return variable; 17866 } 17867 } 17868 const USER_VALUE_PREFIX = 'var:'; 17869 const THEME_VALUE_PREFIX = 'var(--wp--'; 17870 const THEME_VALUE_SUFFIX = ')'; 17871 let parsedVar; 17872 if (variable.startsWith(USER_VALUE_PREFIX)) { 17873 parsedVar = variable.slice(USER_VALUE_PREFIX.length).split('|'); 17874 } else if (variable.startsWith(THEME_VALUE_PREFIX) && variable.endsWith(THEME_VALUE_SUFFIX)) { 17875 parsedVar = variable.slice(THEME_VALUE_PREFIX.length, -THEME_VALUE_SUFFIX.length).split('--'); 17876 } else { 17877 // We don't know how to parse the value: either is raw of uses complex CSS such as `calc(1px * var(--wp--variable) )` 17878 return variable; 17879 } 17880 const [type, ...path] = parsedVar; 17881 if (type === 'preset') { 17882 return getValueFromPresetVariable(features, blockName, variable, path); 17883 } 17884 if (type === 'custom') { 17885 return getValueFromCustomVariable(features, blockName, variable, path); 17886 } 17887 return variable; 17888 } 17889 17890 /** 17891 * Function that scopes a selector with another one. This works a bit like 17892 * SCSS nesting except the `&` operator isn't supported. 17893 * 17894 * @example 17895 * ```js 17896 * const scope = '.a, .b .c'; 17897 * const selector = '> .x, .y'; 17898 * const merged = scopeSelector( scope, selector ); 17899 * // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y' 17900 * ``` 17901 * 17902 * @param {string} scope Selector to scope to. 17903 * @param {string} selector Original selector. 17904 * 17905 * @return {string} Scoped selector. 17906 */ 17907 function scopeSelector(scope, selector) { 17908 if (!scope || !selector) { 17909 return selector; 17910 } 17911 const scopes = scope.split(','); 17912 const selectors = selector.split(','); 17913 const selectorsScoped = []; 17914 scopes.forEach(outer => { 17915 selectors.forEach(inner => { 17916 selectorsScoped.push(`$outer.trim()} $inner.trim()}`); 17917 }); 17918 }); 17919 return selectorsScoped.join(', '); 17920 } 17921 17922 /** 17923 * Scopes a collection of selectors for features and subfeatures. 17924 * 17925 * @example 17926 * ```js 17927 * const scope = '.custom-scope'; 17928 * const selectors = { 17929 * color: '.wp-my-block p', 17930 * typography: { fontSize: '.wp-my-block caption' }, 17931 * }; 17932 * const result = scopeFeatureSelector( scope, selectors ); 17933 * // result is { 17934 * // color: '.custom-scope .wp-my-block p', 17935 * // typography: { fonSize: '.custom-scope .wp-my-block caption' }, 17936 * // } 17937 * ``` 17938 * 17939 * @param {string} scope Selector to scope collection of selectors with. 17940 * @param {Object} selectors Collection of feature selectors e.g. 17941 * 17942 * @return {Object|undefined} Scoped collection of feature selectors. 17943 */ 17944 function scopeFeatureSelectors(scope, selectors) { 17945 if (!scope || !selectors) { 17946 return; 17947 } 17948 const featureSelectors = {}; 17949 Object.entries(selectors).forEach(([feature, selector]) => { 17950 if (typeof selector === 'string') { 17951 featureSelectors[feature] = scopeSelector(scope, selector); 17952 } 17953 if (typeof selector === 'object') { 17954 featureSelectors[feature] = {}; 17955 Object.entries(selector).forEach(([subfeature, subfeatureSelector]) => { 17956 featureSelectors[feature][subfeature] = scopeSelector(scope, subfeatureSelector); 17957 }); 17958 } 17959 }); 17960 return featureSelectors; 17961 } 17962 17963 /** 17964 * Appends a sub-selector to an existing one. 17965 * 17966 * Given the compounded `selector` "h1, h2, h3" 17967 * and the `toAppend` selector ".some-class" the result will be 17968 * "h1.some-class, h2.some-class, h3.some-class". 17969 * 17970 * @param {string} selector Original selector. 17971 * @param {string} toAppend Selector to append. 17972 * 17973 * @return {string} The new selector. 17974 */ 17975 function appendToSelector(selector, toAppend) { 17976 if (!selector.includes(',')) { 17977 return selector + toAppend; 17978 } 17979 const selectors = selector.split(','); 17980 const newSelectors = selectors.map(sel => sel + toAppend); 17981 return newSelectors.join(','); 17982 } 17983 17984 /** 17985 * Compares global style variations according to their styles and settings properties. 17986 * 17987 * @example 17988 * ```js 17989 * const globalStyles = { styles: { typography: { fontSize: '10px' } }, settings: {} }; 17990 * const variation = { styles: { typography: { fontSize: '10000px' } }, settings: {} }; 17991 * const isEqual = areGlobalStyleConfigsEqual( globalStyles, variation ); 17992 * // false 17993 * ``` 17994 * 17995 * @param {Object} original A global styles object. 17996 * @param {Object} variation A global styles object. 17997 * 17998 * @return {boolean} Whether `original` and `variation` match. 17999 */ 18000 function areGlobalStyleConfigsEqual(original, variation) { 18001 if (typeof original !== 'object' || typeof variation !== 'object') { 18002 return original === variation; 18003 } 18004 return es6_default()(original?.styles, variation?.styles) && es6_default()(original?.settings, variation?.settings); 18005 } 18006 18007 /** 18008 * Generates the selector for a block style variation by creating the 18009 * appropriate CSS class and adding it to the ancestor portion of the block's 18010 * selector. 18011 * 18012 * For example, take the Button block which has a compound selector: 18013 * `.wp-block-button .wp-block-button__link`. With a variation named 'custom', 18014 * the class `.is-style-custom` should be added to the `.wp-block-button` 18015 * ancestor only. 18016 * 18017 * This function will take into account comma separated and complex selectors. 18018 * 18019 * @param {string} variation Name for the variation. 18020 * @param {string} blockSelector CSS selector for the block. 18021 * 18022 * @return {string} CSS selector for the block style variation. 18023 */ 18024 function getBlockStyleVariationSelector(variation, blockSelector) { 18025 const variationClass = `.is-style-$variation}`; 18026 if (!blockSelector) { 18027 return variationClass; 18028 } 18029 const ancestorRegex = /((?::\([^)]+\))?\s*)([^\s:]+)/; 18030 const addVariationClass = (_match, group1, group2) => { 18031 return group1 + group2 + variationClass; 18032 }; 18033 const result = blockSelector.split(',').map(part => part.replace(ancestorRegex, addVariationClass)); 18034 return result.join(','); 18035 } 18036 18037 /** 18038 * Looks up a theme file URI based on a relative path. 18039 * 18040 * @param {string} file A relative path. 18041 * @param {Array<Object>} themeFileURIs A collection of absolute theme file URIs and their corresponding file paths. 18042 * @return {string} A resolved theme file URI, if one is found in the themeFileURIs collection. 18043 */ 18044 function getResolvedThemeFilePath(file, themeFileURIs) { 18045 if (!file || !themeFileURIs || !Array.isArray(themeFileURIs)) { 18046 return file; 18047 } 18048 const uri = themeFileURIs.find(themeFileUri => themeFileUri?.name === file); 18049 if (!uri?.href) { 18050 return file; 18051 } 18052 return uri?.href; 18053 } 18054 18055 /** 18056 * Resolves ref values in theme JSON. 18057 * 18058 * @param {Object|string} ruleValue A block style value that may contain a reference to a theme.json value. 18059 * @param {Object} tree A theme.json object. 18060 * @return {*} The resolved value or incoming ruleValue. 18061 */ 18062 function getResolvedRefValue(ruleValue, tree) { 18063 if (!ruleValue || !tree) { 18064 return ruleValue; 18065 } 18066 18067 /* 18068 * Where the rule value is an object with a 'ref' property pointing 18069 * to a path, this converts that path into the value at that path. 18070 * For example: { "ref": "style.color.background" } => "#fff". 18071 */ 18072 if (typeof ruleValue !== 'string' && ruleValue?.ref) { 18073 const resolvedRuleValue = (0,external_wp_styleEngine_namespaceObject.getCSSValueFromRawStyle)(getValueFromObjectPath(tree, ruleValue.ref)); 18074 18075 /* 18076 * Presence of another ref indicates a reference to another dynamic value. 18077 * Pointing to another dynamic value is not supported. 18078 */ 18079 if (resolvedRuleValue?.ref) { 18080 return undefined; 18081 } 18082 if (resolvedRuleValue === undefined) { 18083 return ruleValue; 18084 } 18085 return resolvedRuleValue; 18086 } 18087 return ruleValue; 18088 } 18089 18090 /** 18091 * Resolves ref and relative path values in theme JSON. 18092 * 18093 * @param {Object|string} ruleValue A block style value that may contain a reference to a theme.json value. 18094 * @param {Object} tree A theme.json object. 18095 * @return {*} The resolved value or incoming ruleValue. 18096 */ 18097 function getResolvedValue(ruleValue, tree) { 18098 if (!ruleValue || !tree) { 18099 return ruleValue; 18100 } 18101 18102 // Resolve ref values. 18103 const resolvedValue = getResolvedRefValue(ruleValue, tree); 18104 18105 // Resolve relative paths. 18106 if (resolvedValue?.url) { 18107 resolvedValue.url = getResolvedThemeFilePath(resolvedValue.url, tree?._links?.['wp:theme-file']); 18108 } 18109 return resolvedValue; 18110 } 18111 18112 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/context.js 18113 /** 18114 * WordPress dependencies 18115 */ 18116 18117 const DEFAULT_GLOBAL_STYLES_CONTEXT = { 18118 user: {}, 18119 base: {}, 18120 merged: {}, 18121 setUserConfig: () => {} 18122 }; 18123 const GlobalStylesContext = (0,external_wp_element_namespaceObject.createContext)(DEFAULT_GLOBAL_STYLES_CONTEXT); 18124 18125 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/hooks.js 18126 /** 18127 * External dependencies 18128 */ 18129 18130 18131 /** 18132 * WordPress dependencies 18133 */ 18134 18135 18136 18137 18138 18139 /** 18140 * Internal dependencies 18141 */ 18142 18143 18144 18145 18146 const EMPTY_CONFIG = { 18147 settings: {}, 18148 styles: {} 18149 }; 18150 const VALID_SETTINGS = ['appearanceTools', 'useRootPaddingAwareAlignments', 'background.backgroundImage', 'background.backgroundRepeat', 'background.backgroundSize', 'background.backgroundPosition', '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.defaultSpacingSizes', 'spacing.spacingSizes', 'spacing.spacingScale', 'spacing.blockGap', 'spacing.margin', 'spacing.padding', 'spacing.units', 'typography.fluid', 'typography.customFontSize', 'typography.defaultFontSizes', 'typography.dropCap', 'typography.fontFamilies', 'typography.fontSizes', 'typography.fontStyle', 'typography.fontWeight', 'typography.letterSpacing', 'typography.lineHeight', 'typography.textAlign', 'typography.textColumns', 'typography.textDecoration', 'typography.textTransform', 'typography.writingMode']; 18151 const useGlobalStylesReset = () => { 18152 const { 18153 user, 18154 setUserConfig 18155 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 18156 const config = { 18157 settings: user.settings, 18158 styles: user.styles 18159 }; 18160 const canReset = !!config && !es6_default()(config, EMPTY_CONFIG); 18161 return [canReset, (0,external_wp_element_namespaceObject.useCallback)(() => setUserConfig(EMPTY_CONFIG), [setUserConfig])]; 18162 }; 18163 function useGlobalSetting(propertyPath, blockName, source = 'all') { 18164 const { 18165 setUserConfig, 18166 ...configs 18167 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 18168 const appendedBlockPath = blockName ? '.blocks.' + blockName : ''; 18169 const appendedPropertyPath = propertyPath ? '.' + propertyPath : ''; 18170 const contextualPath = `settings$appendedBlockPath}$appendedPropertyPath}`; 18171 const globalPath = `settings$appendedPropertyPath}`; 18172 const sourceKey = source === 'all' ? 'merged' : source; 18173 const settingValue = (0,external_wp_element_namespaceObject.useMemo)(() => { 18174 const configToUse = configs[sourceKey]; 18175 if (!configToUse) { 18176 throw 'Unsupported source'; 18177 } 18178 if (propertyPath) { 18179 var _getValueFromObjectPa; 18180 return (_getValueFromObjectPa = getValueFromObjectPath(configToUse, contextualPath)) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(configToUse, globalPath); 18181 } 18182 let result = {}; 18183 VALID_SETTINGS.forEach(setting => { 18184 var _getValueFromObjectPa2; 18185 const value = (_getValueFromObjectPa2 = getValueFromObjectPath(configToUse, `settings$appendedBlockPath}.$setting}`)) !== null && _getValueFromObjectPa2 !== void 0 ? _getValueFromObjectPa2 : getValueFromObjectPath(configToUse, `settings.$setting}`); 18186 if (value !== undefined) { 18187 result = setImmutably(result, setting.split('.'), value); 18188 } 18189 }); 18190 return result; 18191 }, [configs, sourceKey, propertyPath, contextualPath, globalPath, appendedBlockPath]); 18192 const setSetting = newValue => { 18193 setUserConfig(currentConfig => setImmutably(currentConfig, contextualPath.split('.'), newValue)); 18194 }; 18195 return [settingValue, setSetting]; 18196 } 18197 function useGlobalStyle(path, blockName, source = 'all', { 18198 shouldDecodeEncode = true 18199 } = {}) { 18200 const { 18201 merged: mergedConfig, 18202 base: baseConfig, 18203 user: userConfig, 18204 setUserConfig 18205 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 18206 const appendedPath = path ? '.' + path : ''; 18207 const finalPath = !blockName ? `styles$appendedPath}` : `styles.blocks.$blockName}$appendedPath}`; 18208 const setStyle = newValue => { 18209 setUserConfig(currentConfig => setImmutably(currentConfig, finalPath.split('.'), shouldDecodeEncode ? getPresetVariableFromValue(mergedConfig.settings, blockName, path, newValue) : newValue)); 18210 }; 18211 let rawResult, result; 18212 switch (source) { 18213 case 'all': 18214 rawResult = getValueFromObjectPath(mergedConfig, finalPath); 18215 result = shouldDecodeEncode ? getValueFromVariable(mergedConfig, blockName, rawResult) : rawResult; 18216 break; 18217 case 'user': 18218 rawResult = getValueFromObjectPath(userConfig, finalPath); 18219 result = shouldDecodeEncode ? getValueFromVariable(mergedConfig, blockName, rawResult) : rawResult; 18220 break; 18221 case 'base': 18222 rawResult = getValueFromObjectPath(baseConfig, finalPath); 18223 result = shouldDecodeEncode ? getValueFromVariable(baseConfig, blockName, rawResult) : rawResult; 18224 break; 18225 default: 18226 throw 'Unsupported source'; 18227 } 18228 return [result, setStyle]; 18229 } 18230 18231 /** 18232 * React hook that overrides a global settings object with block and element specific settings. 18233 * 18234 * @param {Object} parentSettings Settings object. 18235 * @param {blockName?} blockName Block name. 18236 * @param {element?} element Element name. 18237 * 18238 * @return {Object} Merge of settings and supports. 18239 */ 18240 function useSettingsForBlockElement(parentSettings, blockName, element) { 18241 const { 18242 supportedStyles, 18243 supports 18244 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 18245 return { 18246 supportedStyles: unlock(select(external_wp_blocks_namespaceObject.store)).getSupportedStyles(blockName, element), 18247 supports: select(external_wp_blocks_namespaceObject.store).getBlockType(blockName)?.supports 18248 }; 18249 }, [blockName, element]); 18250 return (0,external_wp_element_namespaceObject.useMemo)(() => { 18251 const updatedSettings = { 18252 ...parentSettings 18253 }; 18254 if (!supportedStyles.includes('fontSize')) { 18255 updatedSettings.typography = { 18256 ...updatedSettings.typography, 18257 fontSizes: {}, 18258 customFontSize: false, 18259 defaultFontSizes: false 18260 }; 18261 } 18262 if (!supportedStyles.includes('fontFamily')) { 18263 updatedSettings.typography = { 18264 ...updatedSettings.typography, 18265 fontFamilies: {} 18266 }; 18267 } 18268 updatedSettings.color = { 18269 ...updatedSettings.color, 18270 text: updatedSettings.color?.text && supportedStyles.includes('color'), 18271 background: updatedSettings.color?.background && (supportedStyles.includes('background') || supportedStyles.includes('backgroundColor')), 18272 button: updatedSettings.color?.button && supportedStyles.includes('buttonColor'), 18273 heading: updatedSettings.color?.heading && supportedStyles.includes('headingColor'), 18274 link: updatedSettings.color?.link && supportedStyles.includes('linkColor'), 18275 caption: updatedSettings.color?.caption && supportedStyles.includes('captionColor') 18276 }; 18277 18278 // Some blocks can enable background colors but disable gradients. 18279 if (!supportedStyles.includes('background')) { 18280 updatedSettings.color.gradients = []; 18281 updatedSettings.color.customGradient = false; 18282 } 18283 18284 // If filters are not supported by the block/element, disable duotone. 18285 if (!supportedStyles.includes('filter')) { 18286 updatedSettings.color.defaultDuotone = false; 18287 updatedSettings.color.customDuotone = false; 18288 } 18289 ['lineHeight', 'fontStyle', 'fontWeight', 'letterSpacing', 'textAlign', 'textTransform', 'textDecoration', 'writingMode'].forEach(key => { 18290 if (!supportedStyles.includes(key)) { 18291 updatedSettings.typography = { 18292 ...updatedSettings.typography, 18293 [key]: false 18294 }; 18295 } 18296 }); 18297 18298 // The column-count style is named text column to reduce confusion with 18299 // the columns block and manage expectations from the support. 18300 // See: https://github.com/WordPress/gutenberg/pull/33587 18301 if (!supportedStyles.includes('columnCount')) { 18302 updatedSettings.typography = { 18303 ...updatedSettings.typography, 18304 textColumns: false 18305 }; 18306 } 18307 ['contentSize', 'wideSize'].forEach(key => { 18308 if (!supportedStyles.includes(key)) { 18309 updatedSettings.layout = { 18310 ...updatedSettings.layout, 18311 [key]: false 18312 }; 18313 } 18314 }); 18315 ['padding', 'margin', 'blockGap'].forEach(key => { 18316 if (!supportedStyles.includes(key)) { 18317 updatedSettings.spacing = { 18318 ...updatedSettings.spacing, 18319 [key]: false 18320 }; 18321 } 18322 const sides = Array.isArray(supports?.spacing?.[key]) ? supports?.spacing?.[key] : supports?.spacing?.[key]?.sides; 18323 // Check if spacing type is supported before adding sides. 18324 if (sides?.length && updatedSettings.spacing?.[key]) { 18325 updatedSettings.spacing = { 18326 ...updatedSettings.spacing, 18327 [key]: { 18328 ...updatedSettings.spacing?.[key], 18329 sides 18330 } 18331 }; 18332 } 18333 }); 18334 ['aspectRatio', 'minHeight'].forEach(key => { 18335 if (!supportedStyles.includes(key)) { 18336 updatedSettings.dimensions = { 18337 ...updatedSettings.dimensions, 18338 [key]: false 18339 }; 18340 } 18341 }); 18342 ['radius', 'color', 'style', 'width'].forEach(key => { 18343 if (!supportedStyles.includes('border' + key.charAt(0).toUpperCase() + key.slice(1))) { 18344 updatedSettings.border = { 18345 ...updatedSettings.border, 18346 [key]: false 18347 }; 18348 } 18349 }); 18350 ['backgroundImage', 'backgroundSize'].forEach(key => { 18351 if (!supportedStyles.includes(key)) { 18352 updatedSettings.background = { 18353 ...updatedSettings.background, 18354 [key]: false 18355 }; 18356 } 18357 }); 18358 updatedSettings.shadow = supportedStyles.includes('shadow') ? updatedSettings.shadow : false; 18359 18360 // Text alignment is only available for blocks. 18361 if (element) { 18362 updatedSettings.typography.textAlign = false; 18363 } 18364 return updatedSettings; 18365 }, [parentSettings, supportedStyles, supports, element]); 18366 } 18367 function useColorsPerOrigin(settings) { 18368 const customColors = settings?.color?.palette?.custom; 18369 const themeColors = settings?.color?.palette?.theme; 18370 const defaultColors = settings?.color?.palette?.default; 18371 const shouldDisplayDefaultColors = settings?.color?.defaultPalette; 18372 return (0,external_wp_element_namespaceObject.useMemo)(() => { 18373 const result = []; 18374 if (themeColors && themeColors.length) { 18375 result.push({ 18376 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 18377 colors: themeColors 18378 }); 18379 } 18380 if (shouldDisplayDefaultColors && defaultColors && defaultColors.length) { 18381 result.push({ 18382 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 18383 colors: defaultColors 18384 }); 18385 } 18386 if (customColors && customColors.length) { 18387 result.push({ 18388 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 18389 colors: customColors 18390 }); 18391 } 18392 return result; 18393 }, [customColors, themeColors, defaultColors, shouldDisplayDefaultColors]); 18394 } 18395 function useGradientsPerOrigin(settings) { 18396 const customGradients = settings?.color?.gradients?.custom; 18397 const themeGradients = settings?.color?.gradients?.theme; 18398 const defaultGradients = settings?.color?.gradients?.default; 18399 const shouldDisplayDefaultGradients = settings?.color?.defaultGradients; 18400 return (0,external_wp_element_namespaceObject.useMemo)(() => { 18401 const result = []; 18402 if (themeGradients && themeGradients.length) { 18403 result.push({ 18404 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 18405 gradients: themeGradients 18406 }); 18407 } 18408 if (shouldDisplayDefaultGradients && defaultGradients && defaultGradients.length) { 18409 result.push({ 18410 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 18411 gradients: defaultGradients 18412 }); 18413 } 18414 if (customGradients && customGradients.length) { 18415 result.push({ 18416 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 18417 gradients: customGradients 18418 }); 18419 } 18420 return result; 18421 }, [customGradients, themeGradients, defaultGradients, shouldDisplayDefaultGradients]); 18422 } 18423 18424 ;// ./node_modules/clsx/dist/clsx.mjs 18425 function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f)}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}/* harmony default export */ const dist_clsx = (clsx); 18426 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/utils.js 18427 /** 18428 * WordPress dependencies 18429 */ 18430 18431 18432 18433 18434 18435 18436 /** 18437 * Internal dependencies 18438 */ 18439 18440 18441 18442 18443 18444 18445 /** 18446 * External dependencies 18447 */ 18448 18449 18450 /** 18451 * Removed falsy values from nested object. 18452 * 18453 * @param {*} object 18454 * @return {*} Object cleaned from falsy values 18455 */ 18456 18457 const utils_cleanEmptyObject = object => { 18458 if (object === null || typeof object !== 'object' || Array.isArray(object)) { 18459 return object; 18460 } 18461 const cleanedNestedObjects = Object.entries(object).map(([key, value]) => [key, utils_cleanEmptyObject(value)]).filter(([, value]) => value !== undefined); 18462 return !cleanedNestedObjects.length ? undefined : Object.fromEntries(cleanedNestedObjects); 18463 }; 18464 function transformStyles(activeSupports, migrationPaths, result, source, index, results) { 18465 // If there are no active supports return early. 18466 if (Object.values(activeSupports !== null && activeSupports !== void 0 ? activeSupports : {}).every(isActive => !isActive)) { 18467 return result; 18468 } 18469 // If the condition verifies we are probably in the presence of a wrapping transform 18470 // e.g: nesting paragraphs in a group or columns and in that case the styles should not be transformed. 18471 if (results.length === 1 && result.innerBlocks.length === source.length) { 18472 return result; 18473 } 18474 // For cases where we have a transform from one block to multiple blocks 18475 // or multiple blocks to one block we apply the styles of the first source block 18476 // to the result(s). 18477 let referenceBlockAttributes = source[0]?.attributes; 18478 // If we are in presence of transform between more than one block in the source 18479 // that has more than one block in the result 18480 // we apply the styles on source N to the result N, 18481 // if source N does not exists we do nothing. 18482 if (results.length > 1 && source.length > 1) { 18483 if (source[index]) { 18484 referenceBlockAttributes = source[index]?.attributes; 18485 } else { 18486 return result; 18487 } 18488 } 18489 let returnBlock = result; 18490 Object.entries(activeSupports).forEach(([support, isActive]) => { 18491 if (isActive) { 18492 migrationPaths[support].forEach(path => { 18493 const styleValue = getValueFromObjectPath(referenceBlockAttributes, path); 18494 if (styleValue) { 18495 returnBlock = { 18496 ...returnBlock, 18497 attributes: setImmutably(returnBlock.attributes, path, styleValue) 18498 }; 18499 } 18500 }); 18501 } 18502 }); 18503 return returnBlock; 18504 } 18505 18506 /** 18507 * Check whether serialization of specific block support feature or set should 18508 * be skipped. 18509 * 18510 * @param {string|Object} blockNameOrType Block name or block type object. 18511 * @param {string} featureSet Name of block support feature set. 18512 * @param {string} feature Name of the individual feature to check. 18513 * 18514 * @return {boolean} Whether serialization should occur. 18515 */ 18516 function shouldSkipSerialization(blockNameOrType, featureSet, feature) { 18517 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, featureSet); 18518 const skipSerialization = support?.__experimentalSkipSerialization; 18519 if (Array.isArray(skipSerialization)) { 18520 return skipSerialization.includes(feature); 18521 } 18522 return skipSerialization; 18523 } 18524 const pendingStyleOverrides = new WeakMap(); 18525 18526 /** 18527 * Override a block editor settings style. Leave the ID blank to create a new 18528 * style. 18529 * 18530 * @param {Object} override Override object. 18531 * @param {?string} override.id Id of the style override, leave blank to create 18532 * a new style. 18533 * @param {string} override.css CSS to apply. 18534 */ 18535 function useStyleOverride({ 18536 id, 18537 css 18538 }) { 18539 return usePrivateStyleOverride({ 18540 id, 18541 css 18542 }); 18543 } 18544 function usePrivateStyleOverride({ 18545 id, 18546 css, 18547 assets, 18548 __unstableType, 18549 variation, 18550 clientId 18551 } = {}) { 18552 const { 18553 setStyleOverride, 18554 deleteStyleOverride 18555 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 18556 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 18557 const fallbackId = (0,external_wp_element_namespaceObject.useId)(); 18558 (0,external_wp_element_namespaceObject.useEffect)(() => { 18559 // Unmount if there is CSS and assets are empty. 18560 if (!css && !assets) { 18561 return; 18562 } 18563 const _id = id || fallbackId; 18564 const override = { 18565 id, 18566 css, 18567 assets, 18568 __unstableType, 18569 variation, 18570 clientId 18571 }; 18572 // Batch updates to style overrides to avoid triggering cascading renders 18573 // for each style override block included in a tree and optimize initial render. 18574 if (!pendingStyleOverrides.get(registry)) { 18575 pendingStyleOverrides.set(registry, []); 18576 } 18577 pendingStyleOverrides.get(registry).push([_id, override]); 18578 window.queueMicrotask(() => { 18579 if (pendingStyleOverrides.get(registry)?.length) { 18580 registry.batch(() => { 18581 pendingStyleOverrides.get(registry).forEach(args => { 18582 setStyleOverride(...args); 18583 }); 18584 pendingStyleOverrides.set(registry, []); 18585 }); 18586 } 18587 }); 18588 return () => { 18589 const isPending = pendingStyleOverrides.get(registry)?.find(([currentId]) => currentId === _id); 18590 if (isPending) { 18591 pendingStyleOverrides.set(registry, pendingStyleOverrides.get(registry).filter(([currentId]) => currentId !== _id)); 18592 } else { 18593 deleteStyleOverride(_id); 18594 } 18595 }; 18596 }, [id, css, clientId, assets, __unstableType, fallbackId, setStyleOverride, deleteStyleOverride, registry]); 18597 } 18598 18599 /** 18600 * Based on the block and its context, returns an object of all the block settings. 18601 * This object can be passed as a prop to all the Styles UI components 18602 * (TypographyPanel, DimensionsPanel...). 18603 * 18604 * @param {string} name Block name. 18605 * @param {*} parentLayout Parent layout. 18606 * 18607 * @return {Object} Settings object. 18608 */ 18609 function useBlockSettings(name, parentLayout) { 18610 const [backgroundImage, backgroundSize, customFontFamilies, defaultFontFamilies, themeFontFamilies, defaultFontSizesEnabled, customFontSizes, defaultFontSizes, themeFontSizes, customFontSize, fontStyle, fontWeight, lineHeight, textAlign, textColumns, textDecoration, writingMode, textTransform, letterSpacing, padding, margin, blockGap, defaultSpacingSizesEnabled, customSpacingSize, userSpacingSizes, defaultSpacingSizes, themeSpacingSizes, 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.defaultFontSizes', 'typography.fontSizes.custom', 'typography.fontSizes.default', 'typography.fontSizes.theme', 'typography.customFontSize', 'typography.fontStyle', 'typography.fontWeight', 'typography.lineHeight', 'typography.textAlign', 'typography.textColumns', 'typography.textDecoration', 'typography.writingMode', 'typography.textTransform', 'typography.letterSpacing', 'spacing.padding', 'spacing.margin', 'spacing.blockGap', 'spacing.defaultSpacingSizes', 'spacing.customSpacingSize', 'spacing.spacingSizes.custom', 'spacing.spacingSizes.default', 'spacing.spacingSizes.theme', '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'); 18611 const rawSettings = (0,external_wp_element_namespaceObject.useMemo)(() => { 18612 return { 18613 background: { 18614 backgroundImage, 18615 backgroundSize 18616 }, 18617 color: { 18618 palette: { 18619 custom: customColors, 18620 theme: themeColors, 18621 default: defaultColors 18622 }, 18623 gradients: { 18624 custom: userGradientPalette, 18625 theme: themeGradientPalette, 18626 default: defaultGradientPalette 18627 }, 18628 duotone: { 18629 custom: userDuotonePalette, 18630 theme: themeDuotonePalette, 18631 default: defaultDuotonePalette 18632 }, 18633 defaultGradients, 18634 defaultPalette, 18635 defaultDuotone, 18636 custom: customColorsEnabled, 18637 customGradient: areCustomGradientsEnabled, 18638 customDuotone, 18639 background: isBackgroundEnabled, 18640 link: isLinkEnabled, 18641 heading: isHeadingEnabled, 18642 button: isButtonEnabled, 18643 text: isTextEnabled 18644 }, 18645 typography: { 18646 fontFamilies: { 18647 custom: customFontFamilies, 18648 default: defaultFontFamilies, 18649 theme: themeFontFamilies 18650 }, 18651 fontSizes: { 18652 custom: customFontSizes, 18653 default: defaultFontSizes, 18654 theme: themeFontSizes 18655 }, 18656 customFontSize, 18657 defaultFontSizes: defaultFontSizesEnabled, 18658 fontStyle, 18659 fontWeight, 18660 lineHeight, 18661 textAlign, 18662 textColumns, 18663 textDecoration, 18664 textTransform, 18665 letterSpacing, 18666 writingMode 18667 }, 18668 spacing: { 18669 spacingSizes: { 18670 custom: userSpacingSizes, 18671 default: defaultSpacingSizes, 18672 theme: themeSpacingSizes 18673 }, 18674 customSpacingSize, 18675 defaultSpacingSizes: defaultSpacingSizesEnabled, 18676 padding, 18677 margin, 18678 blockGap, 18679 units 18680 }, 18681 border: { 18682 color: borderColor, 18683 radius: borderRadius, 18684 style: borderStyle, 18685 width: borderWidth 18686 }, 18687 dimensions: { 18688 aspectRatio, 18689 minHeight 18690 }, 18691 layout, 18692 parentLayout, 18693 shadow 18694 }; 18695 }, [backgroundImage, backgroundSize, customFontFamilies, defaultFontFamilies, themeFontFamilies, defaultFontSizesEnabled, customFontSizes, defaultFontSizes, themeFontSizes, customFontSize, fontStyle, fontWeight, lineHeight, textAlign, textColumns, textDecoration, textTransform, letterSpacing, writingMode, padding, margin, blockGap, defaultSpacingSizesEnabled, customSpacingSize, userSpacingSizes, defaultSpacingSizes, themeSpacingSizes, 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]); 18696 return useSettingsForBlockElement(rawSettings, name); 18697 } 18698 function createBlockEditFilter(features) { 18699 // We don't want block controls to re-render when typing inside a block. 18700 // `memo` will prevent re-renders unless props change, so only pass the 18701 // needed props and not the whole attributes object. 18702 features = features.map(settings => { 18703 return { 18704 ...settings, 18705 Edit: (0,external_wp_element_namespaceObject.memo)(settings.edit) 18706 }; 18707 }); 18708 const withBlockEditHooks = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(OriginalBlockEdit => props => { 18709 const context = useBlockEditContext(); 18710 // CAUTION: code added before this line will be executed for all 18711 // blocks, not just those that support the feature! Code added 18712 // above this line should be carefully evaluated for its impact on 18713 // performance. 18714 return [...features.map((feature, i) => { 18715 const { 18716 Edit, 18717 hasSupport, 18718 attributeKeys = [], 18719 shareWithChildBlocks 18720 } = feature; 18721 const shouldDisplayControls = context[mayDisplayControlsKey] || context[mayDisplayParentControlsKey] && shareWithChildBlocks; 18722 if (!shouldDisplayControls || !hasSupport(props.name)) { 18723 return null; 18724 } 18725 const neededProps = {}; 18726 for (const key of attributeKeys) { 18727 if (props.attributes[key]) { 18728 neededProps[key] = props.attributes[key]; 18729 } 18730 } 18731 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Edit 18732 // We can use the index because the array length 18733 // is fixed per page load right now. 18734 , { 18735 name: props.name, 18736 isSelected: props.isSelected, 18737 clientId: props.clientId, 18738 setAttributes: props.setAttributes, 18739 __unstableParentLayout: props.__unstableParentLayout 18740 // This component is pure, so only pass needed 18741 // props!!! 18742 , 18743 ...neededProps 18744 }, i); 18745 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(OriginalBlockEdit, { 18746 ...props 18747 }, "edit")]; 18748 }, 'withBlockEditHooks'); 18749 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockEdit', 'core/editor/hooks', withBlockEditHooks); 18750 } 18751 function BlockProps({ 18752 index, 18753 useBlockProps: hook, 18754 setAllWrapperProps, 18755 ...props 18756 }) { 18757 const wrapperProps = hook(props); 18758 const setWrapperProps = next => setAllWrapperProps(prev => { 18759 const nextAll = [...prev]; 18760 nextAll[index] = next; 18761 return nextAll; 18762 }); 18763 // Setting state after every render is fine because this component is 18764 // pure and will only re-render when needed props change. 18765 (0,external_wp_element_namespaceObject.useEffect)(() => { 18766 // We could shallow compare the props, but since this component only 18767 // changes when needed attributes change, the benefit is probably small. 18768 setWrapperProps(wrapperProps); 18769 return () => { 18770 setWrapperProps(undefined); 18771 }; 18772 }); 18773 return null; 18774 } 18775 const BlockPropsPure = (0,external_wp_element_namespaceObject.memo)(BlockProps); 18776 function createBlockListBlockFilter(features) { 18777 const withBlockListBlockHooks = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockListBlock => props => { 18778 const [allWrapperProps, setAllWrapperProps] = (0,external_wp_element_namespaceObject.useState)(Array(features.length).fill(undefined)); 18779 return [...features.map((feature, i) => { 18780 const { 18781 hasSupport, 18782 attributeKeys = [], 18783 useBlockProps, 18784 isMatch 18785 } = feature; 18786 const neededProps = {}; 18787 for (const key of attributeKeys) { 18788 if (props.attributes[key]) { 18789 neededProps[key] = props.attributes[key]; 18790 } 18791 } 18792 if ( 18793 // Skip rendering if none of the needed attributes are 18794 // set. 18795 !Object.keys(neededProps).length || !hasSupport(props.name) || isMatch && !isMatch(neededProps)) { 18796 return null; 18797 } 18798 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockPropsPure 18799 // We can use the index because the array length 18800 // is fixed per page load right now. 18801 , { 18802 index: i, 18803 useBlockProps: useBlockProps 18804 // This component is pure, so we must pass a stable 18805 // function reference. 18806 , 18807 setAllWrapperProps: setAllWrapperProps, 18808 name: props.name, 18809 clientId: props.clientId 18810 // This component is pure, so only pass needed 18811 // props!!! 18812 , 18813 ...neededProps 18814 }, i); 18815 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListBlock, { 18816 ...props, 18817 wrapperProps: allWrapperProps.filter(Boolean).reduce((acc, wrapperProps) => { 18818 return { 18819 ...acc, 18820 ...wrapperProps, 18821 className: dist_clsx(acc.className, wrapperProps.className), 18822 style: { 18823 ...acc.style, 18824 ...wrapperProps.style 18825 } 18826 }; 18827 }, props.wrapperProps || {}) 18828 }, "edit")]; 18829 }, 'withBlockListBlockHooks'); 18830 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockListBlock', 'core/editor/hooks', withBlockListBlockHooks); 18831 } 18832 function createBlockSaveFilter(features) { 18833 function extraPropsFromHooks(props, name, attributes) { 18834 return features.reduce((accu, feature) => { 18835 const { 18836 hasSupport, 18837 attributeKeys = [], 18838 addSaveProps 18839 } = feature; 18840 const neededAttributes = {}; 18841 for (const key of attributeKeys) { 18842 if (attributes[key]) { 18843 neededAttributes[key] = attributes[key]; 18844 } 18845 } 18846 if ( 18847 // Skip rendering if none of the needed attributes are 18848 // set. 18849 !Object.keys(neededAttributes).length || !hasSupport(name)) { 18850 return accu; 18851 } 18852 return addSaveProps(accu, name, neededAttributes); 18853 }, props); 18854 } 18855 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/editor/hooks', extraPropsFromHooks, 0); 18856 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/editor/hooks', props => { 18857 // Previously we had a filter deleting the className if it was an empty 18858 // string. That filter is no longer running, so now we need to delete it 18859 // here. 18860 if (props.hasOwnProperty('className') && !props.className) { 18861 delete props.className; 18862 } 18863 return props; 18864 }); 18865 } 18866 18867 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/compat.js 18868 /** 18869 * WordPress dependencies 18870 */ 18871 18872 18873 function migrateLightBlockWrapper(settings) { 18874 const { 18875 apiVersion = 1 18876 } = settings; 18877 if (apiVersion < 2 && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'lightBlockWrapper', false)) { 18878 settings.apiVersion = 2; 18879 } 18880 return settings; 18881 } 18882 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/compat/migrateLightBlockWrapper', migrateLightBlockWrapper); 18883 18884 ;// external ["wp","components"] 18885 const external_wp_components_namespaceObject = window["wp"]["components"]; 18886 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-controls/groups.js 18887 /** 18888 * WordPress dependencies 18889 */ 18890 18891 const BlockControlsDefault = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControls'); 18892 const BlockControlsBlock = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsBlock'); 18893 const BlockControlsInline = (0,external_wp_components_namespaceObject.createSlotFill)('BlockFormatControls'); 18894 const BlockControlsOther = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsOther'); 18895 const BlockControlsParent = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsParent'); 18896 const groups = { 18897 default: BlockControlsDefault, 18898 block: BlockControlsBlock, 18899 inline: BlockControlsInline, 18900 other: BlockControlsOther, 18901 parent: BlockControlsParent 18902 }; 18903 /* harmony default export */ const block_controls_groups = (groups); 18904 18905 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-controls/hook.js 18906 /** 18907 * WordPress dependencies 18908 */ 18909 18910 /** 18911 * Internal dependencies 18912 */ 18913 18914 18915 function useBlockControlsFill(group, shareWithChildBlocks) { 18916 const context = useBlockEditContext(); 18917 if (context[mayDisplayControlsKey]) { 18918 return block_controls_groups[group]?.Fill; 18919 } 18920 if (context[mayDisplayParentControlsKey] && shareWithChildBlocks) { 18921 return block_controls_groups.parent.Fill; 18922 } 18923 return null; 18924 } 18925 18926 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-controls/fill.js 18927 /** 18928 * WordPress dependencies 18929 */ 18930 18931 18932 /** 18933 * Internal dependencies 18934 */ 18935 18936 18937 function BlockControlsFill({ 18938 group = 'default', 18939 controls, 18940 children, 18941 __experimentalShareWithChildBlocks = false 18942 }) { 18943 const Fill = useBlockControlsFill(group, __experimentalShareWithChildBlocks); 18944 if (!Fill) { 18945 return null; 18946 } 18947 const innerMarkup = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 18948 children: [group === 'default' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 18949 controls: controls 18950 }), children] 18951 }); 18952 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 18953 document: document, 18954 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Fill, { 18955 children: fillProps => { 18956 // `fillProps.forwardedContext` is an array of context provider entries, provided by slot, 18957 // that should wrap the fill markup. 18958 const { 18959 forwardedContext = [] 18960 } = fillProps; 18961 return forwardedContext.reduce((inner, [Provider, props]) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Provider, { 18962 ...props, 18963 children: inner 18964 }), innerMarkup); 18965 } 18966 }) 18967 }); 18968 } 18969 18970 ;// external ["wp","warning"] 18971 const external_wp_warning_namespaceObject = window["wp"]["warning"]; 18972 var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject); 18973 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-controls/slot.js 18974 /** 18975 * WordPress dependencies 18976 */ 18977 18978 18979 18980 18981 /** 18982 * Internal dependencies 18983 */ 18984 18985 18986 18987 const { 18988 ComponentsContext 18989 } = unlock(external_wp_components_namespaceObject.privateApis); 18990 function BlockControlsSlot({ 18991 group = 'default', 18992 ...props 18993 }) { 18994 const toolbarState = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolbarContext); 18995 const contextState = (0,external_wp_element_namespaceObject.useContext)(ComponentsContext); 18996 const fillProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 18997 forwardedContext: [[external_wp_components_namespaceObject.__experimentalToolbarContext.Provider, { 18998 value: toolbarState 18999 }], [ComponentsContext.Provider, { 19000 value: contextState 19001 }]] 19002 }), [toolbarState, contextState]); 19003 const slotFill = block_controls_groups[group]; 19004 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(slotFill.name); 19005 if (!slotFill) { 19006 true ? external_wp_warning_default()(`Unknown BlockControls group "$group}" provided.`) : 0; 19007 return null; 19008 } 19009 if (!fills?.length) { 19010 return null; 19011 } 19012 const { 19013 Slot 19014 } = slotFill; 19015 const slot = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Slot, { 19016 ...props, 19017 bubblesVirtually: true, 19018 fillProps: fillProps 19019 }); 19020 if (group === 'default') { 19021 return slot; 19022 } 19023 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 19024 children: slot 19025 }); 19026 } 19027 19028 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-controls/index.js 19029 /** 19030 * Internal dependencies 19031 */ 19032 19033 19034 19035 const BlockControls = BlockControlsFill; 19036 BlockControls.Slot = BlockControlsSlot; 19037 19038 // This is just here for backward compatibility. 19039 const BlockFormatControls = props => { 19040 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockControlsFill, { 19041 group: "inline", 19042 ...props 19043 }); 19044 }; 19045 BlockFormatControls.Slot = props => { 19046 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockControlsSlot, { 19047 group: "inline", 19048 ...props 19049 }); 19050 }; 19051 /* harmony default export */ const block_controls = (BlockControls); 19052 19053 ;// ./node_modules/@wordpress/icons/build-module/library/justify-left.js 19054 /** 19055 * WordPress dependencies 19056 */ 19057 19058 19059 const justifyLeft = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19060 xmlns: "http://www.w3.org/2000/svg", 19061 viewBox: "0 0 24 24", 19062 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19063 d: "M9 9v6h11V9H9zM4 20h1.5V4H4v16z" 19064 }) 19065 }); 19066 /* harmony default export */ const justify_left = (justifyLeft); 19067 19068 ;// ./node_modules/@wordpress/icons/build-module/library/justify-center.js 19069 /** 19070 * WordPress dependencies 19071 */ 19072 19073 19074 const justifyCenter = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19075 xmlns: "http://www.w3.org/2000/svg", 19076 viewBox: "0 0 24 24", 19077 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19078 d: "M12.5 15v5H11v-5H4V9h7V4h1.5v5h7v6h-7Z" 19079 }) 19080 }); 19081 /* harmony default export */ const justify_center = (justifyCenter); 19082 19083 ;// ./node_modules/@wordpress/icons/build-module/library/justify-right.js 19084 /** 19085 * WordPress dependencies 19086 */ 19087 19088 19089 const justifyRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19090 xmlns: "http://www.w3.org/2000/svg", 19091 viewBox: "0 0 24 24", 19092 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19093 d: "M4 15h11V9H4v6zM18.5 4v16H20V4h-1.5z" 19094 }) 19095 }); 19096 /* harmony default export */ const justify_right = (justifyRight); 19097 19098 ;// ./node_modules/@wordpress/icons/build-module/library/justify-space-between.js 19099 /** 19100 * WordPress dependencies 19101 */ 19102 19103 19104 const justifySpaceBetween = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19105 xmlns: "http://www.w3.org/2000/svg", 19106 viewBox: "0 0 24 24", 19107 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19108 d: "M9 15h6V9H9v6zm-5 5h1.5V4H4v16zM18.5 4v16H20V4h-1.5z" 19109 }) 19110 }); 19111 /* harmony default export */ const justify_space_between = (justifySpaceBetween); 19112 19113 ;// ./node_modules/@wordpress/icons/build-module/library/justify-stretch.js 19114 /** 19115 * WordPress dependencies 19116 */ 19117 19118 19119 const justifyStretch = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19120 xmlns: "http://www.w3.org/2000/svg", 19121 viewBox: "0 0 24 24", 19122 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19123 d: "M4 4H5.5V20H4V4ZM7 10L17 10V14L7 14V10ZM20 4H18.5V20H20V4Z" 19124 }) 19125 }); 19126 /* harmony default export */ const justify_stretch = (justifyStretch); 19127 19128 ;// ./node_modules/@wordpress/icons/build-module/library/arrow-right.js 19129 /** 19130 * WordPress dependencies 19131 */ 19132 19133 19134 const arrowRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19135 xmlns: "http://www.w3.org/2000/svg", 19136 viewBox: "0 0 24 24", 19137 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19138 d: "m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z" 19139 }) 19140 }); 19141 /* harmony default export */ const arrow_right = (arrowRight); 19142 19143 ;// ./node_modules/@wordpress/icons/build-module/library/arrow-down.js 19144 /** 19145 * WordPress dependencies 19146 */ 19147 19148 19149 const arrowDown = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19150 xmlns: "http://www.w3.org/2000/svg", 19151 viewBox: "0 0 24 24", 19152 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19153 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" 19154 }) 19155 }); 19156 /* harmony default export */ const arrow_down = (arrowDown); 19157 19158 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/definitions.js 19159 // Layout definitions keyed by layout type. 19160 // Provides a common definition of slugs, classnames, base styles, and spacing styles for each layout type. 19161 // If making changes or additions to layout definitions, be sure to update the corresponding PHP definitions in 19162 // `block-supports/layout.php` so that the server-side and client-side definitions match. 19163 const LAYOUT_DEFINITIONS = { 19164 default: { 19165 name: 'default', 19166 slug: 'flow', 19167 className: 'is-layout-flow', 19168 baseStyles: [{ 19169 selector: ' > .alignleft', 19170 rules: { 19171 float: 'left', 19172 'margin-inline-start': '0', 19173 'margin-inline-end': '2em' 19174 } 19175 }, { 19176 selector: ' > .alignright', 19177 rules: { 19178 float: 'right', 19179 'margin-inline-start': '2em', 19180 'margin-inline-end': '0' 19181 } 19182 }, { 19183 selector: ' > .aligncenter', 19184 rules: { 19185 'margin-left': 'auto !important', 19186 'margin-right': 'auto !important' 19187 } 19188 }], 19189 spacingStyles: [{ 19190 selector: ' > :first-child', 19191 rules: { 19192 'margin-block-start': '0' 19193 } 19194 }, { 19195 selector: ' > :last-child', 19196 rules: { 19197 'margin-block-end': '0' 19198 } 19199 }, { 19200 selector: ' > *', 19201 rules: { 19202 'margin-block-start': null, 19203 'margin-block-end': '0' 19204 } 19205 }] 19206 }, 19207 constrained: { 19208 name: 'constrained', 19209 slug: 'constrained', 19210 className: 'is-layout-constrained', 19211 baseStyles: [{ 19212 selector: ' > .alignleft', 19213 rules: { 19214 float: 'left', 19215 'margin-inline-start': '0', 19216 'margin-inline-end': '2em' 19217 } 19218 }, { 19219 selector: ' > .alignright', 19220 rules: { 19221 float: 'right', 19222 'margin-inline-start': '2em', 19223 'margin-inline-end': '0' 19224 } 19225 }, { 19226 selector: ' > .aligncenter', 19227 rules: { 19228 'margin-left': 'auto !important', 19229 'margin-right': 'auto !important' 19230 } 19231 }, { 19232 selector: ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))', 19233 rules: { 19234 'max-width': 'var(--wp--style--global--content-size)', 19235 'margin-left': 'auto !important', 19236 'margin-right': 'auto !important' 19237 } 19238 }, { 19239 selector: ' > .alignwide', 19240 rules: { 19241 'max-width': 'var(--wp--style--global--wide-size)' 19242 } 19243 }], 19244 spacingStyles: [{ 19245 selector: ' > :first-child', 19246 rules: { 19247 'margin-block-start': '0' 19248 } 19249 }, { 19250 selector: ' > :last-child', 19251 rules: { 19252 'margin-block-end': '0' 19253 } 19254 }, { 19255 selector: ' > *', 19256 rules: { 19257 'margin-block-start': null, 19258 'margin-block-end': '0' 19259 } 19260 }] 19261 }, 19262 flex: { 19263 name: 'flex', 19264 slug: 'flex', 19265 className: 'is-layout-flex', 19266 displayMode: 'flex', 19267 baseStyles: [{ 19268 selector: '', 19269 rules: { 19270 'flex-wrap': 'wrap', 19271 'align-items': 'center' 19272 } 19273 }, { 19274 selector: ' > :is(*, div)', 19275 // :is(*, div) instead of just * increases the specificity by 001. 19276 rules: { 19277 margin: '0' 19278 } 19279 }], 19280 spacingStyles: [{ 19281 selector: '', 19282 rules: { 19283 gap: null 19284 } 19285 }] 19286 }, 19287 grid: { 19288 name: 'grid', 19289 slug: 'grid', 19290 className: 'is-layout-grid', 19291 displayMode: 'grid', 19292 baseStyles: [{ 19293 selector: ' > :is(*, div)', 19294 // :is(*, div) instead of just * increases the specificity by 001. 19295 rules: { 19296 margin: '0' 19297 } 19298 }], 19299 spacingStyles: [{ 19300 selector: '', 19301 rules: { 19302 gap: null 19303 } 19304 }] 19305 } 19306 }; 19307 19308 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/utils.js 19309 /** 19310 * WordPress dependencies 19311 */ 19312 19313 19314 /** 19315 * Internal dependencies 19316 */ 19317 19318 19319 /** 19320 * Utility to generate the proper CSS selector for layout styles. 19321 * 19322 * @param {string} selectors CSS selector, also supports multiple comma-separated selectors. 19323 * @param {string} append The string to append. 19324 * 19325 * @return {string} - CSS selector. 19326 */ 19327 function appendSelectors(selectors, append = '') { 19328 return selectors.split(',').map(subselector => `$subselector}$append ? ` $append}` : ''}`).join(','); 19329 } 19330 19331 /** 19332 * Get generated blockGap CSS rules based on layout definitions provided in theme.json 19333 * Falsy values in the layout definition's spacingStyles rules will be swapped out 19334 * with the provided `blockGapValue`. 19335 * 19336 * @param {string} selector The CSS selector to target for the generated rules. 19337 * @param {Object} layoutDefinitions Layout definitions object. 19338 * @param {string} layoutType The layout type (e.g. `default` or `flex`). 19339 * @param {string} blockGapValue The current blockGap value to be applied. 19340 * @return {string} The generated CSS rules. 19341 */ 19342 function getBlockGapCSS(selector, layoutDefinitions = LAYOUT_DEFINITIONS, layoutType, blockGapValue) { 19343 let output = ''; 19344 if (layoutDefinitions?.[layoutType]?.spacingStyles?.length && blockGapValue) { 19345 layoutDefinitions[layoutType].spacingStyles.forEach(gapStyle => { 19346 output += `$appendSelectors(selector, gapStyle.selector.trim())} { `; 19347 output += Object.entries(gapStyle.rules).map(([cssProperty, value]) => `$cssProperty}: $value ? value : blockGapValue}`).join('; '); 19348 output += '; }'; 19349 }); 19350 } 19351 return output; 19352 } 19353 19354 /** 19355 * Helper method to assign contextual info to clarify 19356 * alignment settings. 19357 * 19358 * Besides checking if `contentSize` and `wideSize` have a 19359 * value, we now show this information only if their values 19360 * are not a `css var`. This needs to change when parsing 19361 * css variables land. 19362 * 19363 * @see https://github.com/WordPress/gutenberg/pull/34710#issuecomment-918000752 19364 * 19365 * @param {Object} layout The layout object. 19366 * @return {Object} An object with contextual info per alignment. 19367 */ 19368 function getAlignmentsInfo(layout) { 19369 const { 19370 contentSize, 19371 wideSize, 19372 type = 'default' 19373 } = layout; 19374 const alignmentInfo = {}; 19375 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; 19376 if (sizeRegex.test(contentSize) && type === 'constrained') { 19377 // translators: %s: container size (i.e. 600px etc) 19378 alignmentInfo.none = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Max %s wide'), contentSize); 19379 } 19380 if (sizeRegex.test(wideSize)) { 19381 // translators: %s: container size (i.e. 600px etc) 19382 alignmentInfo.wide = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Max %s wide'), wideSize); 19383 } 19384 return alignmentInfo; 19385 } 19386 19387 ;// ./node_modules/@wordpress/icons/build-module/library/sides-all.js 19388 /** 19389 * WordPress dependencies 19390 */ 19391 19392 19393 const sidesAll = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19394 xmlns: "http://www.w3.org/2000/svg", 19395 viewBox: "0 0 24 24", 19396 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19397 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z" 19398 }) 19399 }); 19400 /* harmony default export */ const sides_all = (sidesAll); 19401 19402 ;// ./node_modules/@wordpress/icons/build-module/library/sides-horizontal.js 19403 /** 19404 * WordPress dependencies 19405 */ 19406 19407 19408 const sidesHorizontal = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 19409 xmlns: "http://www.w3.org/2000/svg", 19410 viewBox: "0 0 24 24", 19411 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19412 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 19413 style: { 19414 opacity: 0.25 19415 } 19416 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19417 d: "m4.5 7.5v9h1.5v-9z" 19418 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19419 d: "m18 7.5v9h1.5v-9z" 19420 })] 19421 }); 19422 /* harmony default export */ const sides_horizontal = (sidesHorizontal); 19423 19424 ;// ./node_modules/@wordpress/icons/build-module/library/sides-vertical.js 19425 /** 19426 * WordPress dependencies 19427 */ 19428 19429 19430 const sidesVertical = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 19431 xmlns: "http://www.w3.org/2000/svg", 19432 viewBox: "0 0 24 24", 19433 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19434 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 19435 style: { 19436 opacity: 0.25 19437 } 19438 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19439 d: "m7.5 6h9v-1.5h-9z" 19440 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19441 d: "m7.5 19.5h9v-1.5h-9z" 19442 })] 19443 }); 19444 /* harmony default export */ const sides_vertical = (sidesVertical); 19445 19446 ;// ./node_modules/@wordpress/icons/build-module/library/sides-top.js 19447 /** 19448 * WordPress dependencies 19449 */ 19450 19451 19452 const sidesTop = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 19453 xmlns: "http://www.w3.org/2000/svg", 19454 viewBox: "0 0 24 24", 19455 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19456 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 19457 style: { 19458 opacity: 0.25 19459 } 19460 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19461 d: "m16.5 6h-9v-1.5h9z" 19462 })] 19463 }); 19464 /* harmony default export */ const sides_top = (sidesTop); 19465 19466 ;// ./node_modules/@wordpress/icons/build-module/library/sides-right.js 19467 /** 19468 * WordPress dependencies 19469 */ 19470 19471 19472 const sidesRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 19473 xmlns: "http://www.w3.org/2000/svg", 19474 viewBox: "0 0 24 24", 19475 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19476 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 19477 style: { 19478 opacity: 0.25 19479 } 19480 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19481 d: "m18 16.5v-9h1.5v9z" 19482 })] 19483 }); 19484 /* harmony default export */ const sides_right = (sidesRight); 19485 19486 ;// ./node_modules/@wordpress/icons/build-module/library/sides-bottom.js 19487 /** 19488 * WordPress dependencies 19489 */ 19490 19491 19492 const sidesBottom = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 19493 xmlns: "http://www.w3.org/2000/svg", 19494 viewBox: "0 0 24 24", 19495 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19496 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 19497 style: { 19498 opacity: 0.25 19499 } 19500 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19501 d: "m16.5 19.5h-9v-1.5h9z" 19502 })] 19503 }); 19504 /* harmony default export */ const sides_bottom = (sidesBottom); 19505 19506 ;// ./node_modules/@wordpress/icons/build-module/library/sides-left.js 19507 /** 19508 * WordPress dependencies 19509 */ 19510 19511 19512 const sidesLeft = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 19513 xmlns: "http://www.w3.org/2000/svg", 19514 viewBox: "0 0 24 24", 19515 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19516 d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z", 19517 style: { 19518 opacity: 0.25 19519 } 19520 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19521 d: "m4.5 16.5v-9h1.5v9z" 19522 })] 19523 }); 19524 /* harmony default export */ const sides_left = (sidesLeft); 19525 19526 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/utils.js 19527 /** 19528 * WordPress dependencies 19529 */ 19530 19531 19532 const RANGE_CONTROL_MAX_SIZE = 8; 19533 const ALL_SIDES = ['top', 'right', 'bottom', 'left']; 19534 const DEFAULT_VALUES = { 19535 top: undefined, 19536 right: undefined, 19537 bottom: undefined, 19538 left: undefined 19539 }; 19540 const ICONS = { 19541 custom: sides_all, 19542 axial: sides_all, 19543 horizontal: sides_horizontal, 19544 vertical: sides_vertical, 19545 top: sides_top, 19546 right: sides_right, 19547 bottom: sides_bottom, 19548 left: sides_left 19549 }; 19550 const LABELS = { 19551 default: (0,external_wp_i18n_namespaceObject.__)('Spacing control'), 19552 top: (0,external_wp_i18n_namespaceObject.__)('Top'), 19553 bottom: (0,external_wp_i18n_namespaceObject.__)('Bottom'), 19554 left: (0,external_wp_i18n_namespaceObject.__)('Left'), 19555 right: (0,external_wp_i18n_namespaceObject.__)('Right'), 19556 mixed: (0,external_wp_i18n_namespaceObject.__)('Mixed'), 19557 vertical: (0,external_wp_i18n_namespaceObject.__)('Vertical'), 19558 horizontal: (0,external_wp_i18n_namespaceObject.__)('Horizontal'), 19559 axial: (0,external_wp_i18n_namespaceObject.__)('Horizontal & vertical'), 19560 custom: (0,external_wp_i18n_namespaceObject.__)('Custom') 19561 }; 19562 const VIEWS = { 19563 axial: 'axial', 19564 top: 'top', 19565 right: 'right', 19566 bottom: 'bottom', 19567 left: 'left', 19568 custom: 'custom' 19569 }; 19570 19571 /** 19572 * Checks is given value is a spacing preset. 19573 * 19574 * @param {string} value Value to check 19575 * 19576 * @return {boolean} Return true if value is string in format var:preset|spacing|. 19577 */ 19578 function isValueSpacingPreset(value) { 19579 if (!value?.includes) { 19580 return false; 19581 } 19582 return value === '0' || value.includes('var:preset|spacing|'); 19583 } 19584 19585 /** 19586 * Converts a spacing preset into a custom value. 19587 * 19588 * @param {string} value Value to convert 19589 * @param {Array} spacingSizes Array of the current spacing preset objects 19590 * 19591 * @return {string} Mapping of the spacing preset to its equivalent custom value. 19592 */ 19593 function getCustomValueFromPreset(value, spacingSizes) { 19594 if (!isValueSpacingPreset(value)) { 19595 return value; 19596 } 19597 const slug = getSpacingPresetSlug(value); 19598 const spacingSize = spacingSizes.find(size => String(size.slug) === slug); 19599 return spacingSize?.size; 19600 } 19601 19602 /** 19603 * Converts a custom value to preset value if one can be found. 19604 * 19605 * Returns value as-is if no match is found. 19606 * 19607 * @param {string} value Value to convert 19608 * @param {Array} spacingSizes Array of the current spacing preset objects 19609 * 19610 * @return {string} The preset value if it can be found. 19611 */ 19612 function getPresetValueFromCustomValue(value, spacingSizes) { 19613 // Return value as-is if it is undefined or is already a preset, or '0'; 19614 if (!value || isValueSpacingPreset(value) || value === '0') { 19615 return value; 19616 } 19617 const spacingMatch = spacingSizes.find(size => String(size.size) === String(value)); 19618 if (spacingMatch?.slug) { 19619 return `var:preset|spacing|$spacingMatch.slug}`; 19620 } 19621 return value; 19622 } 19623 19624 /** 19625 * Converts a spacing preset into a custom value. 19626 * 19627 * @param {string} value Value to convert. 19628 * 19629 * @return {string | undefined} CSS var string for given spacing preset value. 19630 */ 19631 function getSpacingPresetCssVar(value) { 19632 if (!value) { 19633 return; 19634 } 19635 const slug = value.match(/var:preset\|spacing\|(.+)/); 19636 if (!slug) { 19637 return value; 19638 } 19639 return `var(--wp--preset--spacing--$slug[1]})`; 19640 } 19641 19642 /** 19643 * Returns the slug section of the given spacing preset string. 19644 * 19645 * @param {string} value Value to extract slug from. 19646 * 19647 * @return {string|undefined} The int value of the slug from given spacing preset. 19648 */ 19649 function getSpacingPresetSlug(value) { 19650 if (!value) { 19651 return; 19652 } 19653 if (value === '0' || value === 'default') { 19654 return value; 19655 } 19656 const slug = value.match(/var:preset\|spacing\|(.+)/); 19657 return slug ? slug[1] : undefined; 19658 } 19659 19660 /** 19661 * Converts spacing preset value into a Range component value . 19662 * 19663 * @param {string} presetValue Value to convert to Range value. 19664 * @param {Array} spacingSizes Array of current spacing preset value objects. 19665 * 19666 * @return {number} The int value for use in Range control. 19667 */ 19668 function getSliderValueFromPreset(presetValue, spacingSizes) { 19669 if (presetValue === undefined) { 19670 return 0; 19671 } 19672 const slug = parseFloat(presetValue, 10) === 0 ? '0' : getSpacingPresetSlug(presetValue); 19673 const sliderValue = spacingSizes.findIndex(spacingSize => { 19674 return String(spacingSize.slug) === slug; 19675 }); 19676 19677 // Returning NaN rather than undefined as undefined makes range control thumb sit in center 19678 return sliderValue !== -1 ? sliderValue : NaN; 19679 } 19680 19681 /** 19682 * Determines whether a particular axis has support. If no axis is 19683 * specified, this function checks if either axis is supported. 19684 * 19685 * @param {Array} sides Supported sides. 19686 * @param {string} axis Which axis to check. 19687 * 19688 * @return {boolean} Whether there is support for the specified axis or both axes. 19689 */ 19690 function hasAxisSupport(sides, axis) { 19691 if (!sides || !sides.length) { 19692 return false; 19693 } 19694 const hasHorizontalSupport = sides.includes('horizontal') || sides.includes('left') && sides.includes('right'); 19695 const hasVerticalSupport = sides.includes('vertical') || sides.includes('top') && sides.includes('bottom'); 19696 if (axis === 'horizontal') { 19697 return hasHorizontalSupport; 19698 } 19699 if (axis === 'vertical') { 19700 return hasVerticalSupport; 19701 } 19702 return hasHorizontalSupport || hasVerticalSupport; 19703 } 19704 19705 /** 19706 * Checks if the supported sides are balanced for each axis. 19707 * - Horizontal - both left and right sides are supported. 19708 * - Vertical - both top and bottom are supported. 19709 * 19710 * @param {Array} sides The supported sides which may be axes as well. 19711 * 19712 * @return {boolean} Whether or not the supported sides are balanced. 19713 */ 19714 function hasBalancedSidesSupport(sides = []) { 19715 const counts = { 19716 top: 0, 19717 right: 0, 19718 bottom: 0, 19719 left: 0 19720 }; 19721 sides.forEach(side => counts[side] += 1); 19722 return (counts.top + counts.bottom) % 2 === 0 && (counts.left + counts.right) % 2 === 0; 19723 } 19724 19725 /** 19726 * Determines which view the SpacingSizesControl should default to on its 19727 * first render; Axial, Custom, or Single side. 19728 * 19729 * @param {Object} values Current side values. 19730 * @param {Array} sides Supported sides. 19731 * 19732 * @return {string} View to display. 19733 */ 19734 function getInitialView(values = {}, sides) { 19735 const { 19736 top, 19737 right, 19738 bottom, 19739 left 19740 } = values; 19741 const sideValues = [top, right, bottom, left].filter(Boolean); 19742 19743 // Axial ( Horizontal & vertical ). 19744 // - Has axial side support 19745 // - Has axial side values which match 19746 // - Has no values and the supported sides are balanced 19747 const hasMatchingAxialValues = top === bottom && left === right && (!!top || !!left); 19748 const hasNoValuesAndBalancedSides = !sideValues.length && hasBalancedSidesSupport(sides); 19749 const hasOnlyAxialSides = sides?.includes('horizontal') && sides?.includes('vertical') && sides?.length === 2; 19750 if (hasAxisSupport(sides) && (hasMatchingAxialValues || hasNoValuesAndBalancedSides)) { 19751 return VIEWS.axial; 19752 } 19753 19754 // Only axial sides are supported and single value defined. 19755 // - Ensure the side returned is the first side that has a value. 19756 if (hasOnlyAxialSides && sideValues.length === 1) { 19757 let side; 19758 Object.entries(values).some(([key, value]) => { 19759 side = key; 19760 return value !== undefined; 19761 }); 19762 return side; 19763 } 19764 19765 // Only single side supported and no value defined. 19766 if (sides?.length === 1 && !sideValues.length) { 19767 return sides[0]; 19768 } 19769 19770 // Default to the Custom (separated sides) view. 19771 return VIEWS.custom; 19772 } 19773 19774 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/gap.js 19775 /** 19776 * Internal dependencies 19777 */ 19778 19779 19780 /** 19781 * Returns a BoxControl object value from a given blockGap style value. 19782 * The string check is for backwards compatibility before Gutenberg supported 19783 * split gap values (row and column) and the value was a string n + unit. 19784 * 19785 * @param {?string | ?Object} blockGapValue A block gap string or axial object value, e.g., '10px' or { top: '10px', left: '10px'}. 19786 * @return {Object|null} A value to pass to the BoxControl component. 19787 */ 19788 function getGapBoxControlValueFromStyle(blockGapValue) { 19789 if (!blockGapValue) { 19790 return null; 19791 } 19792 const isValueString = typeof blockGapValue === 'string'; 19793 return { 19794 top: isValueString ? blockGapValue : blockGapValue?.top, 19795 left: isValueString ? blockGapValue : blockGapValue?.left 19796 }; 19797 } 19798 19799 /** 19800 * Returns a CSS value for the `gap` property from a given blockGap style. 19801 * 19802 * @param {?string | ?Object} blockGapValue A block gap string or axial object value, e.g., '10px' or { top: '10px', left: '10px'}. 19803 * @param {?string} defaultValue A default gap value. 19804 * @return {string|null} The concatenated gap value (row and column). 19805 */ 19806 function getGapCSSValue(blockGapValue, defaultValue = '0') { 19807 const blockGapBoxControlValue = getGapBoxControlValueFromStyle(blockGapValue); 19808 if (!blockGapBoxControlValue) { 19809 return null; 19810 } 19811 const row = getSpacingPresetCssVar(blockGapBoxControlValue?.top) || defaultValue; 19812 const column = getSpacingPresetCssVar(blockGapBoxControlValue?.left) || defaultValue; 19813 return row === column ? row : `$row} $column}`; 19814 } 19815 19816 ;// ./node_modules/@wordpress/icons/build-module/library/justify-top.js 19817 /** 19818 * WordPress dependencies 19819 */ 19820 19821 19822 const justifyTop = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19823 xmlns: "http://www.w3.org/2000/svg", 19824 viewBox: "0 0 24 24", 19825 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19826 d: "M9 20h6V9H9v11zM4 4v1.5h16V4H4z" 19827 }) 19828 }); 19829 /* harmony default export */ const justify_top = (justifyTop); 19830 19831 ;// ./node_modules/@wordpress/icons/build-module/library/justify-center-vertical.js 19832 /** 19833 * WordPress dependencies 19834 */ 19835 19836 19837 const justifyCenterVertical = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19838 xmlns: "http://www.w3.org/2000/svg", 19839 viewBox: "0 0 24 24", 19840 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19841 d: "M20 11h-5V4H9v7H4v1.5h5V20h6v-7.5h5z" 19842 }) 19843 }); 19844 /* harmony default export */ const justify_center_vertical = (justifyCenterVertical); 19845 19846 ;// ./node_modules/@wordpress/icons/build-module/library/justify-bottom.js 19847 /** 19848 * WordPress dependencies 19849 */ 19850 19851 19852 const justifyBottom = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19853 xmlns: "http://www.w3.org/2000/svg", 19854 viewBox: "0 0 24 24", 19855 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19856 d: "M15 4H9v11h6V4zM4 18.5V20h16v-1.5H4z" 19857 }) 19858 }); 19859 /* harmony default export */ const justify_bottom = (justifyBottom); 19860 19861 ;// ./node_modules/@wordpress/icons/build-module/library/justify-stretch-vertical.js 19862 /** 19863 * WordPress dependencies 19864 */ 19865 19866 19867 const justifyStretchVertical = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19868 xmlns: "http://www.w3.org/2000/svg", 19869 viewBox: "0 0 24 24", 19870 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19871 d: "M4 4L20 4L20 5.5L4 5.5L4 4ZM10 7L14 7L14 17L10 17L10 7ZM20 18.5L4 18.5L4 20L20 20L20 18.5Z" 19872 }) 19873 }); 19874 /* harmony default export */ const justify_stretch_vertical = (justifyStretchVertical); 19875 19876 ;// ./node_modules/@wordpress/icons/build-module/library/justify-space-between-vertical.js 19877 /** 19878 * WordPress dependencies 19879 */ 19880 19881 19882 const justifySpaceBetweenVertical = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 19883 xmlns: "http://www.w3.org/2000/svg", 19884 viewBox: "0 0 24 24", 19885 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 19886 d: "M7 4H17V8L7 8V4ZM7 16L17 16V20L7 20V16ZM20 11.25H4V12.75H20V11.25Z" 19887 }) 19888 }); 19889 /* harmony default export */ const justify_space_between_vertical = (justifySpaceBetweenVertical); 19890 19891 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/ui.js 19892 /** 19893 * WordPress dependencies 19894 */ 19895 19896 19897 19898 19899 const BLOCK_ALIGNMENTS_CONTROLS = { 19900 top: { 19901 icon: justify_top, 19902 title: (0,external_wp_i18n_namespaceObject._x)('Align top', 'Block vertical alignment setting') 19903 }, 19904 center: { 19905 icon: justify_center_vertical, 19906 title: (0,external_wp_i18n_namespaceObject._x)('Align middle', 'Block vertical alignment setting') 19907 }, 19908 bottom: { 19909 icon: justify_bottom, 19910 title: (0,external_wp_i18n_namespaceObject._x)('Align bottom', 'Block vertical alignment setting') 19911 }, 19912 stretch: { 19913 icon: justify_stretch_vertical, 19914 title: (0,external_wp_i18n_namespaceObject._x)('Stretch to fill', 'Block vertical alignment setting') 19915 }, 19916 'space-between': { 19917 icon: justify_space_between_vertical, 19918 title: (0,external_wp_i18n_namespaceObject._x)('Space between', 'Block vertical alignment setting') 19919 } 19920 }; 19921 const DEFAULT_CONTROLS = ['top', 'center', 'bottom']; 19922 const DEFAULT_CONTROL = 'top'; 19923 function BlockVerticalAlignmentUI({ 19924 value, 19925 onChange, 19926 controls = DEFAULT_CONTROLS, 19927 isCollapsed = true, 19928 isToolbar 19929 }) { 19930 function applyOrUnset(align) { 19931 return () => onChange(value === align ? undefined : align); 19932 } 19933 const activeAlignment = BLOCK_ALIGNMENTS_CONTROLS[value]; 19934 const defaultAlignmentControl = BLOCK_ALIGNMENTS_CONTROLS[DEFAULT_CONTROL]; 19935 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 19936 const extraProps = isToolbar ? { 19937 isCollapsed 19938 } : {}; 19939 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(UIComponent, { 19940 icon: activeAlignment ? activeAlignment.icon : defaultAlignmentControl.icon, 19941 label: (0,external_wp_i18n_namespaceObject._x)('Change vertical alignment', 'Block vertical alignment setting label'), 19942 controls: controls.map(control => { 19943 return { 19944 ...BLOCK_ALIGNMENTS_CONTROLS[control], 19945 isActive: value === control, 19946 role: isCollapsed ? 'menuitemradio' : undefined, 19947 onClick: applyOrUnset(control) 19948 }; 19949 }), 19950 ...extraProps 19951 }); 19952 } 19953 19954 /** 19955 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-vertical-alignment-toolbar/README.md 19956 */ 19957 /* harmony default export */ const ui = (BlockVerticalAlignmentUI); 19958 19959 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/index.js 19960 /** 19961 * Internal dependencies 19962 */ 19963 19964 19965 const BlockVerticalAlignmentControl = props => { 19966 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ui, { 19967 ...props, 19968 isToolbar: false 19969 }); 19970 }; 19971 const BlockVerticalAlignmentToolbar = props => { 19972 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ui, { 19973 ...props, 19974 isToolbar: true 19975 }); 19976 }; 19977 19978 /** 19979 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-vertical-alignment-control/README.md 19980 */ 19981 19982 19983 ;// ./node_modules/@wordpress/block-editor/build-module/components/justify-content-control/ui.js 19984 /** 19985 * WordPress dependencies 19986 */ 19987 19988 19989 19990 19991 const icons = { 19992 left: justify_left, 19993 center: justify_center, 19994 right: justify_right, 19995 'space-between': justify_space_between, 19996 stretch: justify_stretch 19997 }; 19998 function JustifyContentUI({ 19999 allowedControls = ['left', 'center', 'right', 'space-between'], 20000 isCollapsed = true, 20001 onChange, 20002 value, 20003 popoverProps, 20004 isToolbar 20005 }) { 20006 // If the control is already selected we want a click 20007 // again on the control to deselect the item, so we 20008 // call onChange( undefined ) 20009 const handleClick = next => { 20010 if (next === value) { 20011 onChange(undefined); 20012 } else { 20013 onChange(next); 20014 } 20015 }; 20016 const icon = value ? icons[value] : icons.left; 20017 const allControls = [{ 20018 name: 'left', 20019 icon: justify_left, 20020 title: (0,external_wp_i18n_namespaceObject.__)('Justify items left'), 20021 isActive: 'left' === value, 20022 onClick: () => handleClick('left') 20023 }, { 20024 name: 'center', 20025 icon: justify_center, 20026 title: (0,external_wp_i18n_namespaceObject.__)('Justify items center'), 20027 isActive: 'center' === value, 20028 onClick: () => handleClick('center') 20029 }, { 20030 name: 'right', 20031 icon: justify_right, 20032 title: (0,external_wp_i18n_namespaceObject.__)('Justify items right'), 20033 isActive: 'right' === value, 20034 onClick: () => handleClick('right') 20035 }, { 20036 name: 'space-between', 20037 icon: justify_space_between, 20038 title: (0,external_wp_i18n_namespaceObject.__)('Space between items'), 20039 isActive: 'space-between' === value, 20040 onClick: () => handleClick('space-between') 20041 }, { 20042 name: 'stretch', 20043 icon: justify_stretch, 20044 title: (0,external_wp_i18n_namespaceObject.__)('Stretch items'), 20045 isActive: 'stretch' === value, 20046 onClick: () => handleClick('stretch') 20047 }]; 20048 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 20049 const extraProps = isToolbar ? { 20050 isCollapsed 20051 } : {}; 20052 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(UIComponent, { 20053 icon: icon, 20054 popoverProps: popoverProps, 20055 label: (0,external_wp_i18n_namespaceObject.__)('Change items justification'), 20056 controls: allControls.filter(elem => allowedControls.includes(elem.name)), 20057 ...extraProps 20058 }); 20059 } 20060 /* harmony default export */ const justify_content_control_ui = (JustifyContentUI); 20061 20062 ;// ./node_modules/@wordpress/block-editor/build-module/components/justify-content-control/index.js 20063 /** 20064 * Internal dependencies 20065 */ 20066 20067 20068 const JustifyContentControl = props => { 20069 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(justify_content_control_ui, { 20070 ...props, 20071 isToolbar: false 20072 }); 20073 }; 20074 const JustifyToolbar = props => { 20075 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(justify_content_control_ui, { 20076 ...props, 20077 isToolbar: true 20078 }); 20079 }; 20080 20081 /** 20082 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/justify-content-control/README.md 20083 */ 20084 20085 20086 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/flex.js 20087 /** 20088 * WordPress dependencies 20089 */ 20090 20091 20092 20093 20094 /** 20095 * Internal dependencies 20096 */ 20097 20098 20099 20100 20101 20102 20103 // Used with the default, horizontal flex orientation. 20104 20105 const justifyContentMap = { 20106 left: 'flex-start', 20107 right: 'flex-end', 20108 center: 'center', 20109 'space-between': 'space-between' 20110 }; 20111 20112 // Used with the vertical (column) flex orientation. 20113 const alignItemsMap = { 20114 left: 'flex-start', 20115 right: 'flex-end', 20116 center: 'center', 20117 stretch: 'stretch' 20118 }; 20119 const verticalAlignmentMap = { 20120 top: 'flex-start', 20121 center: 'center', 20122 bottom: 'flex-end', 20123 stretch: 'stretch', 20124 'space-between': 'space-between' 20125 }; 20126 const flexWrapOptions = ['wrap', 'nowrap']; 20127 /* harmony default export */ const flex = ({ 20128 name: 'flex', 20129 label: (0,external_wp_i18n_namespaceObject.__)('Flex'), 20130 inspectorControls: function FlexLayoutInspectorControls({ 20131 layout = {}, 20132 onChange, 20133 layoutBlockSupport = {} 20134 }) { 20135 const { 20136 allowOrientation = true, 20137 allowJustification = true 20138 } = layoutBlockSupport; 20139 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 20140 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 20141 children: [allowJustification && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 20142 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FlexLayoutJustifyContentControl, { 20143 layout: layout, 20144 onChange: onChange 20145 }) 20146 }), allowOrientation && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 20147 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(OrientationControl, { 20148 layout: layout, 20149 onChange: onChange 20150 }) 20151 })] 20152 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FlexWrapControl, { 20153 layout: layout, 20154 onChange: onChange 20155 })] 20156 }); 20157 }, 20158 toolBarControls: function FlexLayoutToolbarControls({ 20159 layout = {}, 20160 onChange, 20161 layoutBlockSupport 20162 }) { 20163 const { 20164 allowVerticalAlignment = true, 20165 allowJustification = true 20166 } = layoutBlockSupport; 20167 if (!allowJustification && !allowVerticalAlignment) { 20168 return null; 20169 } 20170 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(block_controls, { 20171 group: "block", 20172 __experimentalShareWithChildBlocks: true, 20173 children: [allowJustification && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FlexLayoutJustifyContentControl, { 20174 layout: layout, 20175 onChange: onChange, 20176 isToolbar: true 20177 }), allowVerticalAlignment && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FlexLayoutVerticalAlignmentControl, { 20178 layout: layout, 20179 onChange: onChange 20180 })] 20181 }); 20182 }, 20183 getLayoutStyle: function getLayoutStyle({ 20184 selector, 20185 layout, 20186 style, 20187 blockName, 20188 hasBlockGapSupport, 20189 layoutDefinitions = LAYOUT_DEFINITIONS 20190 }) { 20191 const { 20192 orientation = 'horizontal' 20193 } = layout; 20194 20195 // If a block's block.json skips serialization for spacing or spacing.blockGap, 20196 // don't apply the user-defined value to the styles. 20197 const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, 'spacing', 'blockGap') ? getGapCSSValue(style?.spacing?.blockGap, '0.5em') : undefined; 20198 const justifyContent = justifyContentMap[layout.justifyContent]; 20199 const flexWrap = flexWrapOptions.includes(layout.flexWrap) ? layout.flexWrap : 'wrap'; 20200 const verticalAlignment = verticalAlignmentMap[layout.verticalAlignment]; 20201 const alignItems = alignItemsMap[layout.justifyContent] || alignItemsMap.left; 20202 let output = ''; 20203 const rules = []; 20204 if (flexWrap && flexWrap !== 'wrap') { 20205 rules.push(`flex-wrap: $flexWrap}`); 20206 } 20207 if (orientation === 'horizontal') { 20208 if (verticalAlignment) { 20209 rules.push(`align-items: $verticalAlignment}`); 20210 } 20211 if (justifyContent) { 20212 rules.push(`justify-content: $justifyContent}`); 20213 } 20214 } else { 20215 if (verticalAlignment) { 20216 rules.push(`justify-content: $verticalAlignment}`); 20217 } 20218 rules.push('flex-direction: column'); 20219 rules.push(`align-items: $alignItems}`); 20220 } 20221 if (rules.length) { 20222 output = `$appendSelectors(selector)} { 20223 $rules.join('; ')}; 20224 }`; 20225 } 20226 20227 // Output blockGap styles based on rules contained in layout definitions in theme.json. 20228 if (hasBlockGapSupport && blockGapValue) { 20229 output += getBlockGapCSS(selector, layoutDefinitions, 'flex', blockGapValue); 20230 } 20231 return output; 20232 }, 20233 getOrientation(layout) { 20234 const { 20235 orientation = 'horizontal' 20236 } = layout; 20237 return orientation; 20238 }, 20239 getAlignments() { 20240 return []; 20241 } 20242 }); 20243 function FlexLayoutVerticalAlignmentControl({ 20244 layout, 20245 onChange 20246 }) { 20247 const { 20248 orientation = 'horizontal' 20249 } = layout; 20250 const defaultVerticalAlignment = orientation === 'horizontal' ? verticalAlignmentMap.center : verticalAlignmentMap.top; 20251 const { 20252 verticalAlignment = defaultVerticalAlignment 20253 } = layout; 20254 const onVerticalAlignmentChange = value => { 20255 onChange({ 20256 ...layout, 20257 verticalAlignment: value 20258 }); 20259 }; 20260 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockVerticalAlignmentControl, { 20261 onChange: onVerticalAlignmentChange, 20262 value: verticalAlignment, 20263 controls: orientation === 'horizontal' ? ['top', 'center', 'bottom', 'stretch'] : ['top', 'center', 'bottom', 'space-between'] 20264 }); 20265 } 20266 const POPOVER_PROPS = { 20267 placement: 'bottom-start' 20268 }; 20269 function FlexLayoutJustifyContentControl({ 20270 layout, 20271 onChange, 20272 isToolbar = false 20273 }) { 20274 const { 20275 justifyContent = 'left', 20276 orientation = 'horizontal' 20277 } = layout; 20278 const onJustificationChange = value => { 20279 onChange({ 20280 ...layout, 20281 justifyContent: value 20282 }); 20283 }; 20284 const allowedControls = ['left', 'center', 'right']; 20285 if (orientation === 'horizontal') { 20286 allowedControls.push('space-between'); 20287 } else { 20288 allowedControls.push('stretch'); 20289 } 20290 if (isToolbar) { 20291 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(JustifyContentControl, { 20292 allowedControls: allowedControls, 20293 value: justifyContent, 20294 onChange: onJustificationChange, 20295 popoverProps: POPOVER_PROPS 20296 }); 20297 } 20298 const justificationOptions = [{ 20299 value: 'left', 20300 icon: justify_left, 20301 label: (0,external_wp_i18n_namespaceObject.__)('Justify items left') 20302 }, { 20303 value: 'center', 20304 icon: justify_center, 20305 label: (0,external_wp_i18n_namespaceObject.__)('Justify items center') 20306 }, { 20307 value: 'right', 20308 icon: justify_right, 20309 label: (0,external_wp_i18n_namespaceObject.__)('Justify items right') 20310 }]; 20311 if (orientation === 'horizontal') { 20312 justificationOptions.push({ 20313 value: 'space-between', 20314 icon: justify_space_between, 20315 label: (0,external_wp_i18n_namespaceObject.__)('Space between items') 20316 }); 20317 } else { 20318 justificationOptions.push({ 20319 value: 'stretch', 20320 icon: justify_stretch, 20321 label: (0,external_wp_i18n_namespaceObject.__)('Stretch items') 20322 }); 20323 } 20324 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 20325 __next40pxDefaultSize: true, 20326 __nextHasNoMarginBottom: true, 20327 label: (0,external_wp_i18n_namespaceObject.__)('Justification'), 20328 value: justifyContent, 20329 onChange: onJustificationChange, 20330 className: "block-editor-hooks__flex-layout-justification-controls", 20331 children: justificationOptions.map(({ 20332 value, 20333 icon, 20334 label 20335 }) => { 20336 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 20337 value: value, 20338 icon: icon, 20339 label: label 20340 }, value); 20341 }) 20342 }); 20343 } 20344 function FlexWrapControl({ 20345 layout, 20346 onChange 20347 }) { 20348 const { 20349 flexWrap = 'wrap' 20350 } = layout; 20351 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 20352 __nextHasNoMarginBottom: true, 20353 label: (0,external_wp_i18n_namespaceObject.__)('Allow to wrap to multiple lines'), 20354 onChange: value => { 20355 onChange({ 20356 ...layout, 20357 flexWrap: value ? 'wrap' : 'nowrap' 20358 }); 20359 }, 20360 checked: flexWrap === 'wrap' 20361 }); 20362 } 20363 function OrientationControl({ 20364 layout, 20365 onChange 20366 }) { 20367 const { 20368 orientation = 'horizontal', 20369 verticalAlignment, 20370 justifyContent 20371 } = layout; 20372 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 20373 __next40pxDefaultSize: true, 20374 __nextHasNoMarginBottom: true, 20375 className: "block-editor-hooks__flex-layout-orientation-controls", 20376 label: (0,external_wp_i18n_namespaceObject.__)('Orientation'), 20377 value: orientation, 20378 onChange: value => { 20379 // Make sure the vertical alignment and justification are compatible with the new orientation. 20380 let newVerticalAlignment = verticalAlignment; 20381 let newJustification = justifyContent; 20382 if (value === 'horizontal') { 20383 if (verticalAlignment === 'space-between') { 20384 newVerticalAlignment = 'center'; 20385 } 20386 if (justifyContent === 'stretch') { 20387 newJustification = 'left'; 20388 } 20389 } else { 20390 if (verticalAlignment === 'stretch') { 20391 newVerticalAlignment = 'top'; 20392 } 20393 if (justifyContent === 'space-between') { 20394 newJustification = 'left'; 20395 } 20396 } 20397 return onChange({ 20398 ...layout, 20399 orientation: value, 20400 verticalAlignment: newVerticalAlignment, 20401 justifyContent: newJustification 20402 }); 20403 }, 20404 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 20405 icon: arrow_right, 20406 value: "horizontal", 20407 label: (0,external_wp_i18n_namespaceObject.__)('Horizontal') 20408 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 20409 icon: arrow_down, 20410 value: "vertical", 20411 label: (0,external_wp_i18n_namespaceObject.__)('Vertical') 20412 })] 20413 }); 20414 } 20415 20416 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/flow.js 20417 /** 20418 * WordPress dependencies 20419 */ 20420 20421 20422 /** 20423 * Internal dependencies 20424 */ 20425 20426 20427 20428 20429 /* harmony default export */ const flow = ({ 20430 name: 'default', 20431 label: (0,external_wp_i18n_namespaceObject.__)('Flow'), 20432 inspectorControls: function DefaultLayoutInspectorControls() { 20433 return null; 20434 }, 20435 toolBarControls: function DefaultLayoutToolbarControls() { 20436 return null; 20437 }, 20438 getLayoutStyle: function getLayoutStyle({ 20439 selector, 20440 style, 20441 blockName, 20442 hasBlockGapSupport, 20443 layoutDefinitions = LAYOUT_DEFINITIONS 20444 }) { 20445 const blockGapStyleValue = getGapCSSValue(style?.spacing?.blockGap); 20446 20447 // If a block's block.json skips serialization for spacing or 20448 // spacing.blockGap, don't apply the user-defined value to the styles. 20449 let blockGapValue = ''; 20450 if (!shouldSkipSerialization(blockName, 'spacing', 'blockGap')) { 20451 // If an object is provided only use the 'top' value for this kind of gap. 20452 if (blockGapStyleValue?.top) { 20453 blockGapValue = getGapCSSValue(blockGapStyleValue?.top); 20454 } else if (typeof blockGapStyleValue === 'string') { 20455 blockGapValue = getGapCSSValue(blockGapStyleValue); 20456 } 20457 } 20458 let output = ''; 20459 20460 // Output blockGap styles based on rules contained in layout definitions in theme.json. 20461 if (hasBlockGapSupport && blockGapValue) { 20462 output += getBlockGapCSS(selector, layoutDefinitions, 'default', blockGapValue); 20463 } 20464 return output; 20465 }, 20466 getOrientation() { 20467 return 'vertical'; 20468 }, 20469 getAlignments(layout, isBlockBasedTheme) { 20470 const alignmentInfo = getAlignmentsInfo(layout); 20471 if (layout.alignments !== undefined) { 20472 if (!layout.alignments.includes('none')) { 20473 layout.alignments.unshift('none'); 20474 } 20475 return layout.alignments.map(alignment => ({ 20476 name: alignment, 20477 info: alignmentInfo[alignment] 20478 })); 20479 } 20480 const alignments = [{ 20481 name: 'left' 20482 }, { 20483 name: 'center' 20484 }, { 20485 name: 'right' 20486 }]; 20487 20488 // This is for backwards compatibility with hybrid themes. 20489 if (!isBlockBasedTheme) { 20490 const { 20491 contentSize, 20492 wideSize 20493 } = layout; 20494 if (contentSize) { 20495 alignments.unshift({ 20496 name: 'full' 20497 }); 20498 } 20499 if (wideSize) { 20500 alignments.unshift({ 20501 name: 'wide', 20502 info: alignmentInfo.wide 20503 }); 20504 } 20505 } 20506 alignments.unshift({ 20507 name: 'none', 20508 info: alignmentInfo.none 20509 }); 20510 return alignments; 20511 } 20512 }); 20513 20514 ;// ./node_modules/@wordpress/icons/build-module/icon/index.js 20515 /** 20516 * WordPress dependencies 20517 */ 20518 20519 20520 /** @typedef {{icon: JSX.Element, size?: number} & import('@wordpress/primitives').SVGProps} IconProps */ 20521 20522 /** 20523 * Return an SVG icon. 20524 * 20525 * @param {IconProps} props icon is the SVG component to render 20526 * size is a number specifying the icon size in pixels 20527 * Other props will be passed to wrapped SVG component 20528 * @param {import('react').ForwardedRef<HTMLElement>} ref The forwarded ref to the SVG element. 20529 * 20530 * @return {JSX.Element} Icon component 20531 */ 20532 function Icon({ 20533 icon, 20534 size = 24, 20535 ...props 20536 }, ref) { 20537 return (0,external_wp_element_namespaceObject.cloneElement)(icon, { 20538 width: size, 20539 height: size, 20540 ...props, 20541 ref 20542 }); 20543 } 20544 /* harmony default export */ const build_module_icon = ((0,external_wp_element_namespaceObject.forwardRef)(Icon)); 20545 20546 ;// ./node_modules/@wordpress/icons/build-module/library/align-none.js 20547 /** 20548 * WordPress dependencies 20549 */ 20550 20551 20552 const alignNone = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 20553 xmlns: "http://www.w3.org/2000/svg", 20554 viewBox: "0 0 24 24", 20555 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 20556 d: "M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM5 9h14v6H5V9Z" 20557 }) 20558 }); 20559 /* harmony default export */ const align_none = (alignNone); 20560 20561 ;// ./node_modules/@wordpress/icons/build-module/library/stretch-wide.js 20562 /** 20563 * WordPress dependencies 20564 */ 20565 20566 20567 const stretchWide = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 20568 xmlns: "http://www.w3.org/2000/svg", 20569 viewBox: "0 0 24 24", 20570 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 20571 d: "M16 5.5H8V4h8v1.5ZM16 20H8v-1.5h8V20ZM5 9h14v6H5V9Z" 20572 }) 20573 }); 20574 /* harmony default export */ const stretch_wide = (stretchWide); 20575 20576 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/constrained.js 20577 /** 20578 * WordPress dependencies 20579 */ 20580 20581 20582 20583 20584 20585 /** 20586 * Internal dependencies 20587 */ 20588 20589 20590 20591 20592 20593 20594 20595 /* harmony default export */ const constrained = ({ 20596 name: 'constrained', 20597 label: (0,external_wp_i18n_namespaceObject.__)('Constrained'), 20598 inspectorControls: function DefaultLayoutInspectorControls({ 20599 layout, 20600 onChange, 20601 layoutBlockSupport = {} 20602 }) { 20603 const { 20604 wideSize, 20605 contentSize, 20606 justifyContent = 'center' 20607 } = layout; 20608 const { 20609 allowJustification = true, 20610 allowCustomContentAndWideSize = true 20611 } = layoutBlockSupport; 20612 const onJustificationChange = value => { 20613 onChange({ 20614 ...layout, 20615 justifyContent: value 20616 }); 20617 }; 20618 const justificationOptions = [{ 20619 value: 'left', 20620 icon: justify_left, 20621 label: (0,external_wp_i18n_namespaceObject.__)('Justify items left') 20622 }, { 20623 value: 'center', 20624 icon: justify_center, 20625 label: (0,external_wp_i18n_namespaceObject.__)('Justify items center') 20626 }, { 20627 value: 'right', 20628 icon: justify_right, 20629 label: (0,external_wp_i18n_namespaceObject.__)('Justify items right') 20630 }]; 20631 const [availableUnits] = use_settings_useSettings('spacing.units'); 20632 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 20633 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vw'] 20634 }); 20635 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 20636 spacing: 4, 20637 className: "block-editor-hooks__layout-constrained", 20638 children: [allowCustomContentAndWideSize && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 20639 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 20640 __next40pxDefaultSize: true, 20641 label: (0,external_wp_i18n_namespaceObject.__)('Content width'), 20642 labelPosition: "top", 20643 value: contentSize || wideSize || '', 20644 onChange: nextWidth => { 20645 nextWidth = 0 > parseFloat(nextWidth) ? '0' : nextWidth; 20646 onChange({ 20647 ...layout, 20648 contentSize: nextWidth 20649 }); 20650 }, 20651 units: units, 20652 prefix: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlPrefixWrapper, { 20653 variant: "icon", 20654 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 20655 icon: align_none 20656 }) 20657 }) 20658 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 20659 __next40pxDefaultSize: true, 20660 label: (0,external_wp_i18n_namespaceObject.__)('Wide width'), 20661 labelPosition: "top", 20662 value: wideSize || contentSize || '', 20663 onChange: nextWidth => { 20664 nextWidth = 0 > parseFloat(nextWidth) ? '0' : nextWidth; 20665 onChange({ 20666 ...layout, 20667 wideSize: nextWidth 20668 }); 20669 }, 20670 units: units, 20671 prefix: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlPrefixWrapper, { 20672 variant: "icon", 20673 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 20674 icon: stretch_wide 20675 }) 20676 }) 20677 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 20678 className: "block-editor-hooks__layout-constrained-helptext", 20679 children: (0,external_wp_i18n_namespaceObject.__)('Customize the width for all elements that are assigned to the center or wide columns.') 20680 })] 20681 }), allowJustification && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 20682 __next40pxDefaultSize: true, 20683 __nextHasNoMarginBottom: true, 20684 label: (0,external_wp_i18n_namespaceObject.__)('Justification'), 20685 value: justifyContent, 20686 onChange: onJustificationChange, 20687 children: justificationOptions.map(({ 20688 value, 20689 icon, 20690 label 20691 }) => { 20692 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 20693 value: value, 20694 icon: icon, 20695 label: label 20696 }, value); 20697 }) 20698 })] 20699 }); 20700 }, 20701 toolBarControls: function DefaultLayoutToolbarControls({ 20702 layout = {}, 20703 onChange, 20704 layoutBlockSupport 20705 }) { 20706 const { 20707 allowJustification = true 20708 } = layoutBlockSupport; 20709 if (!allowJustification) { 20710 return null; 20711 } 20712 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 20713 group: "block", 20714 __experimentalShareWithChildBlocks: true, 20715 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DefaultLayoutJustifyContentControl, { 20716 layout: layout, 20717 onChange: onChange 20718 }) 20719 }); 20720 }, 20721 getLayoutStyle: function getLayoutStyle({ 20722 selector, 20723 layout = {}, 20724 style, 20725 blockName, 20726 hasBlockGapSupport, 20727 layoutDefinitions = LAYOUT_DEFINITIONS 20728 }) { 20729 const { 20730 contentSize, 20731 wideSize, 20732 justifyContent 20733 } = layout; 20734 const blockGapStyleValue = getGapCSSValue(style?.spacing?.blockGap); 20735 20736 // If a block's block.json skips serialization for spacing or 20737 // spacing.blockGap, don't apply the user-defined value to the styles. 20738 let blockGapValue = ''; 20739 if (!shouldSkipSerialization(blockName, 'spacing', 'blockGap')) { 20740 // If an object is provided only use the 'top' value for this kind of gap. 20741 if (blockGapStyleValue?.top) { 20742 blockGapValue = getGapCSSValue(blockGapStyleValue?.top); 20743 } else if (typeof blockGapStyleValue === 'string') { 20744 blockGapValue = getGapCSSValue(blockGapStyleValue); 20745 } 20746 } 20747 const marginLeft = justifyContent === 'left' ? '0 !important' : 'auto !important'; 20748 const marginRight = justifyContent === 'right' ? '0 !important' : 'auto !important'; 20749 let output = !!contentSize || !!wideSize ? ` 20750 $appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} { 20751 max-width: $contentSize !== null && contentSize !== void 0 ? contentSize : wideSize}; 20752 margin-left: $marginLeft}; 20753 margin-right: $marginRight}; 20754 } 20755 $appendSelectors(selector, '> .alignwide')} { 20756 max-width: $wideSize !== null && wideSize !== void 0 ? wideSize : contentSize}; 20757 } 20758 $appendSelectors(selector, '> .alignfull')} { 20759 max-width: none; 20760 } 20761 ` : ''; 20762 if (justifyContent === 'left') { 20763 output += `$appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} 20764 { margin-left: $marginLeft}; }`; 20765 } else if (justifyContent === 'right') { 20766 output += `$appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} 20767 { margin-right: $marginRight}; }`; 20768 } 20769 20770 // If there is custom padding, add negative margins for alignfull blocks. 20771 if (style?.spacing?.padding) { 20772 // The style object might be storing a preset so we need to make sure we get a usable value. 20773 const paddingValues = (0,external_wp_styleEngine_namespaceObject.getCSSRules)(style); 20774 paddingValues.forEach(rule => { 20775 if (rule.key === 'paddingRight') { 20776 // Add unit if 0, to avoid calc(0 * -1) which is invalid. 20777 const paddingRightValue = rule.value === '0' ? '0px' : rule.value; 20778 output += ` 20779 $appendSelectors(selector, '> .alignfull')} { 20780 margin-right: calc($paddingRightValue} * -1); 20781 } 20782 `; 20783 } else if (rule.key === 'paddingLeft') { 20784 // Add unit if 0, to avoid calc(0 * -1) which is invalid. 20785 const paddingLeftValue = rule.value === '0' ? '0px' : rule.value; 20786 output += ` 20787 $appendSelectors(selector, '> .alignfull')} { 20788 margin-left: calc($paddingLeftValue} * -1); 20789 } 20790 `; 20791 } 20792 }); 20793 } 20794 20795 // Output blockGap styles based on rules contained in layout definitions in theme.json. 20796 if (hasBlockGapSupport && blockGapValue) { 20797 output += getBlockGapCSS(selector, layoutDefinitions, 'constrained', blockGapValue); 20798 } 20799 return output; 20800 }, 20801 getOrientation() { 20802 return 'vertical'; 20803 }, 20804 getAlignments(layout) { 20805 const alignmentInfo = getAlignmentsInfo(layout); 20806 if (layout.alignments !== undefined) { 20807 if (!layout.alignments.includes('none')) { 20808 layout.alignments.unshift('none'); 20809 } 20810 return layout.alignments.map(alignment => ({ 20811 name: alignment, 20812 info: alignmentInfo[alignment] 20813 })); 20814 } 20815 const { 20816 contentSize, 20817 wideSize 20818 } = layout; 20819 const alignments = [{ 20820 name: 'left' 20821 }, { 20822 name: 'center' 20823 }, { 20824 name: 'right' 20825 }]; 20826 if (contentSize) { 20827 alignments.unshift({ 20828 name: 'full' 20829 }); 20830 } 20831 if (wideSize) { 20832 alignments.unshift({ 20833 name: 'wide', 20834 info: alignmentInfo.wide 20835 }); 20836 } 20837 alignments.unshift({ 20838 name: 'none', 20839 info: alignmentInfo.none 20840 }); 20841 return alignments; 20842 } 20843 }); 20844 const constrained_POPOVER_PROPS = { 20845 placement: 'bottom-start' 20846 }; 20847 function DefaultLayoutJustifyContentControl({ 20848 layout, 20849 onChange 20850 }) { 20851 const { 20852 justifyContent = 'center' 20853 } = layout; 20854 const onJustificationChange = value => { 20855 onChange({ 20856 ...layout, 20857 justifyContent: value 20858 }); 20859 }; 20860 const allowedControls = ['left', 'center', 'right']; 20861 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(JustifyContentControl, { 20862 allowedControls: allowedControls, 20863 value: justifyContent, 20864 onChange: onJustificationChange, 20865 popoverProps: constrained_POPOVER_PROPS 20866 }); 20867 } 20868 20869 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/grid.js 20870 /** 20871 * WordPress dependencies 20872 */ 20873 20874 20875 20876 20877 /** 20878 * Internal dependencies 20879 */ 20880 20881 20882 20883 20884 20885 const RANGE_CONTROL_MAX_VALUES = { 20886 px: 600, 20887 '%': 100, 20888 vw: 100, 20889 vh: 100, 20890 em: 38, 20891 rem: 38, 20892 svw: 100, 20893 lvw: 100, 20894 dvw: 100, 20895 svh: 100, 20896 lvh: 100, 20897 dvh: 100, 20898 vi: 100, 20899 svi: 100, 20900 lvi: 100, 20901 dvi: 100, 20902 vb: 100, 20903 svb: 100, 20904 lvb: 100, 20905 dvb: 100, 20906 vmin: 100, 20907 svmin: 100, 20908 lvmin: 100, 20909 dvmin: 100, 20910 vmax: 100, 20911 svmax: 100, 20912 lvmax: 100, 20913 dvmax: 100 20914 }; 20915 const units = [{ 20916 value: 'px', 20917 label: 'px', 20918 default: 0 20919 }, { 20920 value: 'rem', 20921 label: 'rem', 20922 default: 0 20923 }, { 20924 value: 'em', 20925 label: 'em', 20926 default: 0 20927 }]; 20928 /* harmony default export */ const grid = ({ 20929 name: 'grid', 20930 label: (0,external_wp_i18n_namespaceObject.__)('Grid'), 20931 inspectorControls: function GridLayoutInspectorControls({ 20932 layout = {}, 20933 onChange, 20934 layoutBlockSupport = {} 20935 }) { 20936 const { 20937 allowSizingOnChildren = false 20938 } = layoutBlockSupport; 20939 20940 // In the experiment we want to also show column control in Auto mode, and 20941 // the minimum width control in Manual mode. 20942 const showColumnsControl = window.__experimentalEnableGridInteractivity || !!layout?.columnCount; 20943 const showMinWidthControl = window.__experimentalEnableGridInteractivity || !layout?.columnCount; 20944 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 20945 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridLayoutTypeControl, { 20946 layout: layout, 20947 onChange: onChange 20948 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 20949 spacing: 4, 20950 children: [showColumnsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridLayoutColumnsAndRowsControl, { 20951 layout: layout, 20952 onChange: onChange, 20953 allowSizingOnChildren: allowSizingOnChildren 20954 }), showMinWidthControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridLayoutMinimumWidthControl, { 20955 layout: layout, 20956 onChange: onChange 20957 })] 20958 })] 20959 }); 20960 }, 20961 toolBarControls: function GridLayoutToolbarControls() { 20962 return null; 20963 }, 20964 getLayoutStyle: function getLayoutStyle({ 20965 selector, 20966 layout, 20967 style, 20968 blockName, 20969 hasBlockGapSupport, 20970 layoutDefinitions = LAYOUT_DEFINITIONS 20971 }) { 20972 const { 20973 minimumColumnWidth = null, 20974 columnCount = null, 20975 rowCount = null 20976 } = layout; 20977 20978 // Check that the grid layout attributes are of the correct type, so that we don't accidentally 20979 // write code that stores a string attribute instead of a number. 20980 if (false) {} 20981 20982 // If a block's block.json skips serialization for spacing or spacing.blockGap, 20983 // don't apply the user-defined value to the styles. 20984 const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, 'spacing', 'blockGap') ? getGapCSSValue(style?.spacing?.blockGap, '0.5em') : undefined; 20985 let output = ''; 20986 const rules = []; 20987 if (minimumColumnWidth && columnCount > 0) { 20988 const maxValue = `max($minimumColumnWidth}, ( 100% - ($blockGapValue || '1.2rem'}*$columnCount - 1}) ) / $columnCount})`; 20989 rules.push(`grid-template-columns: repeat(auto-fill, minmax($maxValue}, 1fr))`, `container-type: inline-size`); 20990 if (rowCount) { 20991 rules.push(`grid-template-rows: repeat($rowCount}, minmax(1rem, auto))`); 20992 } 20993 } else if (columnCount) { 20994 rules.push(`grid-template-columns: repeat($columnCount}, minmax(0, 1fr))`); 20995 if (rowCount) { 20996 rules.push(`grid-template-rows: repeat($rowCount}, minmax(1rem, auto))`); 20997 } 20998 } else { 20999 rules.push(`grid-template-columns: repeat(auto-fill, minmax(min($minimumColumnWidth || '12rem'}, 100%), 1fr))`, 'container-type: inline-size'); 21000 } 21001 if (rules.length) { 21002 // Reason to disable: the extra line breaks added by prettier mess with the unit tests. 21003 // eslint-disable-next-line prettier/prettier 21004 output = `$appendSelectors(selector)} { $rules.join('; ')}; }`; 21005 } 21006 21007 // Output blockGap styles based on rules contained in layout definitions in theme.json. 21008 if (hasBlockGapSupport && blockGapValue) { 21009 output += getBlockGapCSS(selector, layoutDefinitions, 'grid', blockGapValue); 21010 } 21011 return output; 21012 }, 21013 getOrientation() { 21014 return 'horizontal'; 21015 }, 21016 getAlignments() { 21017 return []; 21018 } 21019 }); 21020 21021 // Enables setting minimum width of grid items. 21022 function GridLayoutMinimumWidthControl({ 21023 layout, 21024 onChange 21025 }) { 21026 const { 21027 minimumColumnWidth, 21028 columnCount, 21029 isManualPlacement 21030 } = layout; 21031 const defaultValue = isManualPlacement || columnCount ? null : '12rem'; 21032 const value = minimumColumnWidth || defaultValue; 21033 const [quantity, unit = 'rem'] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value); 21034 const handleSliderChange = next => { 21035 onChange({ 21036 ...layout, 21037 minimumColumnWidth: [next, unit].join('') 21038 }); 21039 }; 21040 21041 // Mostly copied from HeightControl. 21042 const handleUnitChange = newUnit => { 21043 // Attempt to smooth over differences between currentUnit and newUnit. 21044 // This should slightly improve the experience of switching between unit types. 21045 let newValue; 21046 if (['em', 'rem'].includes(newUnit) && unit === 'px') { 21047 // Convert pixel value to an approximate of the new unit, assuming a root size of 16px. 21048 newValue = (quantity / 16).toFixed(2) + newUnit; 21049 } else if (['em', 'rem'].includes(unit) && newUnit === 'px') { 21050 // Convert to pixel value assuming a root size of 16px. 21051 newValue = Math.round(quantity * 16) + newUnit; 21052 } 21053 onChange({ 21054 ...layout, 21055 minimumColumnWidth: newValue 21056 }); 21057 }; 21058 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 21059 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 21060 as: "legend", 21061 children: (0,external_wp_i18n_namespaceObject.__)('Minimum column width') 21062 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 21063 gap: 4, 21064 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 21065 isBlock: true, 21066 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 21067 size: "__unstable-large", 21068 onChange: newValue => { 21069 onChange({ 21070 ...layout, 21071 minimumColumnWidth: newValue === '' ? undefined : newValue 21072 }); 21073 }, 21074 onUnitChange: handleUnitChange, 21075 value: value, 21076 units: units, 21077 min: 0, 21078 label: (0,external_wp_i18n_namespaceObject.__)('Minimum column width'), 21079 hideLabelFromVision: true 21080 }) 21081 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 21082 isBlock: true, 21083 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 21084 __next40pxDefaultSize: true, 21085 __nextHasNoMarginBottom: true, 21086 onChange: handleSliderChange, 21087 value: quantity || 0, 21088 min: 0, 21089 max: RANGE_CONTROL_MAX_VALUES[unit] || 600, 21090 withInputField: false, 21091 label: (0,external_wp_i18n_namespaceObject.__)('Minimum column width'), 21092 hideLabelFromVision: true 21093 }) 21094 })] 21095 })] 21096 }); 21097 } 21098 21099 // Enables setting number of grid columns 21100 function GridLayoutColumnsAndRowsControl({ 21101 layout, 21102 onChange, 21103 allowSizingOnChildren 21104 }) { 21105 // If the grid interactivity experiment is enabled, allow unsetting the column count. 21106 const defaultColumnCount = window.__experimentalEnableGridInteractivity ? undefined : 3; 21107 const { 21108 columnCount = defaultColumnCount, 21109 rowCount, 21110 isManualPlacement 21111 } = layout; 21112 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 21113 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 21114 children: [(!window.__experimentalEnableGridInteractivity || !isManualPlacement) && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 21115 as: "legend", 21116 children: (0,external_wp_i18n_namespaceObject.__)('Columns') 21117 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 21118 gap: 4, 21119 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 21120 isBlock: true, 21121 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, { 21122 size: "__unstable-large", 21123 onChange: value => { 21124 if (window.__experimentalEnableGridInteractivity) { 21125 // Allow unsetting the column count when in auto mode. 21126 const defaultNewColumnCount = isManualPlacement ? 1 : undefined; 21127 const newColumnCount = value === '' || value === '0' ? defaultNewColumnCount : parseInt(value, 10); 21128 onChange({ 21129 ...layout, 21130 columnCount: newColumnCount 21131 }); 21132 } else { 21133 // Don't allow unsetting the column count. 21134 const newColumnCount = value === '' || value === '0' ? 1 : parseInt(value, 10); 21135 onChange({ 21136 ...layout, 21137 columnCount: newColumnCount 21138 }); 21139 } 21140 }, 21141 value: columnCount, 21142 min: 1, 21143 label: (0,external_wp_i18n_namespaceObject.__)('Columns'), 21144 hideLabelFromVision: !window.__experimentalEnableGridInteractivity || !isManualPlacement 21145 }) 21146 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 21147 isBlock: true, 21148 children: window.__experimentalEnableGridInteractivity && allowSizingOnChildren && isManualPlacement ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, { 21149 size: "__unstable-large", 21150 onChange: value => { 21151 // Don't allow unsetting the row count. 21152 const newRowCount = value === '' || value === '0' ? 1 : parseInt(value, 10); 21153 onChange({ 21154 ...layout, 21155 rowCount: newRowCount 21156 }); 21157 }, 21158 value: rowCount, 21159 min: 1, 21160 label: (0,external_wp_i18n_namespaceObject.__)('Rows') 21161 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 21162 __next40pxDefaultSize: true, 21163 __nextHasNoMarginBottom: true, 21164 value: columnCount !== null && columnCount !== void 0 ? columnCount : 1, 21165 onChange: value => onChange({ 21166 ...layout, 21167 columnCount: value === '' || value === '0' ? 1 : value 21168 }), 21169 min: 1, 21170 max: 16, 21171 withInputField: false, 21172 label: (0,external_wp_i18n_namespaceObject.__)('Columns'), 21173 hideLabelFromVision: true 21174 }) 21175 })] 21176 })] 21177 }) 21178 }); 21179 } 21180 21181 // Enables switching between grid types 21182 function GridLayoutTypeControl({ 21183 layout, 21184 onChange 21185 }) { 21186 const { 21187 columnCount, 21188 rowCount, 21189 minimumColumnWidth, 21190 isManualPlacement 21191 } = layout; 21192 21193 /** 21194 * When switching, temporarily save any custom values set on the 21195 * previous type so we can switch back without loss. 21196 */ 21197 const [tempColumnCount, setTempColumnCount] = (0,external_wp_element_namespaceObject.useState)(columnCount || 3); 21198 const [tempRowCount, setTempRowCount] = (0,external_wp_element_namespaceObject.useState)(rowCount); 21199 const [tempMinimumColumnWidth, setTempMinimumColumnWidth] = (0,external_wp_element_namespaceObject.useState)(minimumColumnWidth || '12rem'); 21200 const gridPlacement = isManualPlacement || !!columnCount && !window.__experimentalEnableGridInteractivity ? 'manual' : 'auto'; 21201 const onChangeType = value => { 21202 if (value === 'manual') { 21203 setTempMinimumColumnWidth(minimumColumnWidth || '12rem'); 21204 } else { 21205 setTempColumnCount(columnCount || 3); 21206 setTempRowCount(rowCount); 21207 } 21208 onChange({ 21209 ...layout, 21210 columnCount: value === 'manual' ? tempColumnCount : null, 21211 rowCount: value === 'manual' && window.__experimentalEnableGridInteractivity ? tempRowCount : undefined, 21212 isManualPlacement: value === 'manual' && window.__experimentalEnableGridInteractivity ? true : undefined, 21213 minimumColumnWidth: value === 'auto' ? tempMinimumColumnWidth : null 21214 }); 21215 }; 21216 const helpText = gridPlacement === 'manual' ? (0,external_wp_i18n_namespaceObject.__)('Grid items can be manually placed in any position on the grid.') : (0,external_wp_i18n_namespaceObject.__)('Grid items are placed automatically depending on their order.'); 21217 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 21218 __next40pxDefaultSize: true, 21219 __nextHasNoMarginBottom: true, 21220 label: (0,external_wp_i18n_namespaceObject.__)('Grid item position'), 21221 value: gridPlacement, 21222 onChange: onChangeType, 21223 isBlock: true, 21224 help: window.__experimentalEnableGridInteractivity ? helpText : undefined, 21225 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 21226 value: "auto", 21227 label: (0,external_wp_i18n_namespaceObject.__)('Auto') 21228 }, "auto"), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 21229 value: "manual", 21230 label: (0,external_wp_i18n_namespaceObject.__)('Manual') 21231 }, "manual")] 21232 }); 21233 } 21234 21235 ;// ./node_modules/@wordpress/block-editor/build-module/layouts/index.js 21236 /** 21237 * Internal dependencies 21238 */ 21239 21240 21241 21242 21243 const layoutTypes = [flow, flex, constrained, grid]; 21244 21245 /** 21246 * Retrieves a layout type by name. 21247 * 21248 * @param {string} name - The name of the layout type. 21249 * @return {Object} Layout type. 21250 */ 21251 function getLayoutType(name = 'default') { 21252 return layoutTypes.find(layoutType => layoutType.name === name); 21253 } 21254 21255 /** 21256 * Retrieves the available layout types. 21257 * 21258 * @return {Array} Layout types. 21259 */ 21260 function getLayoutTypes() { 21261 return layoutTypes; 21262 } 21263 21264 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/layout.js 21265 /** 21266 * WordPress dependencies 21267 */ 21268 21269 21270 /** 21271 * Internal dependencies 21272 */ 21273 21274 21275 21276 const defaultLayout = { 21277 type: 'default' 21278 }; 21279 const Layout = (0,external_wp_element_namespaceObject.createContext)(defaultLayout); 21280 21281 /** 21282 * Allows to define the layout. 21283 */ 21284 const LayoutProvider = Layout.Provider; 21285 21286 /** 21287 * React hook used to retrieve the layout config. 21288 */ 21289 function useLayout() { 21290 return (0,external_wp_element_namespaceObject.useContext)(Layout); 21291 } 21292 function LayoutStyle({ 21293 layout = {}, 21294 css, 21295 ...props 21296 }) { 21297 const layoutType = getLayoutType(layout.type); 21298 const [blockGapSupport] = use_settings_useSettings('spacing.blockGap'); 21299 const hasBlockGapSupport = blockGapSupport !== null; 21300 if (layoutType) { 21301 if (css) { 21302 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("style", { 21303 children: css 21304 }); 21305 } 21306 const layoutStyle = layoutType.getLayoutStyle?.({ 21307 hasBlockGapSupport, 21308 layout, 21309 ...props 21310 }); 21311 if (layoutStyle) { 21312 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("style", { 21313 children: layoutStyle 21314 }); 21315 } 21316 } 21317 return null; 21318 } 21319 21320 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/use-available-alignments.js 21321 /** 21322 * WordPress dependencies 21323 */ 21324 21325 21326 /** 21327 * Internal dependencies 21328 */ 21329 21330 21331 21332 const use_available_alignments_EMPTY_ARRAY = []; 21333 const use_available_alignments_DEFAULT_CONTROLS = ['none', 'left', 'center', 'right', 'wide', 'full']; 21334 const WIDE_CONTROLS = ['wide', 'full']; 21335 function useAvailableAlignments(controls = use_available_alignments_DEFAULT_CONTROLS) { 21336 // Always add the `none` option if not exists. 21337 if (!controls.includes('none')) { 21338 controls = ['none', ...controls]; 21339 } 21340 const isNoneOnly = controls.length === 1 && controls[0] === 'none'; 21341 const [wideControlsEnabled, themeSupportsLayout, isBlockBasedTheme] = (0,external_wp_data_namespaceObject.useSelect)(select => { 21342 var _settings$alignWide; 21343 // If `isNoneOnly` is true, we'll be returning early because there is 21344 // nothing to filter on an empty array. We won't need the info from 21345 // the `useSelect` but we must call it anyway because Rules of Hooks. 21346 // So the callback returns early to avoid block editor subscription. 21347 if (isNoneOnly) { 21348 return [false, false, false]; 21349 } 21350 const settings = select(store).getSettings(); 21351 return [(_settings$alignWide = settings.alignWide) !== null && _settings$alignWide !== void 0 ? _settings$alignWide : false, settings.supportsLayout, settings.__unstableIsBlockBasedTheme]; 21352 }, [isNoneOnly]); 21353 const layout = useLayout(); 21354 if (isNoneOnly) { 21355 return use_available_alignments_EMPTY_ARRAY; 21356 } 21357 const layoutType = getLayoutType(layout?.type); 21358 if (themeSupportsLayout) { 21359 const layoutAlignments = layoutType.getAlignments(layout, isBlockBasedTheme); 21360 const alignments = layoutAlignments.filter(alignment => controls.includes(alignment.name)); 21361 // While we treat `none` as an alignment, we shouldn't return it if no 21362 // other alignments exist. 21363 if (alignments.length === 1 && alignments[0].name === 'none') { 21364 return use_available_alignments_EMPTY_ARRAY; 21365 } 21366 return alignments; 21367 } 21368 21369 // Starting here, it's the fallback for themes not supporting the layout config. 21370 if (layoutType.name !== 'default' && layoutType.name !== 'constrained') { 21371 return use_available_alignments_EMPTY_ARRAY; 21372 } 21373 const alignments = controls.filter(control => { 21374 if (layout.alignments) { 21375 return layout.alignments.includes(control); 21376 } 21377 if (!wideControlsEnabled && WIDE_CONTROLS.includes(control)) { 21378 return false; 21379 } 21380 return use_available_alignments_DEFAULT_CONTROLS.includes(control); 21381 }).map(name => ({ 21382 name 21383 })); 21384 21385 // While we treat `none` as an alignment, we shouldn't return it if no 21386 // other alignments exist. 21387 if (alignments.length === 1 && alignments[0].name === 'none') { 21388 return use_available_alignments_EMPTY_ARRAY; 21389 } 21390 return alignments; 21391 } 21392 21393 ;// ./node_modules/@wordpress/icons/build-module/library/position-left.js 21394 /** 21395 * WordPress dependencies 21396 */ 21397 21398 21399 const positionLeft = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 21400 xmlns: "http://www.w3.org/2000/svg", 21401 viewBox: "0 0 24 24", 21402 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 21403 d: "M5 5.5h8V4H5v1.5ZM5 20h8v-1.5H5V20ZM19 9H5v6h14V9Z" 21404 }) 21405 }); 21406 /* harmony default export */ const position_left = (positionLeft); 21407 21408 ;// ./node_modules/@wordpress/icons/build-module/library/position-center.js 21409 /** 21410 * WordPress dependencies 21411 */ 21412 21413 21414 const positionCenter = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 21415 xmlns: "http://www.w3.org/2000/svg", 21416 viewBox: "0 0 24 24", 21417 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 21418 d: "M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM7 9h10v6H7V9Z" 21419 }) 21420 }); 21421 /* harmony default export */ const position_center = (positionCenter); 21422 21423 ;// ./node_modules/@wordpress/icons/build-module/library/position-right.js 21424 /** 21425 * WordPress dependencies 21426 */ 21427 21428 21429 const positionRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 21430 xmlns: "http://www.w3.org/2000/svg", 21431 viewBox: "0 0 24 24", 21432 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 21433 d: "M19 5.5h-8V4h8v1.5ZM19 20h-8v-1.5h8V20ZM5 9h14v6H5V9Z" 21434 }) 21435 }); 21436 /* harmony default export */ const position_right = (positionRight); 21437 21438 ;// ./node_modules/@wordpress/icons/build-module/library/stretch-full-width.js 21439 /** 21440 * WordPress dependencies 21441 */ 21442 21443 21444 const stretchFullWidth = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 21445 xmlns: "http://www.w3.org/2000/svg", 21446 viewBox: "0 0 24 24", 21447 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 21448 d: "M5 4h14v11H5V4Zm11 16H8v-1.5h8V20Z" 21449 }) 21450 }); 21451 /* harmony default export */ const stretch_full_width = (stretchFullWidth); 21452 21453 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/constants.js 21454 /** 21455 * WordPress dependencies 21456 */ 21457 21458 21459 const constants_BLOCK_ALIGNMENTS_CONTROLS = { 21460 none: { 21461 icon: align_none, 21462 title: (0,external_wp_i18n_namespaceObject._x)('None', 'Alignment option') 21463 }, 21464 left: { 21465 icon: position_left, 21466 title: (0,external_wp_i18n_namespaceObject.__)('Align left') 21467 }, 21468 center: { 21469 icon: position_center, 21470 title: (0,external_wp_i18n_namespaceObject.__)('Align center') 21471 }, 21472 right: { 21473 icon: position_right, 21474 title: (0,external_wp_i18n_namespaceObject.__)('Align right') 21475 }, 21476 wide: { 21477 icon: stretch_wide, 21478 title: (0,external_wp_i18n_namespaceObject.__)('Wide width') 21479 }, 21480 full: { 21481 icon: stretch_full_width, 21482 title: (0,external_wp_i18n_namespaceObject.__)('Full width') 21483 } 21484 }; 21485 const constants_DEFAULT_CONTROL = 'none'; 21486 21487 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/ui.js 21488 /** 21489 * External dependencies 21490 */ 21491 21492 21493 /** 21494 * WordPress dependencies 21495 */ 21496 21497 21498 21499 /** 21500 * Internal dependencies 21501 */ 21502 21503 21504 21505 function BlockAlignmentUI({ 21506 value, 21507 onChange, 21508 controls, 21509 isToolbar, 21510 isCollapsed = true 21511 }) { 21512 const enabledControls = useAvailableAlignments(controls); 21513 const hasEnabledControls = !!enabledControls.length; 21514 if (!hasEnabledControls) { 21515 return null; 21516 } 21517 function onChangeAlignment(align) { 21518 onChange([value, 'none'].includes(align) ? undefined : align); 21519 } 21520 const activeAlignmentControl = constants_BLOCK_ALIGNMENTS_CONTROLS[value]; 21521 const defaultAlignmentControl = constants_BLOCK_ALIGNMENTS_CONTROLS[constants_DEFAULT_CONTROL]; 21522 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 21523 const commonProps = { 21524 icon: activeAlignmentControl ? activeAlignmentControl.icon : defaultAlignmentControl.icon, 21525 label: (0,external_wp_i18n_namespaceObject.__)('Align') 21526 }; 21527 const extraProps = isToolbar ? { 21528 isCollapsed, 21529 controls: enabledControls.map(({ 21530 name: controlName 21531 }) => { 21532 return { 21533 ...constants_BLOCK_ALIGNMENTS_CONTROLS[controlName], 21534 isActive: value === controlName || !value && controlName === 'none', 21535 role: isCollapsed ? 'menuitemradio' : undefined, 21536 onClick: () => onChangeAlignment(controlName) 21537 }; 21538 }) 21539 } : { 21540 toggleProps: { 21541 description: (0,external_wp_i18n_namespaceObject.__)('Change alignment') 21542 }, 21543 children: ({ 21544 onClose 21545 }) => { 21546 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 21547 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 21548 className: "block-editor-block-alignment-control__menu-group", 21549 children: enabledControls.map(({ 21550 name: controlName, 21551 info 21552 }) => { 21553 const { 21554 icon, 21555 title 21556 } = constants_BLOCK_ALIGNMENTS_CONTROLS[controlName]; 21557 // If no value is provided, mark as selected the `none` option. 21558 const isSelected = controlName === value || !value && controlName === 'none'; 21559 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 21560 icon: icon, 21561 iconPosition: "left", 21562 className: dist_clsx('components-dropdown-menu__menu-item', { 21563 'is-active': isSelected 21564 }), 21565 isSelected: isSelected, 21566 onClick: () => { 21567 onChangeAlignment(controlName); 21568 onClose(); 21569 }, 21570 role: "menuitemradio", 21571 info: info, 21572 children: title 21573 }, controlName); 21574 }) 21575 }) 21576 }); 21577 } 21578 }; 21579 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(UIComponent, { 21580 ...commonProps, 21581 ...extraProps 21582 }); 21583 } 21584 /* harmony default export */ const block_alignment_control_ui = (BlockAlignmentUI); 21585 21586 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/index.js 21587 /** 21588 * Internal dependencies 21589 */ 21590 21591 21592 const BlockAlignmentControl = props => { 21593 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_alignment_control_ui, { 21594 ...props, 21595 isToolbar: false 21596 }); 21597 }; 21598 const BlockAlignmentToolbar = props => { 21599 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_alignment_control_ui, { 21600 ...props, 21601 isToolbar: true 21602 }); 21603 }; 21604 21605 /** 21606 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-alignment-control/README.md 21607 */ 21608 21609 21610 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-editing-mode/index.js 21611 /** 21612 * WordPress dependencies 21613 */ 21614 21615 21616 21617 /** 21618 * Internal dependencies 21619 */ 21620 21621 21622 21623 /** 21624 * @typedef {'disabled'|'contentOnly'|'default'} BlockEditingMode 21625 */ 21626 21627 /** 21628 * Allows a block to restrict the user interface that is displayed for editing 21629 * that block and its inner blocks. 21630 * 21631 * @example 21632 * ```js 21633 * function MyBlock( { attributes, setAttributes } ) { 21634 * useBlockEditingMode( 'disabled' ); 21635 * return <div { ...useBlockProps() }></div>; 21636 * } 21637 * ``` 21638 * 21639 * `mode` can be one of three options: 21640 * 21641 * - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be 21642 * selected. 21643 * - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the 21644 * toolbar, the block movers, block settings. 21645 * - `'default'`: Allows editing the block as normal. 21646 * 21647 * The mode is inherited by all of the block's inner blocks, unless they have 21648 * their own mode. 21649 * 21650 * If called outside of a block context, the mode is applied to all blocks. 21651 * 21652 * @param {?BlockEditingMode} mode The editing mode to apply. If undefined, the 21653 * current editing mode is not changed. 21654 * 21655 * @return {BlockEditingMode} The current editing mode. 21656 */ 21657 function useBlockEditingMode(mode) { 21658 const context = useBlockEditContext(); 21659 const { 21660 clientId = '' 21661 } = context; 21662 const { 21663 setBlockEditingMode, 21664 unsetBlockEditingMode 21665 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 21666 const globalBlockEditingMode = (0,external_wp_data_namespaceObject.useSelect)(select => 21667 // Avoid adding the subscription if not needed! 21668 clientId ? null : select(store).getBlockEditingMode(), [clientId]); 21669 (0,external_wp_element_namespaceObject.useEffect)(() => { 21670 if (mode) { 21671 setBlockEditingMode(clientId, mode); 21672 } 21673 return () => { 21674 if (mode) { 21675 unsetBlockEditingMode(clientId); 21676 } 21677 }; 21678 }, [clientId, mode, setBlockEditingMode, unsetBlockEditingMode]); 21679 return clientId ? context[blockEditingModeKey] : globalBlockEditingMode; 21680 } 21681 21682 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/align.js 21683 /** 21684 * External dependencies 21685 */ 21686 21687 21688 /** 21689 * WordPress dependencies 21690 */ 21691 21692 21693 21694 /** 21695 * Internal dependencies 21696 */ 21697 21698 21699 21700 21701 /** 21702 * An array which includes all possible valid alignments, 21703 * used to validate if an alignment is valid or not. 21704 * 21705 * @constant 21706 * @type {string[]} 21707 */ 21708 21709 const ALL_ALIGNMENTS = ['left', 'center', 'right', 'wide', 'full']; 21710 21711 /** 21712 * An array which includes all wide alignments. 21713 * In order for this alignments to be valid they need to be supported by the block, 21714 * and by the theme. 21715 * 21716 * @constant 21717 * @type {string[]} 21718 */ 21719 const WIDE_ALIGNMENTS = ['wide', 'full']; 21720 21721 /** 21722 * Returns the valid alignments. 21723 * 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. 21724 * Exported just for testing purposes, not exported outside the module. 21725 * 21726 * @param {?boolean|string[]} blockAlign Aligns supported by the block. 21727 * @param {?boolean} hasWideBlockSupport True if block supports wide alignments. And False otherwise. 21728 * @param {?boolean} hasWideEnabled True if theme supports wide alignments. And False otherwise. 21729 * 21730 * @return {string[]} Valid alignments. 21731 */ 21732 function getValidAlignments(blockAlign, hasWideBlockSupport = true, hasWideEnabled = true) { 21733 let validAlignments; 21734 if (Array.isArray(blockAlign)) { 21735 validAlignments = ALL_ALIGNMENTS.filter(value => blockAlign.includes(value)); 21736 } else if (blockAlign === true) { 21737 // `true` includes all alignments... 21738 validAlignments = [...ALL_ALIGNMENTS]; 21739 } else { 21740 validAlignments = []; 21741 } 21742 if (!hasWideEnabled || blockAlign === true && !hasWideBlockSupport) { 21743 return validAlignments.filter(alignment => !WIDE_ALIGNMENTS.includes(alignment)); 21744 } 21745 return validAlignments; 21746 } 21747 21748 /** 21749 * Filters registered block settings, extending attributes to include `align`. 21750 * 21751 * @param {Object} settings Original block settings. 21752 * 21753 * @return {Object} Filtered block settings. 21754 */ 21755 function addAttribute(settings) { 21756 var _settings$attributes$; 21757 // Allow blocks to specify their own attribute definition with default values if needed. 21758 if ('type' in ((_settings$attributes$ = settings.attributes?.align) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 21759 return settings; 21760 } 21761 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'align')) { 21762 // Gracefully handle if settings.attributes is undefined. 21763 settings.attributes = { 21764 ...settings.attributes, 21765 align: { 21766 type: 'string', 21767 // Allow for '' since it is used by the `updateAlignment` function 21768 // in toolbar controls for special cases with defined default values. 21769 enum: [...ALL_ALIGNMENTS, ''] 21770 } 21771 }; 21772 } 21773 return settings; 21774 } 21775 function BlockEditAlignmentToolbarControlsPure({ 21776 name: blockName, 21777 align, 21778 setAttributes 21779 }) { 21780 // Compute the block valid alignments by taking into account, 21781 // if the theme supports wide alignments or not and the layout's 21782 // available alignments. We do that for conditionally rendering 21783 // Slot. 21784 const blockAllowedAlignments = getValidAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, 'align'), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'alignWide', true)); 21785 const validAlignments = useAvailableAlignments(blockAllowedAlignments).map(({ 21786 name 21787 }) => name); 21788 const blockEditingMode = useBlockEditingMode(); 21789 if (!validAlignments.length || blockEditingMode !== 'default') { 21790 return null; 21791 } 21792 const updateAlignment = nextAlign => { 21793 if (!nextAlign) { 21794 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 21795 const blockDefaultAlign = blockType?.attributes?.align?.default; 21796 if (blockDefaultAlign) { 21797 nextAlign = ''; 21798 } 21799 } 21800 setAttributes({ 21801 align: nextAlign 21802 }); 21803 }; 21804 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 21805 group: "block", 21806 __experimentalShareWithChildBlocks: true, 21807 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockAlignmentControl, { 21808 value: align, 21809 onChange: updateAlignment, 21810 controls: validAlignments 21811 }) 21812 }); 21813 } 21814 /* harmony default export */ const align = ({ 21815 shareWithChildBlocks: true, 21816 edit: BlockEditAlignmentToolbarControlsPure, 21817 useBlockProps, 21818 addSaveProps: addAssignedAlign, 21819 attributeKeys: ['align'], 21820 hasSupport(name) { 21821 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'align', false); 21822 } 21823 }); 21824 function useBlockProps({ 21825 name, 21826 align 21827 }) { 21828 const blockAllowedAlignments = getValidAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'align'), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'alignWide', true)); 21829 const validAlignments = useAvailableAlignments(blockAllowedAlignments); 21830 if (validAlignments.some(alignment => alignment.name === align)) { 21831 return { 21832 'data-align': align 21833 }; 21834 } 21835 return {}; 21836 } 21837 21838 /** 21839 * Override props assigned to save component to inject alignment class name if 21840 * block supports it. 21841 * 21842 * @param {Object} props Additional props applied to save element. 21843 * @param {Object} blockType Block type. 21844 * @param {Object} attributes Block attributes. 21845 * 21846 * @return {Object} Filtered props applied to save element. 21847 */ 21848 function addAssignedAlign(props, blockType, attributes) { 21849 const { 21850 align 21851 } = attributes; 21852 const blockAlign = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'align'); 21853 const hasWideBlockSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'alignWide', true); 21854 21855 // Compute valid alignments without taking into account if 21856 // the theme supports wide alignments or not. 21857 // This way changing themes does not impact the block save. 21858 const isAlignValid = getValidAlignments(blockAlign, hasWideBlockSupport).includes(align); 21859 if (isAlignValid) { 21860 props.className = dist_clsx(`align$align}`, props.className); 21861 } 21862 return props; 21863 } 21864 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/align/addAttribute', addAttribute); 21865 21866 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/groups.js 21867 /** 21868 * WordPress dependencies 21869 */ 21870 21871 const InspectorControlsDefault = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControls'); 21872 const InspectorControlsAdvanced = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorAdvancedControls'); 21873 const InspectorControlsBindings = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBindings'); 21874 const InspectorControlsBackground = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBackground'); 21875 const InspectorControlsBorder = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBorder'); 21876 const InspectorControlsColor = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsColor'); 21877 const InspectorControlsFilter = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsFilter'); 21878 const InspectorControlsDimensions = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsDimensions'); 21879 const InspectorControlsPosition = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsPosition'); 21880 const InspectorControlsTypography = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsTypography'); 21881 const InspectorControlsListView = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsListView'); 21882 const InspectorControlsStyles = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsStyles'); 21883 const InspectorControlsEffects = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsEffects'); 21884 const groups_groups = { 21885 default: InspectorControlsDefault, 21886 advanced: InspectorControlsAdvanced, 21887 background: InspectorControlsBackground, 21888 bindings: InspectorControlsBindings, 21889 border: InspectorControlsBorder, 21890 color: InspectorControlsColor, 21891 dimensions: InspectorControlsDimensions, 21892 effects: InspectorControlsEffects, 21893 filter: InspectorControlsFilter, 21894 list: InspectorControlsListView, 21895 position: InspectorControlsPosition, 21896 settings: InspectorControlsDefault, 21897 // Alias for default. 21898 styles: InspectorControlsStyles, 21899 typography: InspectorControlsTypography 21900 }; 21901 /* harmony default export */ const inspector_controls_groups = (groups_groups); 21902 21903 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/fill.js 21904 /** 21905 * WordPress dependencies 21906 */ 21907 21908 21909 21910 21911 21912 /** 21913 * Internal dependencies 21914 */ 21915 21916 21917 21918 function InspectorControlsFill({ 21919 children, 21920 group = 'default', 21921 __experimentalGroup, 21922 resetAllFilter 21923 }) { 21924 if (__experimentalGroup) { 21925 external_wp_deprecated_default()('`__experimentalGroup` property in `InspectorControlsFill`', { 21926 since: '6.2', 21927 version: '6.4', 21928 alternative: '`group`' 21929 }); 21930 group = __experimentalGroup; 21931 } 21932 const context = useBlockEditContext(); 21933 const Fill = inspector_controls_groups[group]?.Fill; 21934 if (!Fill) { 21935 true ? external_wp_warning_default()(`Unknown InspectorControls group "$group}" provided.`) : 0; 21936 return null; 21937 } 21938 if (!context[mayDisplayControlsKey]) { 21939 return null; 21940 } 21941 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 21942 document: document, 21943 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Fill, { 21944 children: fillProps => { 21945 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ToolsPanelInspectorControl, { 21946 fillProps: fillProps, 21947 children: children, 21948 resetAllFilter: resetAllFilter 21949 }); 21950 } 21951 }) 21952 }); 21953 } 21954 function RegisterResetAll({ 21955 resetAllFilter, 21956 children 21957 }) { 21958 const { 21959 registerResetAllFilter, 21960 deregisterResetAllFilter 21961 } = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolsPanelContext); 21962 (0,external_wp_element_namespaceObject.useEffect)(() => { 21963 if (resetAllFilter && registerResetAllFilter && deregisterResetAllFilter) { 21964 registerResetAllFilter(resetAllFilter); 21965 return () => { 21966 deregisterResetAllFilter(resetAllFilter); 21967 }; 21968 } 21969 }, [resetAllFilter, registerResetAllFilter, deregisterResetAllFilter]); 21970 return children; 21971 } 21972 function ToolsPanelInspectorControl({ 21973 children, 21974 resetAllFilter, 21975 fillProps 21976 }) { 21977 // `fillProps.forwardedContext` is an array of context provider entries, provided by slot, 21978 // that should wrap the fill markup. 21979 const { 21980 forwardedContext = [] 21981 } = fillProps; 21982 21983 // Children passed to InspectorControlsFill will not have 21984 // access to any React Context whose Provider is part of 21985 // the InspectorControlsSlot tree. So we re-create the 21986 // Provider in this subtree. 21987 const innerMarkup = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RegisterResetAll, { 21988 resetAllFilter: resetAllFilter, 21989 children: children 21990 }); 21991 return forwardedContext.reduce((inner, [Provider, props]) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Provider, { 21992 ...props, 21993 children: inner 21994 }), innerMarkup); 21995 } 21996 21997 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/block-support-tools-panel.js 21998 /** 21999 * WordPress dependencies 22000 */ 22001 22002 22003 22004 22005 /** 22006 * Internal dependencies 22007 */ 22008 22009 22010 22011 22012 function BlockSupportToolsPanel({ 22013 children, 22014 group, 22015 label 22016 }) { 22017 const { 22018 updateBlockAttributes 22019 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 22020 const { 22021 getBlockAttributes, 22022 getMultiSelectedBlockClientIds, 22023 getSelectedBlockClientId, 22024 hasMultiSelection 22025 } = (0,external_wp_data_namespaceObject.useSelect)(store); 22026 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 22027 const panelId = getSelectedBlockClientId(); 22028 const resetAll = (0,external_wp_element_namespaceObject.useCallback)((resetFilters = []) => { 22029 const newAttributes = {}; 22030 const clientIds = hasMultiSelection() ? getMultiSelectedBlockClientIds() : [panelId]; 22031 clientIds.forEach(clientId => { 22032 const { 22033 style 22034 } = getBlockAttributes(clientId); 22035 let newBlockAttributes = { 22036 style 22037 }; 22038 resetFilters.forEach(resetFilter => { 22039 newBlockAttributes = { 22040 ...newBlockAttributes, 22041 ...resetFilter(newBlockAttributes) 22042 }; 22043 }); 22044 22045 // Enforce a cleaned style object. 22046 newBlockAttributes = { 22047 ...newBlockAttributes, 22048 style: utils_cleanEmptyObject(newBlockAttributes.style) 22049 }; 22050 newAttributes[clientId] = newBlockAttributes; 22051 }); 22052 updateBlockAttributes(clientIds, newAttributes, true); 22053 }, [getBlockAttributes, getMultiSelectedBlockClientIds, hasMultiSelection, panelId, updateBlockAttributes]); 22054 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 22055 className: `$group}-block-support-panel`, 22056 label: label, 22057 resetAll: resetAll, 22058 panelId: panelId, 22059 hasInnerWrapper: true, 22060 shouldRenderPlaceholderItems: true // Required to maintain fills ordering. 22061 , 22062 __experimentalFirstVisibleItemClass: "first", 22063 __experimentalLastVisibleItemClass: "last", 22064 dropdownMenuProps: dropdownMenuProps, 22065 children: children 22066 }, panelId); 22067 } 22068 22069 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/block-support-slot-container.js 22070 /** 22071 * WordPress dependencies 22072 */ 22073 22074 22075 22076 function BlockSupportSlotContainer({ 22077 Slot, 22078 fillProps, 22079 ...props 22080 }) { 22081 // Add the toolspanel context provider and value to existing fill props 22082 const toolsPanelContext = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolsPanelContext); 22083 const computedFillProps = (0,external_wp_element_namespaceObject.useMemo)(() => { 22084 var _fillProps$forwardedC; 22085 return { 22086 ...(fillProps !== null && fillProps !== void 0 ? fillProps : {}), 22087 forwardedContext: [...((_fillProps$forwardedC = fillProps?.forwardedContext) !== null && _fillProps$forwardedC !== void 0 ? _fillProps$forwardedC : []), [external_wp_components_namespaceObject.__experimentalToolsPanelContext.Provider, { 22088 value: toolsPanelContext 22089 }]] 22090 }; 22091 }, [toolsPanelContext, fillProps]); 22092 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Slot, { 22093 ...props, 22094 fillProps: computedFillProps, 22095 bubblesVirtually: true 22096 }); 22097 } 22098 22099 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/slot.js 22100 /** 22101 * WordPress dependencies 22102 */ 22103 22104 22105 22106 22107 /** 22108 * Internal dependencies 22109 */ 22110 22111 22112 22113 22114 function InspectorControlsSlot({ 22115 __experimentalGroup, 22116 group = 'default', 22117 label, 22118 fillProps, 22119 ...props 22120 }) { 22121 if (__experimentalGroup) { 22122 external_wp_deprecated_default()('`__experimentalGroup` property in `InspectorControlsSlot`', { 22123 since: '6.2', 22124 version: '6.4', 22125 alternative: '`group`' 22126 }); 22127 group = __experimentalGroup; 22128 } 22129 const slotFill = inspector_controls_groups[group]; 22130 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(slotFill?.name); 22131 if (!slotFill) { 22132 true ? external_wp_warning_default()(`Unknown InspectorControls group "$group}" provided.`) : 0; 22133 return null; 22134 } 22135 if (!fills?.length) { 22136 return null; 22137 } 22138 const { 22139 Slot 22140 } = slotFill; 22141 if (label) { 22142 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockSupportToolsPanel, { 22143 group: group, 22144 label: label, 22145 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockSupportSlotContainer, { 22146 ...props, 22147 fillProps: fillProps, 22148 Slot: Slot 22149 }) 22150 }); 22151 } 22152 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Slot, { 22153 ...props, 22154 fillProps: fillProps, 22155 bubblesVirtually: true 22156 }); 22157 } 22158 22159 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/index.js 22160 /** 22161 * Internal dependencies 22162 */ 22163 22164 22165 22166 const InspectorControls = InspectorControlsFill; 22167 InspectorControls.Slot = InspectorControlsSlot; 22168 22169 // This is just here for backward compatibility. 22170 const InspectorAdvancedControls = props => { 22171 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorControlsFill, { 22172 ...props, 22173 group: "advanced" 22174 }); 22175 }; 22176 InspectorAdvancedControls.Slot = props => { 22177 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorControlsSlot, { 22178 ...props, 22179 group: "advanced" 22180 }); 22181 }; 22182 InspectorAdvancedControls.slotName = 'InspectorAdvancedControls'; 22183 22184 /** 22185 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inspector-controls/README.md 22186 */ 22187 /* harmony default export */ const inspector_controls = (InspectorControls); 22188 22189 ;// external ["wp","url"] 22190 const external_wp_url_namespaceObject = window["wp"]["url"]; 22191 ;// external ["wp","dom"] 22192 const external_wp_dom_namespaceObject = window["wp"]["dom"]; 22193 ;// external ["wp","blob"] 22194 const external_wp_blob_namespaceObject = window["wp"]["blob"]; 22195 ;// external ["wp","keycodes"] 22196 const external_wp_keycodes_namespaceObject = window["wp"]["keycodes"]; 22197 ;// ./node_modules/@wordpress/icons/build-module/library/media.js 22198 /** 22199 * WordPress dependencies 22200 */ 22201 22202 22203 const media = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 22204 xmlns: "http://www.w3.org/2000/svg", 22205 viewBox: "0 0 24 24", 22206 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22207 d: "m7 6.5 4 2.5-4 2.5z" 22208 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22209 fillRule: "evenodd", 22210 clipRule: "evenodd", 22211 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" 22212 })] 22213 }); 22214 /* harmony default export */ const library_media = (media); 22215 22216 ;// ./node_modules/@wordpress/icons/build-module/library/upload.js 22217 /** 22218 * WordPress dependencies 22219 */ 22220 22221 22222 const upload = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22223 xmlns: "http://www.w3.org/2000/svg", 22224 viewBox: "0 0 24 24", 22225 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22226 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" 22227 }) 22228 }); 22229 /* harmony default export */ const library_upload = (upload); 22230 22231 ;// ./node_modules/@wordpress/icons/build-module/library/post-featured-image.js 22232 /** 22233 * WordPress dependencies 22234 */ 22235 22236 22237 const postFeaturedImage = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22238 xmlns: "http://www.w3.org/2000/svg", 22239 viewBox: "0 0 24 24", 22240 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22241 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" 22242 }) 22243 }); 22244 /* harmony default export */ const post_featured_image = (postFeaturedImage); 22245 22246 ;// ./node_modules/@wordpress/block-editor/build-module/components/media-upload/index.js 22247 /** 22248 * WordPress dependencies 22249 */ 22250 22251 22252 /** 22253 * This is a placeholder for the media upload component necessary to make it possible to provide 22254 * an integration with the core blocks that handle media files. By default it renders nothing but 22255 * it provides a way to have it overridden with the `editor.MediaUpload` filter. 22256 * 22257 * @return {Component} The component to be rendered. 22258 */ 22259 const MediaUpload = () => null; 22260 22261 /** 22262 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-upload/README.md 22263 */ 22264 /* harmony default export */ const media_upload = ((0,external_wp_components_namespaceObject.withFilters)('editor.MediaUpload')(MediaUpload)); 22265 22266 ;// ./node_modules/@wordpress/block-editor/build-module/components/media-upload/check.js 22267 /** 22268 * WordPress dependencies 22269 */ 22270 22271 22272 /** 22273 * Internal dependencies 22274 */ 22275 22276 function MediaUploadCheck({ 22277 fallback = null, 22278 children 22279 }) { 22280 const hasUploadPermissions = (0,external_wp_data_namespaceObject.useSelect)(select => { 22281 const { 22282 getSettings 22283 } = select(store); 22284 return !!getSettings().mediaUpload; 22285 }, []); 22286 return hasUploadPermissions ? children : fallback; 22287 } 22288 22289 /** 22290 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-upload/README.md 22291 */ 22292 /* harmony default export */ const check = (MediaUploadCheck); 22293 22294 ;// external ["wp","isShallowEqual"] 22295 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 22296 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 22297 ;// ./node_modules/@wordpress/icons/build-module/library/keyboard-return.js 22298 /** 22299 * WordPress dependencies 22300 */ 22301 22302 22303 const keyboardReturn = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22304 xmlns: "http://www.w3.org/2000/svg", 22305 viewBox: "0 0 24 24", 22306 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22307 d: "m6.734 16.106 2.176-2.38-1.093-1.028-3.846 4.158 3.846 4.158 1.093-1.028-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" 22308 }) 22309 }); 22310 /* harmony default export */ const keyboard_return = (keyboardReturn); 22311 22312 ;// ./node_modules/@wordpress/icons/build-module/library/chevron-left-small.js 22313 /** 22314 * WordPress dependencies 22315 */ 22316 22317 22318 const chevronLeftSmall = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22319 xmlns: "http://www.w3.org/2000/svg", 22320 viewBox: "0 0 24 24", 22321 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22322 d: "m13.1 16-3.4-4 3.4-4 1.1 1-2.6 3 2.6 3-1.1 1z" 22323 }) 22324 }); 22325 /* harmony default export */ const chevron_left_small = (chevronLeftSmall); 22326 22327 ;// ./node_modules/@wordpress/icons/build-module/library/chevron-right-small.js 22328 /** 22329 * WordPress dependencies 22330 */ 22331 22332 22333 const chevronRightSmall = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22334 xmlns: "http://www.w3.org/2000/svg", 22335 viewBox: "0 0 24 24", 22336 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22337 d: "M10.8622 8.04053L14.2805 12.0286L10.8622 16.0167L9.72327 15.0405L12.3049 12.0286L9.72327 9.01672L10.8622 8.04053Z" 22338 }) 22339 }); 22340 /* harmony default export */ const chevron_right_small = (chevronRightSmall); 22341 22342 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/settings-drawer.js 22343 /** 22344 * WordPress dependencies 22345 */ 22346 22347 22348 22349 22350 22351 22352 function LinkSettingsDrawer({ 22353 children, 22354 settingsOpen, 22355 setSettingsOpen 22356 }) { 22357 const prefersReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 22358 const MaybeAnimatePresence = prefersReducedMotion ? external_wp_element_namespaceObject.Fragment : external_wp_components_namespaceObject.__unstableAnimatePresence; 22359 const MaybeMotionDiv = prefersReducedMotion ? 'div' : external_wp_components_namespaceObject.__unstableMotion.div; 22360 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(LinkSettingsDrawer); 22361 const settingsDrawerId = `link-control-settings-drawer-$id}`; 22362 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 22363 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 22364 __next40pxDefaultSize: true, 22365 className: "block-editor-link-control__drawer-toggle", 22366 "aria-expanded": settingsOpen, 22367 onClick: () => setSettingsOpen(!settingsOpen), 22368 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left_small : chevron_right_small, 22369 "aria-controls": settingsDrawerId, 22370 children: (0,external_wp_i18n_namespaceObject._x)('Advanced', 'Additional link settings') 22371 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MaybeAnimatePresence, { 22372 children: settingsOpen && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MaybeMotionDiv, { 22373 className: "block-editor-link-control__drawer", 22374 hidden: !settingsOpen, 22375 id: settingsDrawerId, 22376 initial: "collapsed", 22377 animate: "open", 22378 exit: "collapsed", 22379 variants: { 22380 open: { 22381 opacity: 1, 22382 height: 'auto' 22383 }, 22384 collapsed: { 22385 opacity: 0, 22386 height: 0 22387 } 22388 }, 22389 transition: { 22390 duration: 0.1 22391 }, 22392 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 22393 className: "block-editor-link-control__drawer-inner", 22394 children: children 22395 }) 22396 }) 22397 })] 22398 }); 22399 } 22400 /* harmony default export */ const settings_drawer = (LinkSettingsDrawer); 22401 22402 // EXTERNAL MODULE: external "React" 22403 var external_React_ = __webpack_require__(1609); 22404 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-input/index.js 22405 /** 22406 * External dependencies 22407 */ 22408 22409 22410 /** 22411 * WordPress dependencies 22412 */ 22413 22414 22415 22416 22417 22418 22419 22420 22421 /** 22422 * Internal dependencies 22423 */ 22424 22425 22426 /** 22427 * Whether the argument is a function. 22428 * 22429 * @param {*} maybeFunc The argument to check. 22430 * @return {boolean} True if the argument is a function, false otherwise. 22431 */ 22432 22433 22434 function isFunction(maybeFunc) { 22435 return typeof maybeFunc === 'function'; 22436 } 22437 class URLInput extends external_wp_element_namespaceObject.Component { 22438 constructor(props) { 22439 super(props); 22440 this.onChange = this.onChange.bind(this); 22441 this.onFocus = this.onFocus.bind(this); 22442 this.onKeyDown = this.onKeyDown.bind(this); 22443 this.selectLink = this.selectLink.bind(this); 22444 this.handleOnClick = this.handleOnClick.bind(this); 22445 this.bindSuggestionNode = this.bindSuggestionNode.bind(this); 22446 this.autocompleteRef = props.autocompleteRef || (0,external_wp_element_namespaceObject.createRef)(); 22447 this.inputRef = (0,external_wp_element_namespaceObject.createRef)(); 22448 this.updateSuggestions = (0,external_wp_compose_namespaceObject.debounce)(this.updateSuggestions.bind(this), 200); 22449 this.suggestionNodes = []; 22450 this.suggestionsRequest = null; 22451 this.state = { 22452 suggestions: [], 22453 showSuggestions: false, 22454 suggestionsValue: null, 22455 selectedSuggestion: null, 22456 suggestionsListboxId: '', 22457 suggestionOptionIdPrefix: '' 22458 }; 22459 } 22460 componentDidUpdate(prevProps) { 22461 const { 22462 showSuggestions, 22463 selectedSuggestion 22464 } = this.state; 22465 const { 22466 value, 22467 __experimentalShowInitialSuggestions = false 22468 } = this.props; 22469 22470 // Only have to worry about scrolling selected suggestion into view 22471 // when already expanded. 22472 if (showSuggestions && selectedSuggestion !== null && this.suggestionNodes[selectedSuggestion]) { 22473 this.suggestionNodes[selectedSuggestion].scrollIntoView({ 22474 behavior: 'instant', 22475 block: 'nearest', 22476 inline: 'nearest' 22477 }); 22478 } 22479 22480 // Update suggestions when the value changes. 22481 if (prevProps.value !== value && !this.props.disableSuggestions) { 22482 if (value?.length) { 22483 // If the new value is not empty we need to update with suggestions for it. 22484 this.updateSuggestions(value); 22485 } else if (__experimentalShowInitialSuggestions) { 22486 // If the new value is empty and we can show initial suggestions, then show initial suggestions. 22487 this.updateSuggestions(); 22488 } 22489 } 22490 } 22491 componentDidMount() { 22492 if (this.shouldShowInitialSuggestions()) { 22493 this.updateSuggestions(); 22494 } 22495 } 22496 componentWillUnmount() { 22497 this.suggestionsRequest?.cancel?.(); 22498 this.suggestionsRequest = null; 22499 } 22500 bindSuggestionNode(index) { 22501 return ref => { 22502 this.suggestionNodes[index] = ref; 22503 }; 22504 } 22505 shouldShowInitialSuggestions() { 22506 const { 22507 __experimentalShowInitialSuggestions = false, 22508 value 22509 } = this.props; 22510 return __experimentalShowInitialSuggestions && !(value && value.length); 22511 } 22512 updateSuggestions(value = '') { 22513 const { 22514 __experimentalFetchLinkSuggestions: fetchLinkSuggestions, 22515 __experimentalHandleURLSuggestions: handleURLSuggestions 22516 } = this.props; 22517 if (!fetchLinkSuggestions) { 22518 return; 22519 } 22520 22521 // Initial suggestions may only show if there is no value 22522 // (note: this includes whitespace). 22523 const isInitialSuggestions = !value?.length; 22524 22525 // Trim only now we've determined whether or not it originally had a "length" 22526 // (even if that value was all whitespace). 22527 value = value.trim(); 22528 22529 // Allow a suggestions request if: 22530 // - there are at least 2 characters in the search input (except manual searches where 22531 // search input length is not required to trigger a fetch) 22532 // - this is a direct entry (eg: a URL) 22533 if (!isInitialSuggestions && (value.length < 2 || !handleURLSuggestions && (0,external_wp_url_namespaceObject.isURL)(value))) { 22534 this.suggestionsRequest?.cancel?.(); 22535 this.suggestionsRequest = null; 22536 this.setState({ 22537 suggestions: [], 22538 showSuggestions: false, 22539 suggestionsValue: value, 22540 selectedSuggestion: null, 22541 loading: false 22542 }); 22543 return; 22544 } 22545 this.setState({ 22546 selectedSuggestion: null, 22547 loading: true 22548 }); 22549 const request = fetchLinkSuggestions(value, { 22550 isInitialSuggestions 22551 }); 22552 request.then(suggestions => { 22553 // A fetch Promise doesn't have an abort option. It's mimicked by 22554 // comparing the request reference in on the instance, which is 22555 // reset or deleted on subsequent requests or unmounting. 22556 if (this.suggestionsRequest !== request) { 22557 return; 22558 } 22559 this.setState({ 22560 suggestions, 22561 suggestionsValue: value, 22562 loading: false, 22563 showSuggestions: !!suggestions.length 22564 }); 22565 if (!!suggestions.length) { 22566 this.props.debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of results. */ 22567 (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'); 22568 } else { 22569 this.props.debouncedSpeak((0,external_wp_i18n_namespaceObject.__)('No results.'), 'assertive'); 22570 } 22571 }).catch(() => { 22572 if (this.suggestionsRequest !== request) { 22573 return; 22574 } 22575 this.setState({ 22576 loading: false 22577 }); 22578 }).finally(() => { 22579 // If this is the current promise then reset the reference 22580 // to allow for checking if a new request is made. 22581 if (this.suggestionsRequest === request) { 22582 this.suggestionsRequest = null; 22583 } 22584 }); 22585 22586 // Note that this assignment is handled *before* the async search request 22587 // as a Promise always resolves on the next tick of the event loop. 22588 this.suggestionsRequest = request; 22589 } 22590 onChange(newValue) { 22591 this.props.onChange(newValue); 22592 } 22593 onFocus() { 22594 const { 22595 suggestions 22596 } = this.state; 22597 const { 22598 disableSuggestions, 22599 value 22600 } = this.props; 22601 22602 // 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 22603 // Don't re-run the suggestions on focus if there are already suggestions present (prevents searching again when tabbing between the input and buttons) 22604 // or there is already a request in progress. 22605 if (value && !disableSuggestions && !(suggestions && suggestions.length) && this.suggestionsRequest === null) { 22606 // Ensure the suggestions are updated with the current input value. 22607 this.updateSuggestions(value); 22608 } 22609 } 22610 onKeyDown(event) { 22611 this.props.onKeyDown?.(event); 22612 const { 22613 showSuggestions, 22614 selectedSuggestion, 22615 suggestions, 22616 loading 22617 } = this.state; 22618 22619 // If the suggestions are not shown or loading, we shouldn't handle the arrow keys 22620 // We shouldn't preventDefault to allow block arrow keys navigation. 22621 if (!showSuggestions || !suggestions.length || loading) { 22622 // In the Windows version of Firefox the up and down arrows don't move the caret 22623 // within an input field like they do for Mac Firefox/Chrome/Safari. This causes 22624 // a form of focus trapping that is disruptive to the user experience. This disruption 22625 // only happens if the caret is not in the first or last position in the text input. 22626 // See: https://github.com/WordPress/gutenberg/issues/5693#issuecomment-436684747 22627 switch (event.keyCode) { 22628 // When UP is pressed, if the caret is at the start of the text, move it to the 0 22629 // position. 22630 case external_wp_keycodes_namespaceObject.UP: 22631 { 22632 if (0 !== event.target.selectionStart) { 22633 event.preventDefault(); 22634 22635 // Set the input caret to position 0. 22636 event.target.setSelectionRange(0, 0); 22637 } 22638 break; 22639 } 22640 // When DOWN is pressed, if the caret is not at the end of the text, move it to the 22641 // last position. 22642 case external_wp_keycodes_namespaceObject.DOWN: 22643 { 22644 if (this.props.value.length !== event.target.selectionStart) { 22645 event.preventDefault(); 22646 22647 // Set the input caret to the last position. 22648 event.target.setSelectionRange(this.props.value.length, this.props.value.length); 22649 } 22650 break; 22651 } 22652 22653 // Submitting while loading should trigger onSubmit. 22654 case external_wp_keycodes_namespaceObject.ENTER: 22655 { 22656 if (this.props.onSubmit) { 22657 event.preventDefault(); 22658 this.props.onSubmit(null, event); 22659 } 22660 break; 22661 } 22662 } 22663 return; 22664 } 22665 const suggestion = this.state.suggestions[this.state.selectedSuggestion]; 22666 switch (event.keyCode) { 22667 case external_wp_keycodes_namespaceObject.UP: 22668 { 22669 event.preventDefault(); 22670 const previousIndex = !selectedSuggestion ? suggestions.length - 1 : selectedSuggestion - 1; 22671 this.setState({ 22672 selectedSuggestion: previousIndex 22673 }); 22674 break; 22675 } 22676 case external_wp_keycodes_namespaceObject.DOWN: 22677 { 22678 event.preventDefault(); 22679 const nextIndex = selectedSuggestion === null || selectedSuggestion === suggestions.length - 1 ? 0 : selectedSuggestion + 1; 22680 this.setState({ 22681 selectedSuggestion: nextIndex 22682 }); 22683 break; 22684 } 22685 case external_wp_keycodes_namespaceObject.TAB: 22686 { 22687 if (this.state.selectedSuggestion !== null) { 22688 this.selectLink(suggestion); 22689 // Announce a link has been selected when tabbing away from the input field. 22690 this.props.speak((0,external_wp_i18n_namespaceObject.__)('Link selected.')); 22691 } 22692 break; 22693 } 22694 case external_wp_keycodes_namespaceObject.ENTER: 22695 { 22696 event.preventDefault(); 22697 if (this.state.selectedSuggestion !== null) { 22698 this.selectLink(suggestion); 22699 if (this.props.onSubmit) { 22700 this.props.onSubmit(suggestion, event); 22701 } 22702 } else if (this.props.onSubmit) { 22703 this.props.onSubmit(null, event); 22704 } 22705 break; 22706 } 22707 } 22708 } 22709 selectLink(suggestion) { 22710 this.props.onChange(suggestion.url, suggestion); 22711 this.setState({ 22712 selectedSuggestion: null, 22713 showSuggestions: false 22714 }); 22715 } 22716 handleOnClick(suggestion) { 22717 this.selectLink(suggestion); 22718 // Move focus to the input field when a link suggestion is clicked. 22719 this.inputRef.current.focus(); 22720 } 22721 static getDerivedStateFromProps({ 22722 value, 22723 instanceId, 22724 disableSuggestions, 22725 __experimentalShowInitialSuggestions = false 22726 }, { 22727 showSuggestions 22728 }) { 22729 let shouldShowSuggestions = showSuggestions; 22730 const hasValue = value && value.length; 22731 if (!__experimentalShowInitialSuggestions && !hasValue) { 22732 shouldShowSuggestions = false; 22733 } 22734 if (disableSuggestions === true) { 22735 shouldShowSuggestions = false; 22736 } 22737 return { 22738 showSuggestions: shouldShowSuggestions, 22739 suggestionsListboxId: `block-editor-url-input-suggestions-$instanceId}`, 22740 suggestionOptionIdPrefix: `block-editor-url-input-suggestion-$instanceId}` 22741 }; 22742 } 22743 render() { 22744 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 22745 children: [this.renderControl(), this.renderSuggestions()] 22746 }); 22747 } 22748 renderControl() { 22749 const { 22750 label = null, 22751 className, 22752 isFullWidth, 22753 instanceId, 22754 placeholder = (0,external_wp_i18n_namespaceObject.__)('Paste URL or type to search'), 22755 __experimentalRenderControl: renderControl, 22756 value = '', 22757 hideLabelFromVision = false 22758 } = this.props; 22759 const { 22760 loading, 22761 showSuggestions, 22762 selectedSuggestion, 22763 suggestionsListboxId, 22764 suggestionOptionIdPrefix 22765 } = this.state; 22766 const inputId = `url-input-control-$instanceId}`; 22767 const controlProps = { 22768 id: inputId, 22769 // Passes attribute to label for the for attribute 22770 label, 22771 className: dist_clsx('block-editor-url-input', className, { 22772 'is-full-width': isFullWidth 22773 }), 22774 hideLabelFromVision 22775 }; 22776 const inputProps = { 22777 id: inputId, 22778 value, 22779 required: true, 22780 type: 'text', 22781 onChange: this.onChange, 22782 onFocus: this.onFocus, 22783 placeholder, 22784 onKeyDown: this.onKeyDown, 22785 role: 'combobox', 22786 'aria-label': label ? undefined : (0,external_wp_i18n_namespaceObject.__)('URL'), 22787 // Ensure input always has an accessible label 22788 'aria-expanded': showSuggestions, 22789 'aria-autocomplete': 'list', 22790 'aria-owns': suggestionsListboxId, 22791 'aria-activedescendant': selectedSuggestion !== null ? `$suggestionOptionIdPrefix}-$selectedSuggestion}` : undefined, 22792 ref: this.inputRef, 22793 suffix: this.props.suffix 22794 }; 22795 if (renderControl) { 22796 return renderControl(controlProps, inputProps, loading); 22797 } 22798 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.BaseControl, { 22799 __nextHasNoMarginBottom: true, 22800 ...controlProps, 22801 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, { 22802 ...inputProps, 22803 __next40pxDefaultSize: true 22804 }), loading && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Spinner, {})] 22805 }); 22806 } 22807 renderSuggestions() { 22808 const { 22809 className, 22810 __experimentalRenderSuggestions: renderSuggestions 22811 } = this.props; 22812 const { 22813 showSuggestions, 22814 suggestions, 22815 suggestionsValue, 22816 selectedSuggestion, 22817 suggestionsListboxId, 22818 suggestionOptionIdPrefix, 22819 loading 22820 } = this.state; 22821 if (!showSuggestions || suggestions.length === 0) { 22822 return null; 22823 } 22824 const suggestionsListProps = { 22825 id: suggestionsListboxId, 22826 ref: this.autocompleteRef, 22827 role: 'listbox' 22828 }; 22829 const buildSuggestionItemProps = (suggestion, index) => { 22830 return { 22831 role: 'option', 22832 tabIndex: '-1', 22833 id: `$suggestionOptionIdPrefix}-$index}`, 22834 ref: this.bindSuggestionNode(index), 22835 'aria-selected': index === selectedSuggestion ? true : undefined 22836 }; 22837 }; 22838 if (isFunction(renderSuggestions)) { 22839 return renderSuggestions({ 22840 suggestions, 22841 selectedSuggestion, 22842 suggestionsListProps, 22843 buildSuggestionItemProps, 22844 isLoading: loading, 22845 handleSuggestionClick: this.handleOnClick, 22846 isInitialSuggestions: !suggestionsValue?.length, 22847 currentInputValue: suggestionsValue 22848 }); 22849 } 22850 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 22851 placement: "bottom", 22852 focusOnMount: false, 22853 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 22854 ...suggestionsListProps, 22855 className: dist_clsx('block-editor-url-input__suggestions', { 22856 [`$className}__suggestions`]: className 22857 }), 22858 children: suggestions.map((suggestion, index) => /*#__PURE__*/(0,external_React_.createElement)(external_wp_components_namespaceObject.Button, { 22859 __next40pxDefaultSize: true, 22860 ...buildSuggestionItemProps(suggestion, index), 22861 key: suggestion.id, 22862 className: dist_clsx('block-editor-url-input__suggestion', { 22863 'is-selected': index === selectedSuggestion 22864 }), 22865 onClick: () => this.handleOnClick(suggestion) 22866 }, suggestion.title)) 22867 }) 22868 }); 22869 } 22870 } 22871 22872 /** 22873 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-input/README.md 22874 */ 22875 /* 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) => { 22876 // If a link suggestions handler is already provided then 22877 // bail. 22878 if (isFunction(props.__experimentalFetchLinkSuggestions)) { 22879 return; 22880 } 22881 const { 22882 getSettings 22883 } = select(store); 22884 return { 22885 __experimentalFetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions 22886 }; 22887 }))(URLInput)); 22888 22889 ;// ./node_modules/@wordpress/icons/build-module/library/plus.js 22890 /** 22891 * WordPress dependencies 22892 */ 22893 22894 22895 const plus = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22896 xmlns: "http://www.w3.org/2000/svg", 22897 viewBox: "0 0 24 24", 22898 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22899 d: "M11 12.5V17.5H12.5V12.5H17.5V11H12.5V6H11V11H6V12.5H11Z" 22900 }) 22901 }); 22902 /* harmony default export */ const library_plus = (plus); 22903 22904 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-create-button.js 22905 /** 22906 * WordPress dependencies 22907 */ 22908 22909 22910 22911 22912 22913 const LinkControlSearchCreate = ({ 22914 searchTerm, 22915 onClick, 22916 itemProps, 22917 buttonText 22918 }) => { 22919 if (!searchTerm) { 22920 return null; 22921 } 22922 let text; 22923 if (buttonText) { 22924 text = typeof buttonText === 'function' ? buttonText(searchTerm) : buttonText; 22925 } else { 22926 text = (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: search term. */ 22927 (0,external_wp_i18n_namespaceObject.__)('Create: <mark>%s</mark>'), searchTerm), { 22928 mark: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("mark", {}) 22929 }); 22930 } 22931 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 22932 ...itemProps, 22933 iconPosition: "left", 22934 icon: library_plus, 22935 className: "block-editor-link-control__search-item", 22936 onClick: onClick, 22937 children: text 22938 }); 22939 }; 22940 /* harmony default export */ const search_create_button = (LinkControlSearchCreate); 22941 22942 ;// ./node_modules/@wordpress/icons/build-module/library/post-list.js 22943 /** 22944 * WordPress dependencies 22945 */ 22946 22947 22948 const postList = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22949 viewBox: "0 0 24 24", 22950 xmlns: "http://www.w3.org/2000/svg", 22951 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22952 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" 22953 }) 22954 }); 22955 /* harmony default export */ const post_list = (postList); 22956 22957 ;// ./node_modules/@wordpress/icons/build-module/library/page.js 22958 /** 22959 * WordPress dependencies 22960 */ 22961 22962 22963 const page = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 22964 xmlns: "http://www.w3.org/2000/svg", 22965 viewBox: "0 0 24 24", 22966 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22967 d: "M15.5 7.5h-7V9h7V7.5Zm-7 3.5h7v1.5h-7V11Zm7 3.5h-7V16h7v-1.5Z" 22968 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22969 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" 22970 })] 22971 }); 22972 /* harmony default export */ const library_page = (page); 22973 22974 ;// ./node_modules/@wordpress/icons/build-module/library/tag.js 22975 /** 22976 * WordPress dependencies 22977 */ 22978 22979 22980 const tag = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22981 xmlns: "http://www.w3.org/2000/svg", 22982 viewBox: "0 0 24 24", 22983 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22984 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" 22985 }) 22986 }); 22987 /* harmony default export */ const library_tag = (tag); 22988 22989 ;// ./node_modules/@wordpress/icons/build-module/library/category.js 22990 /** 22991 * WordPress dependencies 22992 */ 22993 22994 22995 const category = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 22996 viewBox: "0 0 24 24", 22997 xmlns: "http://www.w3.org/2000/svg", 22998 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 22999 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", 23000 fillRule: "evenodd", 23001 clipRule: "evenodd" 23002 }) 23003 }); 23004 /* harmony default export */ const library_category = (category); 23005 23006 ;// ./node_modules/@wordpress/icons/build-module/library/file.js 23007 /** 23008 * WordPress dependencies 23009 */ 23010 23011 23012 const file = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23013 viewBox: "0 0 24 24", 23014 xmlns: "http://www.w3.org/2000/svg", 23015 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23016 fillRule: "evenodd", 23017 clipRule: "evenodd", 23018 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" 23019 }) 23020 }); 23021 /* harmony default export */ const library_file = (file); 23022 23023 ;// ./node_modules/@wordpress/icons/build-module/library/globe.js 23024 /** 23025 * WordPress dependencies 23026 */ 23027 23028 23029 const globe = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23030 xmlns: "http://www.w3.org/2000/svg", 23031 viewBox: "0 0 24 24", 23032 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23033 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" 23034 }) 23035 }); 23036 /* harmony default export */ const library_globe = (globe); 23037 23038 ;// ./node_modules/@wordpress/icons/build-module/library/home.js 23039 /** 23040 * WordPress dependencies 23041 */ 23042 23043 23044 const home = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23045 xmlns: "http://www.w3.org/2000/svg", 23046 viewBox: "0 0 24 24", 23047 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23048 d: "M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z" 23049 }) 23050 }); 23051 /* harmony default export */ const library_home = (home); 23052 23053 ;// ./node_modules/@wordpress/icons/build-module/library/verse.js 23054 /** 23055 * WordPress dependencies 23056 */ 23057 23058 23059 const verse = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23060 viewBox: "0 0 24 24", 23061 xmlns: "http://www.w3.org/2000/svg", 23062 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23063 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" 23064 }) 23065 }); 23066 /* harmony default export */ const library_verse = (verse); 23067 23068 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-item.js 23069 /** 23070 * WordPress dependencies 23071 */ 23072 23073 23074 23075 23076 23077 23078 23079 23080 const ICONS_MAP = { 23081 post: post_list, 23082 page: library_page, 23083 post_tag: library_tag, 23084 category: library_category, 23085 attachment: library_file 23086 }; 23087 function SearchItemIcon({ 23088 isURL, 23089 suggestion 23090 }) { 23091 let icon = null; 23092 if (isURL) { 23093 icon = library_globe; 23094 } else if (suggestion.type in ICONS_MAP) { 23095 icon = ICONS_MAP[suggestion.type]; 23096 if (suggestion.type === 'page') { 23097 if (suggestion.isFrontPage) { 23098 icon = library_home; 23099 } 23100 if (suggestion.isBlogHome) { 23101 icon = library_verse; 23102 } 23103 } 23104 } 23105 if (icon) { 23106 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 23107 className: "block-editor-link-control__search-item-icon", 23108 icon: icon 23109 }); 23110 } 23111 return null; 23112 } 23113 23114 /** 23115 * Adds a leading slash to a url if it doesn't already have one. 23116 * @param {string} url the url to add a leading slash to. 23117 * @return {string} the url with a leading slash. 23118 */ 23119 function addLeadingSlash(url) { 23120 const trimmedURL = url?.trim(); 23121 if (!trimmedURL?.length) { 23122 return url; 23123 } 23124 return url?.replace(/^\/?/, '/'); 23125 } 23126 function removeTrailingSlash(url) { 23127 const trimmedURL = url?.trim(); 23128 if (!trimmedURL?.length) { 23129 return url; 23130 } 23131 return url?.replace(/\/$/, ''); 23132 } 23133 const partialRight = (fn, ...partialArgs) => (...args) => fn(...args, ...partialArgs); 23134 const defaultTo = d => v => { 23135 return v === null || v === undefined || v !== v ? d : v; 23136 }; 23137 23138 /** 23139 * Prepares a URL for display in the UI. 23140 * - decodes the URL. 23141 * - filters it (removes protocol, www, etc.). 23142 * - truncates it if necessary. 23143 * - adds a leading slash. 23144 * @param {string} url the url. 23145 * @return {string} the processed url to display. 23146 */ 23147 function getURLForDisplay(url) { 23148 if (!url) { 23149 return url; 23150 } 23151 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); 23152 } 23153 const LinkControlSearchItem = ({ 23154 itemProps, 23155 suggestion, 23156 searchTerm, 23157 onClick, 23158 isURL = false, 23159 shouldShowType = false 23160 }) => { 23161 const info = isURL ? (0,external_wp_i18n_namespaceObject.__)('Press ENTER to add this link') : getURLForDisplay(suggestion.url); 23162 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 23163 ...itemProps, 23164 info: info, 23165 iconPosition: "left", 23166 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SearchItemIcon, { 23167 suggestion: suggestion, 23168 isURL: isURL 23169 }), 23170 onClick: onClick, 23171 shortcut: shouldShowType && getVisualTypeName(suggestion), 23172 className: "block-editor-link-control__search-item", 23173 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextHighlight 23174 // The component expects a plain text string. 23175 , { 23176 text: (0,external_wp_dom_namespaceObject.__unstableStripHTML)(suggestion.title), 23177 highlight: searchTerm 23178 }) 23179 }); 23180 }; 23181 function getVisualTypeName(suggestion) { 23182 if (suggestion.isFrontPage) { 23183 return 'front page'; 23184 } 23185 if (suggestion.isBlogHome) { 23186 return 'blog home'; 23187 } 23188 23189 // Rename 'post_tag' to 'tag'. Ideally, the API would return the localised CPT or taxonomy label. 23190 return suggestion.type === 'post_tag' ? 'tag' : suggestion.type; 23191 } 23192 /* harmony default export */ const search_item = (LinkControlSearchItem); 23193 const __experimentalLinkControlSearchItem = props => { 23194 external_wp_deprecated_default()('wp.blockEditor.__experimentalLinkControlSearchItem', { 23195 since: '6.8' 23196 }); 23197 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkControlSearchItem, { 23198 ...props 23199 }); 23200 }; 23201 23202 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/constants.js 23203 /** 23204 * WordPress dependencies 23205 */ 23206 23207 23208 // Used as a unique identifier for the "Create" option within search results. 23209 // Used to help distinguish the "Create" suggestion within the search results in 23210 // order to handle it as a unique case. 23211 const CREATE_TYPE = '__CREATE__'; 23212 const TEL_TYPE = 'tel'; 23213 const URL_TYPE = 'link'; 23214 const MAILTO_TYPE = 'mailto'; 23215 const INTERNAL_TYPE = 'internal'; 23216 const LINK_ENTRY_TYPES = [URL_TYPE, MAILTO_TYPE, TEL_TYPE, INTERNAL_TYPE]; 23217 const DEFAULT_LINK_SETTINGS = [{ 23218 id: 'opensInNewTab', 23219 title: (0,external_wp_i18n_namespaceObject.__)('Open in new tab') 23220 }]; 23221 23222 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-results.js 23223 /** 23224 * WordPress dependencies 23225 */ 23226 23227 23228 23229 /** 23230 * External dependencies 23231 */ 23232 23233 23234 /** 23235 * Internal dependencies 23236 */ 23237 23238 23239 23240 23241 23242 function LinkControlSearchResults({ 23243 withCreateSuggestion, 23244 currentInputValue, 23245 handleSuggestionClick, 23246 suggestionsListProps, 23247 buildSuggestionItemProps, 23248 suggestions, 23249 selectedSuggestion, 23250 isLoading, 23251 isInitialSuggestions, 23252 createSuggestionButtonText, 23253 suggestionsQuery 23254 }) { 23255 const resultsListClasses = dist_clsx('block-editor-link-control__search-results', { 23256 'is-loading': isLoading 23257 }); 23258 const isSingleDirectEntryResult = suggestions.length === 1 && LINK_ENTRY_TYPES.includes(suggestions[0].type); 23259 const shouldShowCreateSuggestion = withCreateSuggestion && !isSingleDirectEntryResult && !isInitialSuggestions; 23260 // If the query has a specified type, then we can skip showing them in the result. See #24839. 23261 const shouldShowSuggestionsTypes = !suggestionsQuery?.type; 23262 const labelText = isInitialSuggestions ? (0,external_wp_i18n_namespaceObject.__)('Suggestions') : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: search term. */ 23263 (0,external_wp_i18n_namespaceObject.__)('Search results for "%s"'), currentInputValue); 23264 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 23265 className: "block-editor-link-control__search-results-wrapper", 23266 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 23267 ...suggestionsListProps, 23268 className: resultsListClasses, 23269 "aria-label": labelText, 23270 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 23271 children: suggestions.map((suggestion, index) => { 23272 if (shouldShowCreateSuggestion && CREATE_TYPE === suggestion.type) { 23273 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(search_create_button, { 23274 searchTerm: currentInputValue, 23275 buttonText: createSuggestionButtonText, 23276 onClick: () => handleSuggestionClick(suggestion) 23277 // Intentionally only using `type` here as 23278 // the constant is enough to uniquely 23279 // identify the single "CREATE" suggestion. 23280 , 23281 23282 itemProps: buildSuggestionItemProps(suggestion, index), 23283 isSelected: index === selectedSuggestion 23284 }, suggestion.type); 23285 } 23286 23287 // If we're not handling "Create" suggestions above then 23288 // we don't want them in the main results so exit early. 23289 if (CREATE_TYPE === suggestion.type) { 23290 return null; 23291 } 23292 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(search_item, { 23293 itemProps: buildSuggestionItemProps(suggestion, index), 23294 suggestion: suggestion, 23295 index: index, 23296 onClick: () => { 23297 handleSuggestionClick(suggestion); 23298 }, 23299 isSelected: index === selectedSuggestion, 23300 isURL: LINK_ENTRY_TYPES.includes(suggestion.type), 23301 searchTerm: currentInputValue, 23302 shouldShowType: shouldShowSuggestionsTypes, 23303 isFrontPage: suggestion?.isFrontPage, 23304 isBlogHome: suggestion?.isBlogHome 23305 }, `$suggestion.id}-$suggestion.type}`); 23306 }) 23307 }) 23308 }) 23309 }); 23310 } 23311 /* harmony default export */ const search_results = (LinkControlSearchResults); 23312 const __experimentalLinkControlSearchResults = props => { 23313 external_wp_deprecated_default()('wp.blockEditor.__experimentalLinkControlSearchResults', { 23314 since: '6.8' 23315 }); 23316 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkControlSearchResults, { 23317 ...props 23318 }); 23319 }; 23320 23321 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/is-url-like.js 23322 /** 23323 * WordPress dependencies 23324 */ 23325 23326 23327 /** 23328 * Determines whether a given value could be a URL. Note this does not 23329 * guarantee the value is a URL only that it looks like it might be one. For 23330 * example, just because a string has `www.` in it doesn't make it a URL, 23331 * but it does make it highly likely that it will be so in the context of 23332 * creating a link it makes sense to treat it like one. 23333 * 23334 * @param {string} val the candidate for being URL-like (or not). 23335 * 23336 * @return {boolean} whether or not the value is potentially a URL. 23337 */ 23338 function isURLLike(val) { 23339 const hasSpaces = val.includes(' '); 23340 if (hasSpaces) { 23341 return false; 23342 } 23343 const protocol = (0,external_wp_url_namespaceObject.getProtocol)(val); 23344 const protocolIsValid = (0,external_wp_url_namespaceObject.isValidProtocol)(protocol); 23345 const mayBeTLD = hasPossibleTLD(val); 23346 const isWWW = val?.startsWith('www.'); 23347 const isInternal = val?.startsWith('#') && (0,external_wp_url_namespaceObject.isValidFragment)(val); 23348 return protocolIsValid || isWWW || isInternal || mayBeTLD; 23349 } 23350 23351 /** 23352 * Checks if a given URL has a valid Top-Level Domain (TLD). 23353 * 23354 * @param {string} url - The URL to check. 23355 * @param {number} maxLength - The maximum length of the TLD. 23356 * @return {boolean} Returns true if the URL has a valid TLD, false otherwise. 23357 */ 23358 function hasPossibleTLD(url, maxLength = 6) { 23359 // Clean the URL by removing anything after the first occurrence of "?" or "#". 23360 const cleanedURL = url.split(/[?#]/)[0]; 23361 23362 // Regular expression explanation: 23363 // - (?<=\S) : Positive lookbehind assertion to ensure there is at least one non-whitespace character before the TLD 23364 // - \. : Matches a literal dot (.) 23365 // - [a-zA-Z_]{2,maxLength} : Matches 2 to maxLength letters or underscores, representing the TLD 23366 // - (?:\/|$) : Non-capturing group that matches either a forward slash (/) or the end of the string 23367 const regex = new RegExp(`(?<=\\S)\\.(?:[a-zA-Z_]{2,$maxLength}})(?:\\/|$)`); 23368 return regex.test(cleanedURL); 23369 } 23370 23371 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-search-handler.js 23372 /** 23373 * WordPress dependencies 23374 */ 23375 23376 23377 23378 23379 /** 23380 * Internal dependencies 23381 */ 23382 23383 23384 23385 const handleNoop = () => Promise.resolve([]); 23386 const handleDirectEntry = val => { 23387 let type = URL_TYPE; 23388 const protocol = (0,external_wp_url_namespaceObject.getProtocol)(val) || ''; 23389 if (protocol.includes('mailto')) { 23390 type = MAILTO_TYPE; 23391 } 23392 if (protocol.includes('tel')) { 23393 type = TEL_TYPE; 23394 } 23395 if (val?.startsWith('#')) { 23396 type = INTERNAL_TYPE; 23397 } 23398 return Promise.resolve([{ 23399 id: val, 23400 title: val, 23401 url: type === 'URL' ? (0,external_wp_url_namespaceObject.prependHTTP)(val) : val, 23402 type 23403 }]); 23404 }; 23405 const handleEntitySearch = async (val, suggestionsQuery, fetchSearchSuggestions, withCreateSuggestion, pageOnFront, pageForPosts) => { 23406 const { 23407 isInitialSuggestions 23408 } = suggestionsQuery; 23409 const results = await fetchSearchSuggestions(val, suggestionsQuery); 23410 23411 // Identify front page and update type to match. 23412 results.map(result => { 23413 if (Number(result.id) === pageOnFront) { 23414 result.isFrontPage = true; 23415 return result; 23416 } else if (Number(result.id) === pageForPosts) { 23417 result.isBlogHome = true; 23418 return result; 23419 } 23420 return result; 23421 }); 23422 23423 // If displaying initial suggestions just return plain results. 23424 if (isInitialSuggestions) { 23425 return results; 23426 } 23427 23428 // Here we append a faux suggestion to represent a "CREATE" option. This 23429 // is detected in the rendering of the search results and handled as a 23430 // special case. This is currently necessary because the suggestions 23431 // dropdown will only appear if there are valid suggestions and 23432 // therefore unless the create option is a suggestion it will not 23433 // display in scenarios where there are no results returned from the 23434 // API. In addition promoting CREATE to a first class suggestion affords 23435 // the a11y benefits afforded by `URLInput` to all suggestions (eg: 23436 // keyboard handling, ARIA roles...etc). 23437 // 23438 // Note also that the value of the `title` and `url` properties must correspond 23439 // to the text value of the `<input>`. This is because `title` is used 23440 // when creating the suggestion. Similarly `url` is used when using keyboard to select 23441 // the suggestion (the <form> `onSubmit` handler falls-back to `url`). 23442 return isURLLike(val) || !withCreateSuggestion ? results : results.concat({ 23443 // the `id` prop is intentionally omitted here because it 23444 // is never exposed as part of the component's public API. 23445 // see: https://github.com/WordPress/gutenberg/pull/19775#discussion_r378931316. 23446 title: val, 23447 // Must match the existing `<input>`s text value. 23448 url: val, 23449 // Must match the existing `<input>`s text value. 23450 type: CREATE_TYPE 23451 }); 23452 }; 23453 function useSearchHandler(suggestionsQuery, allowDirectEntry, withCreateSuggestion) { 23454 const { 23455 fetchSearchSuggestions, 23456 pageOnFront, 23457 pageForPosts 23458 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 23459 const { 23460 getSettings 23461 } = select(store); 23462 return { 23463 pageOnFront: getSettings().pageOnFront, 23464 pageForPosts: getSettings().pageForPosts, 23465 fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions 23466 }; 23467 }, []); 23468 const directEntryHandler = allowDirectEntry ? handleDirectEntry : handleNoop; 23469 return (0,external_wp_element_namespaceObject.useCallback)((val, { 23470 isInitialSuggestions 23471 }) => { 23472 return isURLLike(val) ? directEntryHandler(val, { 23473 isInitialSuggestions 23474 }) : handleEntitySearch(val, { 23475 ...suggestionsQuery, 23476 isInitialSuggestions 23477 }, fetchSearchSuggestions, withCreateSuggestion, pageOnFront, pageForPosts); 23478 }, [directEntryHandler, fetchSearchSuggestions, pageOnFront, pageForPosts, suggestionsQuery, withCreateSuggestion]); 23479 } 23480 23481 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-input.js 23482 /** 23483 * WordPress dependencies 23484 */ 23485 23486 23487 23488 /** 23489 * Internal dependencies 23490 */ 23491 23492 23493 23494 23495 23496 23497 // Must be a function as otherwise URLInput will default 23498 // to the fetchLinkSuggestions passed in block editor settings 23499 // which will cause an unintended http request. 23500 23501 const noopSearchHandler = () => Promise.resolve([]); 23502 const noop = () => {}; 23503 const LinkControlSearchInput = (0,external_wp_element_namespaceObject.forwardRef)(({ 23504 value, 23505 children, 23506 currentLink = {}, 23507 className = null, 23508 placeholder = null, 23509 withCreateSuggestion = false, 23510 onCreateSuggestion = noop, 23511 onChange = noop, 23512 onSelect = noop, 23513 showSuggestions = true, 23514 renderSuggestions = props => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(search_results, { 23515 ...props 23516 }), 23517 fetchSuggestions = null, 23518 allowDirectEntry = true, 23519 showInitialSuggestions = false, 23520 suggestionsQuery = {}, 23521 withURLSuggestion = true, 23522 createSuggestionButtonText, 23523 hideLabelFromVision = false, 23524 suffix 23525 }, ref) => { 23526 const genericSearchHandler = useSearchHandler(suggestionsQuery, allowDirectEntry, withCreateSuggestion, withURLSuggestion); 23527 const searchHandler = showSuggestions ? fetchSuggestions || genericSearchHandler : noopSearchHandler; 23528 const [focusedSuggestion, setFocusedSuggestion] = (0,external_wp_element_namespaceObject.useState)(); 23529 23530 /** 23531 * Handles the user moving between different suggestions. Does not handle 23532 * choosing an individual item. 23533 * 23534 * @param {string} selection the url of the selected suggestion. 23535 * @param {Object} suggestion the suggestion object. 23536 */ 23537 const onInputChange = (selection, suggestion) => { 23538 onChange(selection); 23539 setFocusedSuggestion(suggestion); 23540 }; 23541 const handleRenderSuggestions = props => renderSuggestions({ 23542 ...props, 23543 withCreateSuggestion, 23544 createSuggestionButtonText, 23545 suggestionsQuery, 23546 handleSuggestionClick: suggestion => { 23547 if (props.handleSuggestionClick) { 23548 props.handleSuggestionClick(suggestion); 23549 } 23550 onSuggestionSelected(suggestion); 23551 } 23552 }); 23553 const onSuggestionSelected = async selectedSuggestion => { 23554 let suggestion = selectedSuggestion; 23555 if (CREATE_TYPE === selectedSuggestion.type) { 23556 // Create a new page and call onSelect with the output from the onCreateSuggestion callback. 23557 try { 23558 suggestion = await onCreateSuggestion(selectedSuggestion.title); 23559 if (suggestion?.url) { 23560 onSelect(suggestion); 23561 } 23562 } catch (e) {} 23563 return; 23564 } 23565 if (allowDirectEntry || suggestion && Object.keys(suggestion).length >= 1) { 23566 const { 23567 id, 23568 url, 23569 ...restLinkProps 23570 } = currentLink !== null && currentLink !== void 0 ? currentLink : {}; 23571 onSelect( 23572 // Some direct entries don't have types or IDs, and we still need to clear the previous ones. 23573 { 23574 ...restLinkProps, 23575 ...suggestion 23576 }, suggestion); 23577 } 23578 }; 23579 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 23580 className: "block-editor-link-control__search-input-container", 23581 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_input, { 23582 disableSuggestions: currentLink?.url === value, 23583 label: (0,external_wp_i18n_namespaceObject.__)('Link'), 23584 hideLabelFromVision: hideLabelFromVision, 23585 className: className, 23586 value: value, 23587 onChange: onInputChange, 23588 placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : (0,external_wp_i18n_namespaceObject.__)('Search or type URL'), 23589 __experimentalRenderSuggestions: showSuggestions ? handleRenderSuggestions : null, 23590 __experimentalFetchLinkSuggestions: searchHandler, 23591 __experimentalHandleURLSuggestions: true, 23592 __experimentalShowInitialSuggestions: showInitialSuggestions, 23593 onSubmit: (suggestion, event) => { 23594 const hasSuggestion = suggestion || focusedSuggestion; 23595 23596 // If there is no suggestion and the value (ie: any manually entered URL) is empty 23597 // then don't allow submission otherwise we get empty links. 23598 if (!hasSuggestion && !value?.trim()?.length) { 23599 event.preventDefault(); 23600 } else { 23601 onSuggestionSelected(hasSuggestion || { 23602 url: value 23603 }); 23604 } 23605 }, 23606 ref: ref, 23607 suffix: suffix 23608 }), children] 23609 }); 23610 }); 23611 /* harmony default export */ const search_input = (LinkControlSearchInput); 23612 const __experimentalLinkControlSearchInput = props => { 23613 external_wp_deprecated_default()('wp.blockEditor.__experimentalLinkControlSearchInput', { 23614 since: '6.8' 23615 }); 23616 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkControlSearchInput, { 23617 ...props 23618 }); 23619 }; 23620 23621 ;// ./node_modules/@wordpress/icons/build-module/library/info.js 23622 /** 23623 * WordPress dependencies 23624 */ 23625 23626 23627 const info = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23628 viewBox: "0 0 24 24", 23629 xmlns: "http://www.w3.org/2000/svg", 23630 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23631 fillRule: "evenodd", 23632 clipRule: "evenodd", 23633 d: "M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm.75 4v1.5h-1.5V8h1.5Zm0 8v-5h-1.5v5h1.5Z" 23634 }) 23635 }); 23636 /* harmony default export */ const library_info = (info); 23637 23638 ;// ./node_modules/@wordpress/icons/build-module/library/pencil.js 23639 /** 23640 * WordPress dependencies 23641 */ 23642 23643 23644 const pencil = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23645 xmlns: "http://www.w3.org/2000/svg", 23646 viewBox: "0 0 24 24", 23647 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23648 d: "m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z" 23649 }) 23650 }); 23651 /* harmony default export */ const library_pencil = (pencil); 23652 23653 ;// ./node_modules/@wordpress/icons/build-module/library/edit.js 23654 /** 23655 * Internal dependencies 23656 */ 23657 23658 23659 /* harmony default export */ const edit = (library_pencil); 23660 23661 ;// ./node_modules/@wordpress/icons/build-module/library/link-off.js 23662 /** 23663 * WordPress dependencies 23664 */ 23665 23666 23667 const linkOff = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23668 xmlns: "http://www.w3.org/2000/svg", 23669 viewBox: "0 0 24 24", 23670 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23671 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" 23672 }) 23673 }); 23674 /* harmony default export */ const link_off = (linkOff); 23675 23676 ;// ./node_modules/@wordpress/icons/build-module/library/copy-small.js 23677 /** 23678 * WordPress dependencies 23679 */ 23680 23681 23682 const copySmall = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 23683 xmlns: "http://www.w3.org/2000/svg", 23684 viewBox: "0 0 24 24", 23685 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 23686 fillRule: "evenodd", 23687 clipRule: "evenodd", 23688 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" 23689 }) 23690 }); 23691 /* harmony default export */ const copy_small = (copySmall); 23692 23693 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/viewer-slot.js 23694 /** 23695 * WordPress dependencies 23696 */ 23697 23698 const { 23699 Slot: ViewerSlot, 23700 Fill: ViewerFill 23701 } = (0,external_wp_components_namespaceObject.createSlotFill)('BlockEditorLinkControlViewer'); 23702 23703 /* harmony default export */ const viewer_slot = ((/* unused pure expression or super */ null && (ViewerSlot))); 23704 23705 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-rich-url-data.js 23706 /** 23707 * Internal dependencies 23708 */ 23709 23710 23711 /** 23712 * WordPress dependencies 23713 */ 23714 23715 23716 function use_rich_url_data_reducer(state, action) { 23717 switch (action.type) { 23718 case 'RESOLVED': 23719 return { 23720 ...state, 23721 isFetching: false, 23722 richData: action.richData 23723 }; 23724 case 'ERROR': 23725 return { 23726 ...state, 23727 isFetching: false, 23728 richData: null 23729 }; 23730 case 'LOADING': 23731 return { 23732 ...state, 23733 isFetching: true 23734 }; 23735 default: 23736 throw new Error(`Unexpected action type $action.type}`); 23737 } 23738 } 23739 function useRemoteUrlData(url) { 23740 const [state, dispatch] = (0,external_wp_element_namespaceObject.useReducer)(use_rich_url_data_reducer, { 23741 richData: null, 23742 isFetching: false 23743 }); 23744 const { 23745 fetchRichUrlData 23746 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 23747 const { 23748 getSettings 23749 } = select(store); 23750 return { 23751 fetchRichUrlData: getSettings().__experimentalFetchRichUrlData 23752 }; 23753 }, []); 23754 (0,external_wp_element_namespaceObject.useEffect)(() => { 23755 // Only make the request if we have an actual URL 23756 // and the fetching util is available. In some editors 23757 // there may not be such a util. 23758 if (url?.length && fetchRichUrlData && typeof AbortController !== 'undefined') { 23759 dispatch({ 23760 type: 'LOADING' 23761 }); 23762 const controller = new window.AbortController(); 23763 const signal = controller.signal; 23764 fetchRichUrlData(url, { 23765 signal 23766 }).then(urlData => { 23767 dispatch({ 23768 type: 'RESOLVED', 23769 richData: urlData 23770 }); 23771 }).catch(() => { 23772 // Avoid setting state on unmounted component 23773 if (!signal.aborted) { 23774 dispatch({ 23775 type: 'ERROR' 23776 }); 23777 } 23778 }); 23779 // Cleanup: when the URL changes the abort the current request. 23780 return () => { 23781 controller.abort(); 23782 }; 23783 } 23784 }, [url]); 23785 return state; 23786 } 23787 /* harmony default export */ const use_rich_url_data = (useRemoteUrlData); 23788 23789 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/link-preview.js 23790 /** 23791 * External dependencies 23792 */ 23793 23794 23795 /** 23796 * WordPress dependencies 23797 */ 23798 23799 23800 23801 23802 23803 23804 23805 23806 23807 23808 /** 23809 * Internal dependencies 23810 */ 23811 23812 23813 23814 /** 23815 * Filters the title for display. Removes the protocol and www prefix. 23816 * 23817 * @param {string} title The title to be filtered. 23818 * 23819 * @return {string} The filtered title. 23820 */ 23821 23822 function filterTitleForDisplay(title) { 23823 // Derived from `filterURLForDisplay` in `@wordpress/url`. 23824 return title.replace(/^[a-z\-.\+]+[0-9]*:(\/\/)?/i, '').replace(/^www\./i, ''); 23825 } 23826 function LinkPreview({ 23827 value, 23828 onEditClick, 23829 hasRichPreviews = false, 23830 hasUnlinkControl = false, 23831 onRemove 23832 }) { 23833 const showIconLabels = (0,external_wp_data_namespaceObject.useSelect)(select => select(external_wp_preferences_namespaceObject.store).get('core', 'showIconLabels'), []); 23834 23835 // Avoid fetching if rich previews are not desired. 23836 const showRichPreviews = hasRichPreviews ? value?.url : null; 23837 const { 23838 richData, 23839 isFetching 23840 } = use_rich_url_data(showRichPreviews); 23841 23842 // Rich data may be an empty object so test for that. 23843 const hasRichData = richData && Object.keys(richData).length; 23844 const displayURL = value && (0,external_wp_url_namespaceObject.filterURLForDisplay)((0,external_wp_url_namespaceObject.safeDecodeURI)(value.url), 24) || ''; 23845 23846 // url can be undefined if the href attribute is unset 23847 const isEmptyURL = !value?.url?.length; 23848 const displayTitle = !isEmptyURL && (0,external_wp_dom_namespaceObject.__unstableStripHTML)(richData?.title || value?.title || displayURL); 23849 const isUrlRedundant = !value?.url || filterTitleForDisplay(displayTitle) === displayURL; 23850 let icon; 23851 if (richData?.icon) { 23852 icon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("img", { 23853 src: richData?.icon, 23854 alt: "" 23855 }); 23856 } else if (isEmptyURL) { 23857 icon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 23858 icon: library_info, 23859 size: 32 23860 }); 23861 } else { 23862 icon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 23863 icon: library_globe 23864 }); 23865 } 23866 const { 23867 createNotice 23868 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 23869 const ref = (0,external_wp_compose_namespaceObject.useCopyToClipboard)(value.url, () => { 23870 createNotice('info', (0,external_wp_i18n_namespaceObject.__)('Link copied to clipboard.'), { 23871 isDismissible: true, 23872 type: 'snackbar' 23873 }); 23874 }); 23875 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 23876 role: "group", 23877 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Manage link'), 23878 className: dist_clsx('block-editor-link-control__search-item', { 23879 'is-current': true, 23880 'is-rich': hasRichData, 23881 'is-fetching': !!isFetching, 23882 'is-preview': true, 23883 'is-error': isEmptyURL, 23884 'is-url-title': displayTitle === displayURL 23885 }), 23886 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 23887 className: "block-editor-link-control__search-item-top", 23888 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("span", { 23889 className: "block-editor-link-control__search-item-header", 23890 role: "figure", 23891 "aria-label": /* translators: Accessibility text for the link preview when editing a link. */ 23892 (0,external_wp_i18n_namespaceObject.__)('Link information'), 23893 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 23894 className: dist_clsx('block-editor-link-control__search-item-icon', { 23895 'is-image': richData?.icon 23896 }), 23897 children: icon 23898 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 23899 className: "block-editor-link-control__search-item-details", 23900 children: !isEmptyURL ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 23901 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ExternalLink, { 23902 className: "block-editor-link-control__search-item-title", 23903 href: value.url, 23904 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 23905 numberOfLines: 1, 23906 children: displayTitle 23907 }) 23908 }), !isUrlRedundant && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 23909 className: "block-editor-link-control__search-item-info", 23910 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 23911 numberOfLines: 1, 23912 children: displayURL 23913 }) 23914 })] 23915 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 23916 className: "block-editor-link-control__search-item-error-notice", 23917 children: (0,external_wp_i18n_namespaceObject.__)('Link is empty') 23918 }) 23919 })] 23920 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 23921 icon: edit, 23922 label: (0,external_wp_i18n_namespaceObject.__)('Edit link'), 23923 onClick: onEditClick, 23924 size: "compact", 23925 showTooltip: !showIconLabels 23926 }), hasUnlinkControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 23927 icon: link_off, 23928 label: (0,external_wp_i18n_namespaceObject.__)('Remove link'), 23929 onClick: onRemove, 23930 size: "compact", 23931 showTooltip: !showIconLabels 23932 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 23933 icon: copy_small, 23934 label: (0,external_wp_i18n_namespaceObject.__)('Copy link'), 23935 ref: ref, 23936 accessibleWhenDisabled: true, 23937 disabled: isEmptyURL, 23938 size: "compact", 23939 showTooltip: !showIconLabels 23940 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ViewerSlot, { 23941 fillProps: value 23942 })] 23943 }) 23944 }); 23945 } 23946 23947 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/settings.js 23948 /** 23949 * WordPress dependencies 23950 */ 23951 23952 23953 23954 const settings_noop = () => {}; 23955 const LinkControlSettings = ({ 23956 value, 23957 onChange = settings_noop, 23958 settings 23959 }) => { 23960 if (!settings || !settings.length) { 23961 return null; 23962 } 23963 const handleSettingChange = setting => newValue => { 23964 onChange({ 23965 ...value, 23966 [setting.id]: newValue 23967 }); 23968 }; 23969 const theSettings = settings.map(setting => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 23970 __nextHasNoMarginBottom: true, 23971 className: "block-editor-link-control__setting", 23972 label: setting.title, 23973 onChange: handleSettingChange(setting), 23974 checked: value ? !!value[setting.id] : false, 23975 help: setting?.help 23976 }, setting.id)); 23977 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 23978 className: "block-editor-link-control__settings", 23979 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 23980 as: "legend", 23981 children: (0,external_wp_i18n_namespaceObject.__)('Currently selected link settings') 23982 }), theSettings] 23983 }); 23984 }; 23985 /* harmony default export */ const link_control_settings = (LinkControlSettings); 23986 23987 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-create-page.js 23988 /** 23989 * WordPress dependencies 23990 */ 23991 23992 23993 function useCreatePage(handleCreatePage) { 23994 const cancelableCreateSuggestion = (0,external_wp_element_namespaceObject.useRef)(); 23995 const [isCreatingPage, setIsCreatingPage] = (0,external_wp_element_namespaceObject.useState)(false); 23996 const [errorMessage, setErrorMessage] = (0,external_wp_element_namespaceObject.useState)(null); 23997 const createPage = async function (suggestionTitle) { 23998 setIsCreatingPage(true); 23999 setErrorMessage(null); 24000 try { 24001 // Make cancellable in order that we can avoid setting State 24002 // if the component unmounts during the call to `createSuggestion` 24003 cancelableCreateSuggestion.current = makeCancelable( 24004 // Using Promise.resolve to allow createSuggestion to return a 24005 // non-Promise based value. 24006 Promise.resolve(handleCreatePage(suggestionTitle))); 24007 return await cancelableCreateSuggestion.current.promise; 24008 } catch (error) { 24009 if (error && error.isCanceled) { 24010 return; // bail if canceled to avoid setting state 24011 } 24012 setErrorMessage(error.message || (0,external_wp_i18n_namespaceObject.__)('An unknown error occurred during creation. Please try again.')); 24013 throw error; 24014 } finally { 24015 setIsCreatingPage(false); 24016 } 24017 }; 24018 24019 /** 24020 * Handles cancelling any pending Promises that have been made cancelable. 24021 */ 24022 (0,external_wp_element_namespaceObject.useEffect)(() => { 24023 return () => { 24024 // componentDidUnmount 24025 if (cancelableCreateSuggestion.current) { 24026 cancelableCreateSuggestion.current.cancel(); 24027 } 24028 }; 24029 }, []); 24030 return { 24031 createPage, 24032 isCreatingPage, 24033 errorMessage 24034 }; 24035 } 24036 24037 /** 24038 * Creates a wrapper around a promise which allows it to be programmatically 24039 * cancelled. 24040 * See: https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html 24041 * 24042 * @param {Promise} promise the Promise to make cancelable 24043 */ 24044 const makeCancelable = promise => { 24045 let hasCanceled_ = false; 24046 const wrappedPromise = new Promise((resolve, reject) => { 24047 promise.then(val => hasCanceled_ ? reject({ 24048 isCanceled: true 24049 }) : resolve(val), error => hasCanceled_ ? reject({ 24050 isCanceled: true 24051 }) : reject(error)); 24052 }); 24053 return { 24054 promise: wrappedPromise, 24055 cancel() { 24056 hasCanceled_ = true; 24057 } 24058 }; 24059 }; 24060 24061 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/index.js 24062 var fast_deep_equal = __webpack_require__(5215); 24063 var fast_deep_equal_default = /*#__PURE__*/__webpack_require__.n(fast_deep_equal); 24064 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-internal-value.js 24065 /** 24066 * WordPress dependencies 24067 */ 24068 24069 24070 /** 24071 * External dependencies 24072 */ 24073 24074 function useInternalValue(value) { 24075 const [internalValue, setInternalValue] = (0,external_wp_element_namespaceObject.useState)(value || {}); 24076 const [previousValue, setPreviousValue] = (0,external_wp_element_namespaceObject.useState)(value); 24077 24078 // If the value prop changes, update the internal state. 24079 // See: 24080 // - https://github.com/WordPress/gutenberg/pull/51387#issuecomment-1722927384. 24081 // - https://react.dev/reference/react/useState#storing-information-from-previous-renders. 24082 if (!fast_deep_equal_default()(value, previousValue)) { 24083 setPreviousValue(value); 24084 setInternalValue(value); 24085 } 24086 const setInternalURLInputValue = nextValue => { 24087 setInternalValue({ 24088 ...internalValue, 24089 url: nextValue 24090 }); 24091 }; 24092 const setInternalTextInputValue = nextValue => { 24093 setInternalValue({ 24094 ...internalValue, 24095 title: nextValue 24096 }); 24097 }; 24098 const createSetInternalSettingValueHandler = settingsKeys => nextValue => { 24099 // Only apply settings values which are defined in the settings prop. 24100 const settingsUpdates = Object.keys(nextValue).reduce((acc, key) => { 24101 if (settingsKeys.includes(key)) { 24102 acc[key] = nextValue[key]; 24103 } 24104 return acc; 24105 }, {}); 24106 setInternalValue({ 24107 ...internalValue, 24108 ...settingsUpdates 24109 }); 24110 }; 24111 return [internalValue, setInternalValue, setInternalURLInputValue, setInternalTextInputValue, createSetInternalSettingValueHandler]; 24112 } 24113 24114 ;// ./node_modules/@wordpress/block-editor/build-module/components/link-control/index.js 24115 /** 24116 * External dependencies 24117 */ 24118 24119 24120 /** 24121 * WordPress dependencies 24122 */ 24123 24124 24125 24126 24127 24128 24129 24130 24131 24132 24133 /** 24134 * Internal dependencies 24135 */ 24136 24137 24138 24139 24140 24141 24142 24143 24144 24145 24146 /** 24147 * Default properties associated with a link control value. 24148 * 24149 * @typedef WPLinkControlDefaultValue 24150 * 24151 * @property {string} url Link URL. 24152 * @property {string=} title Link title. 24153 * @property {boolean=} opensInNewTab Whether link should open in a new browser 24154 * tab. This value is only assigned if not 24155 * providing a custom `settings` prop. 24156 */ 24157 24158 /* eslint-disable jsdoc/valid-types */ 24159 /** 24160 * Custom settings values associated with a link. 24161 * 24162 * @typedef {{[setting:string]:any}} WPLinkControlSettingsValue 24163 */ 24164 /* eslint-enable */ 24165 24166 /** 24167 * Custom settings values associated with a link. 24168 * 24169 * @typedef WPLinkControlSetting 24170 * 24171 * @property {string} id Identifier to use as property for setting value. 24172 * @property {string} title Human-readable label to show in user interface. 24173 */ 24174 24175 /** 24176 * Properties associated with a link control value, composed as a union of the 24177 * default properties and any custom settings values. 24178 * 24179 * @typedef {WPLinkControlDefaultValue&WPLinkControlSettingsValue} WPLinkControlValue 24180 */ 24181 24182 /** @typedef {(nextValue:WPLinkControlValue)=>void} WPLinkControlOnChangeProp */ 24183 24184 /** 24185 * Properties associated with a search suggestion used within the LinkControl. 24186 * 24187 * @typedef WPLinkControlSuggestion 24188 * 24189 * @property {string} id Identifier to use to uniquely identify the suggestion. 24190 * @property {string} type Identifies the type of the suggestion (eg: `post`, 24191 * `page`, `url`...etc) 24192 * @property {string} title Human-readable label to show in user interface. 24193 * @property {string} url A URL for the suggestion. 24194 */ 24195 24196 /** @typedef {(title:string)=>WPLinkControlSuggestion} WPLinkControlCreateSuggestionProp */ 24197 24198 /** 24199 * @typedef WPLinkControlProps 24200 * 24201 * @property {(WPLinkControlSetting[])=} settings An array of settings objects. Each object will used to 24202 * render a `ToggleControl` for that setting. 24203 * @property {boolean=} forceIsEditingLink If passed as either `true` or `false`, controls the 24204 * internal editing state of the component to respective 24205 * show or not show the URL input field. 24206 * @property {WPLinkControlValue=} value Current link value. 24207 * @property {WPLinkControlOnChangeProp=} onChange Value change handler, called with the updated value if 24208 * the user selects a new link or updates settings. 24209 * @property {boolean=} noDirectEntry Whether to allow turning a URL-like search query directly into a link. 24210 * @property {boolean=} showSuggestions Whether to present suggestions when typing the URL. 24211 * @property {boolean=} showInitialSuggestions Whether to present initial suggestions immediately. 24212 * @property {boolean=} withCreateSuggestion Whether to allow creation of link value from suggestion. 24213 * @property {Object=} suggestionsQuery Query parameters to pass along to wp.blockEditor.__experimentalFetchLinkSuggestions. 24214 * @property {boolean=} noURLSuggestion Whether to add a fallback suggestion which treats the search query as a URL. 24215 * @property {boolean=} hasTextControl Whether to add a text field to the UI to update the value.title. 24216 * @property {string|Function|undefined} createSuggestionButtonText The text to use in the button that calls createSuggestion. 24217 * @property {Function} renderControlBottom Optional controls to be rendered at the bottom of the component. 24218 */ 24219 24220 const link_control_noop = () => {}; 24221 const PREFERENCE_SCOPE = 'core/block-editor'; 24222 const PREFERENCE_KEY = 'linkControlSettingsDrawer'; 24223 24224 /** 24225 * Renders a link control. A link control is a controlled input which maintains 24226 * a value associated with a link (HTML anchor element) and relevant settings 24227 * for how that link is expected to behave. 24228 * 24229 * @param {WPLinkControlProps} props Component props. 24230 */ 24231 function LinkControl({ 24232 searchInputPlaceholder, 24233 value, 24234 settings = DEFAULT_LINK_SETTINGS, 24235 onChange = link_control_noop, 24236 onRemove, 24237 onCancel, 24238 noDirectEntry = false, 24239 showSuggestions = true, 24240 showInitialSuggestions, 24241 forceIsEditingLink, 24242 createSuggestion, 24243 withCreateSuggestion, 24244 inputValue: propInputValue = '', 24245 suggestionsQuery = {}, 24246 noURLSuggestion = false, 24247 createSuggestionButtonText, 24248 hasRichPreviews = false, 24249 hasTextControl = false, 24250 renderControlBottom = null 24251 }) { 24252 if (withCreateSuggestion === undefined && createSuggestion) { 24253 withCreateSuggestion = true; 24254 } 24255 const [settingsOpen, setSettingsOpen] = (0,external_wp_element_namespaceObject.useState)(false); 24256 const { 24257 advancedSettingsPreference 24258 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 24259 var _prefsStore$get; 24260 const prefsStore = select(external_wp_preferences_namespaceObject.store); 24261 return { 24262 advancedSettingsPreference: (_prefsStore$get = prefsStore.get(PREFERENCE_SCOPE, PREFERENCE_KEY)) !== null && _prefsStore$get !== void 0 ? _prefsStore$get : false 24263 }; 24264 }, []); 24265 const { 24266 set: setPreference 24267 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_preferences_namespaceObject.store); 24268 24269 /** 24270 * Sets the open/closed state of the Advanced Settings Drawer, 24271 * optionlly persisting the state to the user's preferences. 24272 * 24273 * Note that Block Editor components can be consumed by non-WordPress 24274 * environments which may not have preferences setup. 24275 * Therefore a local state is also used as a fallback. 24276 * 24277 * @param {boolean} prefVal the open/closed state of the Advanced Settings Drawer. 24278 */ 24279 const setSettingsOpenWithPreference = prefVal => { 24280 if (setPreference) { 24281 setPreference(PREFERENCE_SCOPE, PREFERENCE_KEY, prefVal); 24282 } 24283 setSettingsOpen(prefVal); 24284 }; 24285 24286 // Block Editor components can be consumed by non-WordPress environments 24287 // which may not have these preferences setup. 24288 // Therefore a local state is used as a fallback. 24289 const isSettingsOpen = advancedSettingsPreference || settingsOpen; 24290 const isMountingRef = (0,external_wp_element_namespaceObject.useRef)(true); 24291 const wrapperNode = (0,external_wp_element_namespaceObject.useRef)(); 24292 const textInputRef = (0,external_wp_element_namespaceObject.useRef)(); 24293 const isEndingEditWithFocusRef = (0,external_wp_element_namespaceObject.useRef)(false); 24294 const settingsKeys = settings.map(({ 24295 id 24296 }) => id); 24297 const [internalControlValue, setInternalControlValue, setInternalURLInputValue, setInternalTextInputValue, createSetInternalSettingValueHandler] = useInternalValue(value); 24298 const valueHasChanges = value && !(0,external_wp_isShallowEqual_namespaceObject.isShallowEqualObjects)(internalControlValue, value); 24299 const [isEditingLink, setIsEditingLink] = (0,external_wp_element_namespaceObject.useState)(forceIsEditingLink !== undefined ? forceIsEditingLink : !value || !value.url); 24300 const { 24301 createPage, 24302 isCreatingPage, 24303 errorMessage 24304 } = useCreatePage(createSuggestion); 24305 (0,external_wp_element_namespaceObject.useEffect)(() => { 24306 if (forceIsEditingLink === undefined) { 24307 return; 24308 } 24309 setIsEditingLink(forceIsEditingLink); 24310 }, [forceIsEditingLink]); 24311 (0,external_wp_element_namespaceObject.useEffect)(() => { 24312 // We don't auto focus into the Link UI on mount 24313 // because otherwise using the keyboard to select text 24314 // *within* the link format is not possible. 24315 if (isMountingRef.current) { 24316 return; 24317 } 24318 24319 // Scenario - when: 24320 // - switching between editable and non editable LinkControl 24321 // - clicking on a link 24322 // ...then move focus to the *first* element to avoid focus loss 24323 // and to ensure focus is *within* the Link UI. 24324 const nextFocusTarget = external_wp_dom_namespaceObject.focus.focusable.find(wrapperNode.current)[0] || wrapperNode.current; 24325 nextFocusTarget.focus(); 24326 isEndingEditWithFocusRef.current = false; 24327 }, [isEditingLink, isCreatingPage]); 24328 24329 // The component mounting reference is maintained separately 24330 // to correctly reset values in `StrictMode`. 24331 (0,external_wp_element_namespaceObject.useEffect)(() => { 24332 isMountingRef.current = false; 24333 return () => { 24334 isMountingRef.current = true; 24335 }; 24336 }, []); 24337 const hasLinkValue = value?.url?.trim()?.length > 0; 24338 24339 /** 24340 * Cancels editing state and marks that focus may need to be restored after 24341 * the next render, if focus was within the wrapper when editing finished. 24342 */ 24343 const stopEditing = () => { 24344 isEndingEditWithFocusRef.current = !!wrapperNode.current?.contains(wrapperNode.current.ownerDocument.activeElement); 24345 setIsEditingLink(false); 24346 }; 24347 const handleSelectSuggestion = updatedValue => { 24348 // Suggestions may contains "settings" values (e.g. `opensInNewTab`) 24349 // which should not override any existing settings values set by the 24350 // user. This filters out any settings values from the suggestion. 24351 const nonSettingsChanges = Object.keys(updatedValue).reduce((acc, key) => { 24352 if (!settingsKeys.includes(key)) { 24353 acc[key] = updatedValue[key]; 24354 } 24355 return acc; 24356 }, {}); 24357 onChange({ 24358 ...internalControlValue, 24359 ...nonSettingsChanges, 24360 // As title is not a setting, it must be manually applied 24361 // in such a way as to preserve the users changes over 24362 // any "title" value provided by the "suggestion". 24363 title: internalControlValue?.title || updatedValue?.title 24364 }); 24365 stopEditing(); 24366 }; 24367 const handleSubmit = () => { 24368 if (valueHasChanges) { 24369 // Submit the original value with new stored values applied 24370 // on top. URL is a special case as it may also be a prop. 24371 onChange({ 24372 ...value, 24373 ...internalControlValue, 24374 url: currentUrlInputValue 24375 }); 24376 } 24377 stopEditing(); 24378 }; 24379 const handleSubmitWithEnter = event => { 24380 const { 24381 keyCode 24382 } = event; 24383 if (keyCode === external_wp_keycodes_namespaceObject.ENTER && !currentInputIsEmpty // Disallow submitting empty values. 24384 ) { 24385 event.preventDefault(); 24386 handleSubmit(); 24387 } 24388 }; 24389 const resetInternalValues = () => { 24390 setInternalControlValue(value); 24391 }; 24392 const handleCancel = event => { 24393 event.preventDefault(); 24394 event.stopPropagation(); 24395 24396 // Ensure that any unsubmitted input changes are reset. 24397 resetInternalValues(); 24398 if (hasLinkValue) { 24399 // If there is a link then exist editing mode and show preview. 24400 stopEditing(); 24401 } else { 24402 // If there is no link value, then remove the link entirely. 24403 onRemove?.(); 24404 } 24405 onCancel?.(); 24406 }; 24407 const currentUrlInputValue = propInputValue || internalControlValue?.url || ''; 24408 const currentInputIsEmpty = !currentUrlInputValue?.trim()?.length; 24409 const shownUnlinkControl = onRemove && value && !isEditingLink && !isCreatingPage; 24410 const showActions = isEditingLink && hasLinkValue; 24411 24412 // Only show text control once a URL value has been committed 24413 // and it isn't just empty whitespace. 24414 // See https://github.com/WordPress/gutenberg/pull/33849/#issuecomment-932194927. 24415 const showTextControl = hasLinkValue && hasTextControl; 24416 const isEditing = (isEditingLink || !value) && !isCreatingPage; 24417 const isDisabled = !valueHasChanges || currentInputIsEmpty; 24418 const showSettings = !!settings?.length && isEditingLink && hasLinkValue; 24419 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 24420 tabIndex: -1, 24421 ref: wrapperNode, 24422 className: "block-editor-link-control", 24423 children: [isCreatingPage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 24424 className: "block-editor-link-control__loading", 24425 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Spinner, {}), " ", (0,external_wp_i18n_namespaceObject.__)('Creating'), "\u2026"] 24426 }), isEditing && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 24427 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 24428 className: dist_clsx({ 24429 'block-editor-link-control__search-input-wrapper': true, 24430 'has-text-control': showTextControl, 24431 'has-actions': showActions 24432 }), 24433 children: [showTextControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 24434 __nextHasNoMarginBottom: true, 24435 ref: textInputRef, 24436 className: "block-editor-link-control__field block-editor-link-control__text-content", 24437 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 24438 value: internalControlValue?.title, 24439 onChange: setInternalTextInputValue, 24440 onKeyDown: handleSubmitWithEnter, 24441 __next40pxDefaultSize: true 24442 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(search_input, { 24443 currentLink: value, 24444 className: "block-editor-link-control__field block-editor-link-control__search-input", 24445 placeholder: searchInputPlaceholder, 24446 value: currentUrlInputValue, 24447 withCreateSuggestion: withCreateSuggestion, 24448 onCreateSuggestion: createPage, 24449 onChange: setInternalURLInputValue, 24450 onSelect: handleSelectSuggestion, 24451 showInitialSuggestions: showInitialSuggestions, 24452 allowDirectEntry: !noDirectEntry, 24453 showSuggestions: showSuggestions, 24454 suggestionsQuery: suggestionsQuery, 24455 withURLSuggestion: !noURLSuggestion, 24456 createSuggestionButtonText: createSuggestionButtonText, 24457 hideLabelFromVision: !showTextControl, 24458 suffix: showActions ? undefined : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlSuffixWrapper, { 24459 variant: "control", 24460 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 24461 onClick: isDisabled ? link_control_noop : handleSubmit, 24462 label: (0,external_wp_i18n_namespaceObject.__)('Submit'), 24463 icon: keyboard_return, 24464 className: "block-editor-link-control__search-submit", 24465 "aria-disabled": isDisabled, 24466 size: "small" 24467 }) 24468 }) 24469 })] 24470 }), errorMessage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Notice, { 24471 className: "block-editor-link-control__search-error", 24472 status: "error", 24473 isDismissible: false, 24474 children: errorMessage 24475 })] 24476 }), value && !isEditingLink && !isCreatingPage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkPreview, { 24477 // force remount when URL changes to avoid race conditions for rich previews 24478 value: value, 24479 onEditClick: () => setIsEditingLink(true), 24480 hasRichPreviews: hasRichPreviews, 24481 hasUnlinkControl: shownUnlinkControl, 24482 onRemove: () => { 24483 onRemove(); 24484 setIsEditingLink(true); 24485 } 24486 }, value?.url), showSettings && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 24487 className: "block-editor-link-control__tools", 24488 children: !currentInputIsEmpty && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(settings_drawer, { 24489 settingsOpen: isSettingsOpen, 24490 setSettingsOpen: setSettingsOpenWithPreference, 24491 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(link_control_settings, { 24492 value: internalControlValue, 24493 settings: settings, 24494 onChange: createSetInternalSettingValueHandler(settingsKeys) 24495 }) 24496 }) 24497 }), showActions && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 24498 justify: "right", 24499 className: "block-editor-link-control__search-actions", 24500 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 24501 __next40pxDefaultSize: true, 24502 variant: "tertiary", 24503 onClick: handleCancel, 24504 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 24505 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 24506 __next40pxDefaultSize: true, 24507 variant: "primary", 24508 onClick: isDisabled ? link_control_noop : handleSubmit, 24509 className: "block-editor-link-control__search-submit", 24510 "aria-disabled": isDisabled, 24511 children: (0,external_wp_i18n_namespaceObject.__)('Save') 24512 })] 24513 }), !isCreatingPage && renderControlBottom && renderControlBottom()] 24514 }); 24515 } 24516 LinkControl.ViewerFill = ViewerFill; 24517 LinkControl.DEFAULT_LINK_SETTINGS = DEFAULT_LINK_SETTINGS; 24518 const DeprecatedExperimentalLinkControl = props => { 24519 external_wp_deprecated_default()('wp.blockEditor.__experimentalLinkControl', { 24520 since: '6.8', 24521 alternative: 'wp.blockEditor.LinkControl' 24522 }); 24523 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkControl, { 24524 ...props 24525 }); 24526 }; 24527 DeprecatedExperimentalLinkControl.ViewerFill = LinkControl.ViewerFill; 24528 DeprecatedExperimentalLinkControl.DEFAULT_LINK_SETTINGS = LinkControl.DEFAULT_LINK_SETTINGS; 24529 24530 /* harmony default export */ const link_control = (LinkControl); 24531 24532 ;// ./node_modules/@wordpress/block-editor/build-module/components/media-replace-flow/index.js 24533 /** 24534 * WordPress dependencies 24535 */ 24536 24537 24538 24539 24540 24541 24542 24543 24544 24545 24546 /** 24547 * Internal dependencies 24548 */ 24549 24550 24551 24552 24553 24554 const media_replace_flow_noop = () => {}; 24555 let uniqueId = 0; 24556 const MediaReplaceFlow = ({ 24557 mediaURL, 24558 mediaId, 24559 mediaIds, 24560 allowedTypes, 24561 accept, 24562 onError, 24563 onSelect, 24564 onSelectURL, 24565 onReset, 24566 onToggleFeaturedImage, 24567 useFeaturedImage, 24568 onFilesUpload = media_replace_flow_noop, 24569 name = (0,external_wp_i18n_namespaceObject.__)('Replace'), 24570 createNotice, 24571 removeNotice, 24572 children, 24573 multiple = false, 24574 addToGallery, 24575 handleUpload = true, 24576 popoverProps, 24577 renderToggle 24578 }) => { 24579 const { 24580 getSettings 24581 } = (0,external_wp_data_namespaceObject.useSelect)(store); 24582 const errorNoticeID = `block-editor/media-replace-flow/error-notice/${++uniqueId}`; 24583 const onUploadError = message => { 24584 const safeMessage = (0,external_wp_dom_namespaceObject.__unstableStripHTML)(message); 24585 if (onError) { 24586 onError(safeMessage); 24587 return; 24588 } 24589 // We need to set a timeout for showing the notice 24590 // so that VoiceOver and possibly other screen readers 24591 // can announce the error after the toolbar button 24592 // regains focus once the upload dialog closes. 24593 // Otherwise VO simply skips over the notice and announces 24594 // the focused element and the open menu. 24595 setTimeout(() => { 24596 createNotice('error', safeMessage, { 24597 speak: true, 24598 id: errorNoticeID, 24599 isDismissible: true 24600 }); 24601 }, 1000); 24602 }; 24603 const selectMedia = (media, closeMenu) => { 24604 if (useFeaturedImage && onToggleFeaturedImage) { 24605 onToggleFeaturedImage(); 24606 } 24607 closeMenu(); 24608 // Calling `onSelect` after the state update since it might unmount the component. 24609 onSelect(media); 24610 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('The media file has been replaced')); 24611 removeNotice(errorNoticeID); 24612 }; 24613 const uploadFiles = (event, closeMenu) => { 24614 const files = event.target.files; 24615 if (!handleUpload) { 24616 closeMenu(); 24617 return onSelect(files); 24618 } 24619 onFilesUpload(files); 24620 getSettings().mediaUpload({ 24621 allowedTypes, 24622 filesList: files, 24623 onFileChange: ([media]) => { 24624 selectMedia(media, closeMenu); 24625 }, 24626 onError: onUploadError 24627 }); 24628 }; 24629 const openOnArrowDown = event => { 24630 if (event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 24631 event.preventDefault(); 24632 event.target.click(); 24633 } 24634 }; 24635 const onlyAllowsImages = () => { 24636 if (!allowedTypes || allowedTypes.length === 0) { 24637 return false; 24638 } 24639 return allowedTypes.every(allowedType => allowedType === 'image' || allowedType.startsWith('image/')); 24640 }; 24641 const gallery = multiple && onlyAllowsImages(); 24642 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 24643 popoverProps: popoverProps, 24644 contentClassName: "block-editor-media-replace-flow__options", 24645 renderToggle: ({ 24646 isOpen, 24647 onToggle 24648 }) => { 24649 if (renderToggle) { 24650 return renderToggle({ 24651 'aria-expanded': isOpen, 24652 'aria-haspopup': 'true', 24653 onClick: onToggle, 24654 onKeyDown: openOnArrowDown, 24655 children: name 24656 }); 24657 } 24658 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 24659 "aria-expanded": isOpen, 24660 "aria-haspopup": "true", 24661 onClick: onToggle, 24662 onKeyDown: openOnArrowDown, 24663 children: name 24664 }); 24665 }, 24666 renderContent: ({ 24667 onClose 24668 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 24669 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.NavigableMenu, { 24670 className: "block-editor-media-replace-flow__media-upload-menu", 24671 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(check, { 24672 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(media_upload, { 24673 gallery: gallery, 24674 addToGallery: addToGallery, 24675 multiple: multiple, 24676 value: multiple ? mediaIds : mediaId, 24677 onSelect: media => selectMedia(media, onClose), 24678 allowedTypes: allowedTypes, 24679 render: ({ 24680 open 24681 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 24682 icon: library_media, 24683 onClick: open, 24684 children: (0,external_wp_i18n_namespaceObject.__)('Open Media Library') 24685 }) 24686 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FormFileUpload, { 24687 onChange: event => { 24688 uploadFiles(event, onClose); 24689 }, 24690 accept: accept, 24691 multiple: !!multiple, 24692 render: ({ 24693 openFileDialog 24694 }) => { 24695 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 24696 icon: library_upload, 24697 onClick: () => { 24698 openFileDialog(); 24699 }, 24700 children: (0,external_wp_i18n_namespaceObject._x)('Upload', 'verb') 24701 }); 24702 } 24703 })] 24704 }), onToggleFeaturedImage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 24705 icon: post_featured_image, 24706 onClick: onToggleFeaturedImage, 24707 isPressed: useFeaturedImage, 24708 children: (0,external_wp_i18n_namespaceObject.__)('Use featured image') 24709 }), mediaURL && onReset && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 24710 onClick: () => { 24711 onReset(); 24712 onClose(); 24713 }, 24714 children: (0,external_wp_i18n_namespaceObject.__)('Reset') 24715 }), typeof children === 'function' ? children({ 24716 onClose 24717 }) : children] 24718 }), onSelectURL && 24719 /*#__PURE__*/ 24720 // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions 24721 (0,external_ReactJSXRuntime_namespaceObject.jsxs)("form", { 24722 className: "block-editor-media-flow__url-input", 24723 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 24724 className: "block-editor-media-replace-flow__image-url-label", 24725 children: (0,external_wp_i18n_namespaceObject.__)('Current media URL:') 24726 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(link_control, { 24727 value: { 24728 url: mediaURL 24729 }, 24730 settings: [], 24731 showSuggestions: false, 24732 onChange: ({ 24733 url 24734 }) => { 24735 onSelectURL(url); 24736 } 24737 })] 24738 })] 24739 }) 24740 }); 24741 }; 24742 24743 /** 24744 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-replace-flow/README.md 24745 */ 24746 /* harmony default export */ const media_replace_flow = ((0,external_wp_compose_namespaceObject.compose)([(0,external_wp_data_namespaceObject.withDispatch)(dispatch => { 24747 const { 24748 createNotice, 24749 removeNotice 24750 } = dispatch(external_wp_notices_namespaceObject.store); 24751 return { 24752 createNotice, 24753 removeNotice 24754 }; 24755 }), (0,external_wp_components_namespaceObject.withFilters)('editor.MediaReplaceFlow')])(MediaReplaceFlow)); 24756 24757 ;// ./node_modules/@wordpress/block-editor/build-module/components/background-image-control/index.js 24758 /** 24759 * External dependencies 24760 */ 24761 24762 24763 /** 24764 * WordPress dependencies 24765 */ 24766 24767 24768 24769 24770 24771 24772 24773 24774 24775 /** 24776 * Internal dependencies 24777 */ 24778 24779 24780 24781 24782 24783 24784 24785 const IMAGE_BACKGROUND_TYPE = 'image'; 24786 const BACKGROUND_POPOVER_PROPS = { 24787 placement: 'left-start', 24788 offset: 36, 24789 shift: true, 24790 className: 'block-editor-global-styles-background-panel__popover' 24791 }; 24792 const background_image_control_noop = () => {}; 24793 24794 /** 24795 * Get the help text for the background size control. 24796 * 24797 * @param {string} value backgroundSize value. 24798 * @return {string} Translated help text. 24799 */ 24800 function backgroundSizeHelpText(value) { 24801 if (value === 'cover' || value === undefined) { 24802 return (0,external_wp_i18n_namespaceObject.__)('Image covers the space evenly.'); 24803 } 24804 if (value === 'contain') { 24805 return (0,external_wp_i18n_namespaceObject.__)('Image is contained without distortion.'); 24806 } 24807 return (0,external_wp_i18n_namespaceObject.__)('Image has a fixed width.'); 24808 } 24809 24810 /** 24811 * Converts decimal x and y coords from FocalPointPicker to percentage-based values 24812 * to use as backgroundPosition value. 24813 * 24814 * @param {{x?:number, y?:number}} value FocalPointPicker coords. 24815 * @return {string} backgroundPosition value. 24816 */ 24817 const coordsToBackgroundPosition = value => { 24818 if (!value || isNaN(value.x) && isNaN(value.y)) { 24819 return undefined; 24820 } 24821 const x = isNaN(value.x) ? 0.5 : value.x; 24822 const y = isNaN(value.y) ? 0.5 : value.y; 24823 return `$x * 100}% $y * 100}%`; 24824 }; 24825 24826 /** 24827 * Converts backgroundPosition value to x and y coords for FocalPointPicker. 24828 * 24829 * @param {string} value backgroundPosition value. 24830 * @return {{x?:number, y?:number}} FocalPointPicker coords. 24831 */ 24832 const backgroundPositionToCoords = value => { 24833 if (!value) { 24834 return { 24835 x: undefined, 24836 y: undefined 24837 }; 24838 } 24839 let [x, y] = value.split(' ').map(v => parseFloat(v) / 100); 24840 x = isNaN(x) ? undefined : x; 24841 y = isNaN(y) ? x : y; 24842 return { 24843 x, 24844 y 24845 }; 24846 }; 24847 function InspectorImagePreviewItem({ 24848 as = 'span', 24849 imgUrl, 24850 toggleProps = {}, 24851 filename, 24852 label, 24853 className, 24854 onToggleCallback = background_image_control_noop 24855 }) { 24856 (0,external_wp_element_namespaceObject.useEffect)(() => { 24857 if (typeof toggleProps?.isOpen !== 'undefined') { 24858 onToggleCallback(toggleProps?.isOpen); 24859 } 24860 }, [toggleProps?.isOpen, onToggleCallback]); 24861 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalItemGroup, { 24862 as: as, 24863 className: className, 24864 ...toggleProps, 24865 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 24866 justify: "flex-start", 24867 as: "span", 24868 className: "block-editor-global-styles-background-panel__inspector-preview-inner", 24869 children: [imgUrl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 24870 className: "block-editor-global-styles-background-panel__inspector-image-indicator-wrapper", 24871 "aria-hidden": true, 24872 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 24873 className: "block-editor-global-styles-background-panel__inspector-image-indicator", 24874 style: { 24875 backgroundImage: `url($imgUrl})` 24876 } 24877 }) 24878 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.FlexItem, { 24879 as: "span", 24880 style: imgUrl ? {} : { 24881 flexGrow: 1 24882 }, 24883 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 24884 numberOfLines: 1, 24885 className: "block-editor-global-styles-background-panel__inspector-media-replace-title", 24886 children: label 24887 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 24888 as: "span", 24889 children: imgUrl ? (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: file name */ 24890 (0,external_wp_i18n_namespaceObject.__)('Background image: %s'), filename || label) : (0,external_wp_i18n_namespaceObject.__)('No background image selected') 24891 })] 24892 })] 24893 }) 24894 }); 24895 } 24896 function BackgroundControlsPanel({ 24897 label, 24898 filename, 24899 url: imgUrl, 24900 children, 24901 onToggle: onToggleCallback = background_image_control_noop, 24902 hasImageValue 24903 }) { 24904 if (!hasImageValue) { 24905 return; 24906 } 24907 const imgLabel = label || (0,external_wp_url_namespaceObject.getFilename)(imgUrl) || (0,external_wp_i18n_namespaceObject.__)('Add background image'); 24908 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 24909 popoverProps: BACKGROUND_POPOVER_PROPS, 24910 renderToggle: ({ 24911 onToggle, 24912 isOpen 24913 }) => { 24914 const toggleProps = { 24915 onClick: onToggle, 24916 className: 'block-editor-global-styles-background-panel__dropdown-toggle', 24917 'aria-expanded': isOpen, 24918 'aria-label': (0,external_wp_i18n_namespaceObject.__)('Background size, position and repeat options.'), 24919 isOpen 24920 }; 24921 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorImagePreviewItem, { 24922 imgUrl: imgUrl, 24923 filename: filename, 24924 label: imgLabel, 24925 toggleProps: toggleProps, 24926 as: "button", 24927 onToggleCallback: onToggleCallback 24928 }); 24929 }, 24930 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 24931 className: "block-editor-global-styles-background-panel__dropdown-content-wrapper", 24932 paddingSize: "medium", 24933 children: children 24934 }) 24935 }); 24936 } 24937 function LoadingSpinner() { 24938 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Placeholder, { 24939 className: "block-editor-global-styles-background-panel__loading", 24940 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Spinner, {}) 24941 }); 24942 } 24943 function BackgroundImageControls({ 24944 onChange, 24945 style, 24946 inheritedValue, 24947 onRemoveImage = background_image_control_noop, 24948 onResetImage = background_image_control_noop, 24949 displayInPanel, 24950 defaultValues 24951 }) { 24952 const [isUploading, setIsUploading] = (0,external_wp_element_namespaceObject.useState)(false); 24953 const { 24954 getSettings 24955 } = (0,external_wp_data_namespaceObject.useSelect)(store); 24956 const { 24957 id, 24958 title, 24959 url 24960 } = style?.background?.backgroundImage || { 24961 ...inheritedValue?.background?.backgroundImage 24962 }; 24963 const replaceContainerRef = (0,external_wp_element_namespaceObject.useRef)(); 24964 const { 24965 createErrorNotice 24966 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 24967 const onUploadError = message => { 24968 createErrorNotice(message, { 24969 type: 'snackbar' 24970 }); 24971 setIsUploading(false); 24972 }; 24973 const resetBackgroundImage = () => onChange(setImmutably(style, ['background', 'backgroundImage'], undefined)); 24974 const onSelectMedia = media => { 24975 if (!media || !media.url) { 24976 resetBackgroundImage(); 24977 setIsUploading(false); 24978 return; 24979 } 24980 if ((0,external_wp_blob_namespaceObject.isBlobURL)(media.url)) { 24981 setIsUploading(true); 24982 return; 24983 } 24984 24985 // For media selections originated from a file upload. 24986 if (media.media_type && media.media_type !== IMAGE_BACKGROUND_TYPE || !media.media_type && media.type && media.type !== IMAGE_BACKGROUND_TYPE) { 24987 onUploadError((0,external_wp_i18n_namespaceObject.__)('Only images can be used as a background image.')); 24988 return; 24989 } 24990 const sizeValue = style?.background?.backgroundSize || defaultValues?.backgroundSize; 24991 const positionValue = style?.background?.backgroundPosition; 24992 onChange(setImmutably(style, ['background'], { 24993 ...style?.background, 24994 backgroundImage: { 24995 url: media.url, 24996 id: media.id, 24997 source: 'file', 24998 title: media.title || undefined 24999 }, 25000 backgroundPosition: 25001 /* 25002 * A background image uploaded and set in the editor receives a default background position of '50% 0', 25003 * when the background image size is the equivalent of "Tile". 25004 * This is to increase the chance that the image's focus point is visible. 25005 * This is in-editor only to assist with the user experience. 25006 */ 25007 !positionValue && ('auto' === sizeValue || !sizeValue) ? '50% 0' : positionValue, 25008 backgroundSize: sizeValue 25009 })); 25010 setIsUploading(false); 25011 }; 25012 25013 // Drag and drop callback, restricting image to one. 25014 const onFilesDrop = filesList => { 25015 getSettings().mediaUpload({ 25016 allowedTypes: [IMAGE_BACKGROUND_TYPE], 25017 filesList, 25018 onFileChange([image]) { 25019 onSelectMedia(image); 25020 }, 25021 onError: onUploadError, 25022 multiple: false 25023 }); 25024 }; 25025 const hasValue = hasBackgroundImageValue(style); 25026 const closeAndFocus = () => { 25027 const [toggleButton] = external_wp_dom_namespaceObject.focus.tabbable.find(replaceContainerRef.current); 25028 // Focus the toggle button and close the dropdown menu. 25029 // This ensures similar behaviour as to selecting an image, where the dropdown is 25030 // closed and focus is redirected to the dropdown toggle button. 25031 toggleButton?.focus(); 25032 toggleButton?.click(); 25033 }; 25034 const onRemove = () => onChange(setImmutably(style, ['background'], { 25035 backgroundImage: 'none' 25036 })); 25037 const canRemove = !hasValue && hasBackgroundImageValue(inheritedValue); 25038 const imgLabel = title || (0,external_wp_url_namespaceObject.getFilename)(url) || (0,external_wp_i18n_namespaceObject.__)('Add background image'); 25039 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 25040 ref: replaceContainerRef, 25041 className: "block-editor-global-styles-background-panel__image-tools-panel-item", 25042 children: [isUploading && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LoadingSpinner, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(media_replace_flow, { 25043 mediaId: id, 25044 mediaURL: url, 25045 allowedTypes: [IMAGE_BACKGROUND_TYPE], 25046 accept: "image/*", 25047 onSelect: onSelectMedia, 25048 popoverProps: { 25049 className: dist_clsx({ 25050 'block-editor-global-styles-background-panel__media-replace-popover': displayInPanel 25051 }) 25052 }, 25053 name: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorImagePreviewItem, { 25054 className: "block-editor-global-styles-background-panel__image-preview", 25055 imgUrl: url, 25056 filename: title, 25057 label: imgLabel 25058 }), 25059 renderToggle: props => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 25060 ...props, 25061 __next40pxDefaultSize: true 25062 }), 25063 onError: onUploadError, 25064 onReset: () => { 25065 closeAndFocus(); 25066 onResetImage(); 25067 }, 25068 children: canRemove && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 25069 onClick: () => { 25070 closeAndFocus(); 25071 onRemove(); 25072 onRemoveImage(); 25073 }, 25074 children: (0,external_wp_i18n_namespaceObject.__)('Remove') 25075 }) 25076 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropZone, { 25077 onFilesDrop: onFilesDrop, 25078 label: (0,external_wp_i18n_namespaceObject.__)('Drop to upload') 25079 })] 25080 }); 25081 } 25082 function BackgroundSizeControls({ 25083 onChange, 25084 style, 25085 inheritedValue, 25086 defaultValues 25087 }) { 25088 const sizeValue = style?.background?.backgroundSize || inheritedValue?.background?.backgroundSize; 25089 const repeatValue = style?.background?.backgroundRepeat || inheritedValue?.background?.backgroundRepeat; 25090 const imageValue = style?.background?.backgroundImage?.url || inheritedValue?.background?.backgroundImage?.url; 25091 const isUploadedImage = style?.background?.backgroundImage?.id; 25092 const positionValue = style?.background?.backgroundPosition || inheritedValue?.background?.backgroundPosition; 25093 const attachmentValue = style?.background?.backgroundAttachment || inheritedValue?.background?.backgroundAttachment; 25094 25095 /* 25096 * Set default values for uploaded images. 25097 * The default values are passed by the consumer. 25098 * Block-level controls may have different defaults to root-level controls. 25099 * A falsy value is treated by default as `auto` (Tile). 25100 */ 25101 let currentValueForToggle = !sizeValue && isUploadedImage ? defaultValues?.backgroundSize : sizeValue || 'auto'; 25102 /* 25103 * The incoming value could be a value + unit, e.g. '20px'. 25104 * In this case set the value to 'tile'. 25105 */ 25106 currentValueForToggle = !['cover', 'contain', 'auto'].includes(currentValueForToggle) ? 'auto' : currentValueForToggle; 25107 /* 25108 * If the current value is `cover` and the repeat value is `undefined`, then 25109 * the toggle should be unchecked as the default state. Otherwise, the toggle 25110 * should reflect the current repeat value. 25111 */ 25112 const repeatCheckedValue = !(repeatValue === 'no-repeat' || currentValueForToggle === 'cover' && repeatValue === undefined); 25113 const updateBackgroundSize = next => { 25114 // When switching to 'contain' toggle the repeat off. 25115 let nextRepeat = repeatValue; 25116 let nextPosition = positionValue; 25117 if (next === 'contain') { 25118 nextRepeat = 'no-repeat'; 25119 nextPosition = undefined; 25120 } 25121 if (next === 'cover') { 25122 nextRepeat = undefined; 25123 nextPosition = undefined; 25124 } 25125 if ((currentValueForToggle === 'cover' || currentValueForToggle === 'contain') && next === 'auto') { 25126 nextRepeat = undefined; 25127 /* 25128 * A background image uploaded and set in the editor (an image with a record id), 25129 * receives a default background position of '50% 0', 25130 * when the toggle switches to "Tile". This is to increase the chance that 25131 * the image's focus point is visible. 25132 * This is in-editor only to assist with the user experience. 25133 */ 25134 if (!!style?.background?.backgroundImage?.id) { 25135 nextPosition = '50% 0'; 25136 } 25137 } 25138 25139 /* 25140 * Next will be null when the input is cleared, 25141 * in which case the value should be 'auto'. 25142 */ 25143 if (!next && currentValueForToggle === 'auto') { 25144 next = 'auto'; 25145 } 25146 onChange(setImmutably(style, ['background'], { 25147 ...style?.background, 25148 backgroundPosition: nextPosition, 25149 backgroundRepeat: nextRepeat, 25150 backgroundSize: next 25151 })); 25152 }; 25153 const updateBackgroundPosition = next => { 25154 onChange(setImmutably(style, ['background', 'backgroundPosition'], coordsToBackgroundPosition(next))); 25155 }; 25156 const toggleIsRepeated = () => onChange(setImmutably(style, ['background', 'backgroundRepeat'], repeatCheckedValue === true ? 'no-repeat' : 'repeat')); 25157 const toggleScrollWithPage = () => onChange(setImmutably(style, ['background', 'backgroundAttachment'], attachmentValue === 'fixed' ? 'scroll' : 'fixed')); 25158 25159 // Set a default background position for non-site-wide, uploaded images with a size of 'contain'. 25160 const backgroundPositionValue = !positionValue && isUploadedImage && 'contain' === sizeValue ? defaultValues?.backgroundPosition : positionValue; 25161 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 25162 spacing: 3, 25163 className: "single-column", 25164 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FocalPointPicker, { 25165 __nextHasNoMarginBottom: true, 25166 label: (0,external_wp_i18n_namespaceObject.__)('Focal point'), 25167 url: imageValue, 25168 value: backgroundPositionToCoords(backgroundPositionValue), 25169 onChange: updateBackgroundPosition 25170 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 25171 __nextHasNoMarginBottom: true, 25172 label: (0,external_wp_i18n_namespaceObject.__)('Fixed background'), 25173 checked: attachmentValue === 'fixed', 25174 onChange: toggleScrollWithPage 25175 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 25176 __nextHasNoMarginBottom: true, 25177 size: "__unstable-large", 25178 label: (0,external_wp_i18n_namespaceObject.__)('Size'), 25179 value: currentValueForToggle, 25180 onChange: updateBackgroundSize, 25181 isBlock: true, 25182 help: backgroundSizeHelpText(sizeValue || defaultValues?.backgroundSize), 25183 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 25184 value: "cover", 25185 label: (0,external_wp_i18n_namespaceObject._x)('Cover', 'Size option for background image control') 25186 }, "cover"), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 25187 value: "contain", 25188 label: (0,external_wp_i18n_namespaceObject._x)('Contain', 'Size option for background image control') 25189 }, "contain"), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 25190 value: "auto", 25191 label: (0,external_wp_i18n_namespaceObject._x)('Tile', 'Size option for background image control') 25192 }, "tile")] 25193 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 25194 justify: "flex-start", 25195 spacing: 2, 25196 as: "span", 25197 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 25198 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Background image width'), 25199 onChange: updateBackgroundSize, 25200 value: sizeValue, 25201 size: "__unstable-large", 25202 __unstableInputWidth: "100px", 25203 min: 0, 25204 placeholder: (0,external_wp_i18n_namespaceObject.__)('Auto'), 25205 disabled: currentValueForToggle !== 'auto' || currentValueForToggle === undefined 25206 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 25207 __nextHasNoMarginBottom: true, 25208 label: (0,external_wp_i18n_namespaceObject.__)('Repeat'), 25209 checked: repeatCheckedValue, 25210 onChange: toggleIsRepeated, 25211 disabled: currentValueForToggle === 'cover' 25212 })] 25213 })] 25214 }); 25215 } 25216 function BackgroundImagePanel({ 25217 value, 25218 onChange, 25219 inheritedValue = value, 25220 settings, 25221 defaultValues = {} 25222 }) { 25223 /* 25224 * Resolve any inherited "ref" pointers. 25225 * Should the block editor need resolved, inherited values 25226 * across all controls, this could be abstracted into a hook, 25227 * e.g., useResolveGlobalStyle 25228 */ 25229 const { 25230 globalStyles, 25231 _links 25232 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 25233 const { 25234 getSettings 25235 } = select(store); 25236 const _settings = getSettings(); 25237 return { 25238 globalStyles: _settings[globalStylesDataKey], 25239 _links: _settings[globalStylesLinksDataKey] 25240 }; 25241 }, []); 25242 const resolvedInheritedValue = (0,external_wp_element_namespaceObject.useMemo)(() => { 25243 const resolvedValues = { 25244 background: {} 25245 }; 25246 if (!inheritedValue?.background) { 25247 return inheritedValue; 25248 } 25249 Object.entries(inheritedValue?.background).forEach(([key, backgroundValue]) => { 25250 resolvedValues.background[key] = getResolvedValue(backgroundValue, { 25251 styles: globalStyles, 25252 _links 25253 }); 25254 }); 25255 return resolvedValues; 25256 }, [globalStyles, _links, inheritedValue]); 25257 const resetBackground = () => onChange(setImmutably(value, ['background'], {})); 25258 const { 25259 title, 25260 url 25261 } = value?.background?.backgroundImage || { 25262 ...resolvedInheritedValue?.background?.backgroundImage 25263 }; 25264 const hasImageValue = hasBackgroundImageValue(value) || hasBackgroundImageValue(resolvedInheritedValue); 25265 const imageValue = value?.background?.backgroundImage || inheritedValue?.background?.backgroundImage; 25266 const shouldShowBackgroundImageControls = hasImageValue && 'none' !== imageValue && (settings?.background?.backgroundSize || settings?.background?.backgroundPosition || settings?.background?.backgroundRepeat); 25267 const [isDropDownOpen, setIsDropDownOpen] = (0,external_wp_element_namespaceObject.useState)(false); 25268 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 25269 className: dist_clsx('block-editor-global-styles-background-panel__inspector-media-replace-container', { 25270 'is-open': isDropDownOpen 25271 }), 25272 children: shouldShowBackgroundImageControls ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BackgroundControlsPanel, { 25273 label: title, 25274 filename: title, 25275 url: url, 25276 onToggle: setIsDropDownOpen, 25277 hasImageValue: hasImageValue, 25278 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 25279 spacing: 3, 25280 className: "single-column", 25281 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BackgroundImageControls, { 25282 onChange: onChange, 25283 style: value, 25284 inheritedValue: resolvedInheritedValue, 25285 displayInPanel: true, 25286 onResetImage: () => { 25287 setIsDropDownOpen(false); 25288 resetBackground(); 25289 }, 25290 onRemoveImage: () => setIsDropDownOpen(false), 25291 defaultValues: defaultValues 25292 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BackgroundSizeControls, { 25293 onChange: onChange, 25294 style: value, 25295 defaultValues: defaultValues, 25296 inheritedValue: resolvedInheritedValue 25297 })] 25298 }) 25299 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BackgroundImageControls, { 25300 onChange: onChange, 25301 style: value, 25302 inheritedValue: resolvedInheritedValue, 25303 defaultValues: defaultValues, 25304 onResetImage: () => { 25305 setIsDropDownOpen(false); 25306 resetBackground(); 25307 }, 25308 onRemoveImage: () => setIsDropDownOpen(false) 25309 }) 25310 }); 25311 } 25312 25313 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/background-panel.js 25314 /** 25315 * WordPress dependencies 25316 */ 25317 25318 25319 /** 25320 * Internal dependencies 25321 */ 25322 25323 25324 25325 25326 25327 const background_panel_DEFAULT_CONTROLS = { 25328 backgroundImage: true 25329 }; 25330 25331 /** 25332 * Checks site settings to see if the background panel may be used. 25333 * `settings.background.backgroundSize` exists also, 25334 * but can only be used if settings?.background?.backgroundImage is `true`. 25335 * 25336 * @param {Object} settings Site settings 25337 * @return {boolean} Whether site settings has activated background panel. 25338 */ 25339 function useHasBackgroundPanel(settings) { 25340 return external_wp_element_namespaceObject.Platform.OS === 'web' && settings?.background?.backgroundImage; 25341 } 25342 25343 /** 25344 * Checks if there is a current value in the background size block support 25345 * attributes. Background size values include background size as well 25346 * as background position. 25347 * 25348 * @param {Object} style Style attribute. 25349 * @return {boolean} Whether the block has a background size value set. 25350 */ 25351 function hasBackgroundSizeValue(style) { 25352 return style?.background?.backgroundPosition !== undefined || style?.background?.backgroundSize !== undefined; 25353 } 25354 25355 /** 25356 * Checks if there is a current value in the background image block support 25357 * attributes. 25358 * 25359 * @param {Object} style Style attribute. 25360 * @return {boolean} Whether the block has a background image value set. 25361 */ 25362 function hasBackgroundImageValue(style) { 25363 return !!style?.background?.backgroundImage?.id || 25364 // Supports url() string values in theme.json. 25365 'string' === typeof style?.background?.backgroundImage || !!style?.background?.backgroundImage?.url; 25366 } 25367 function BackgroundToolsPanel({ 25368 resetAllFilter, 25369 onChange, 25370 value, 25371 panelId, 25372 children, 25373 headerLabel 25374 }) { 25375 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 25376 const resetAll = () => { 25377 const updatedValue = resetAllFilter(value); 25378 onChange(updatedValue); 25379 }; 25380 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 25381 label: headerLabel, 25382 resetAll: resetAll, 25383 panelId: panelId, 25384 dropdownMenuProps: dropdownMenuProps, 25385 children: children 25386 }); 25387 } 25388 function background_panel_BackgroundImagePanel({ 25389 as: Wrapper = BackgroundToolsPanel, 25390 value, 25391 onChange, 25392 inheritedValue, 25393 settings, 25394 panelId, 25395 defaultControls = background_panel_DEFAULT_CONTROLS, 25396 defaultValues = {}, 25397 headerLabel = (0,external_wp_i18n_namespaceObject.__)('Background image') 25398 }) { 25399 const showBackgroundImageControl = useHasBackgroundPanel(settings); 25400 const resetBackground = () => onChange(setImmutably(value, ['background'], {})); 25401 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 25402 return { 25403 ...previousValue, 25404 background: {} 25405 }; 25406 }, []); 25407 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Wrapper, { 25408 resetAllFilter: resetAllFilter, 25409 value: value, 25410 onChange: onChange, 25411 panelId: panelId, 25412 headerLabel: headerLabel, 25413 children: showBackgroundImageControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 25414 hasValue: () => !!value?.background, 25415 label: (0,external_wp_i18n_namespaceObject.__)('Image'), 25416 onDeselect: resetBackground, 25417 isShownByDefault: defaultControls.backgroundImage, 25418 panelId: panelId, 25419 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BackgroundImagePanel, { 25420 value: value, 25421 onChange: onChange, 25422 settings: settings, 25423 inheritedValue: inheritedValue, 25424 defaultControls: defaultControls, 25425 defaultValues: defaultValues 25426 }) 25427 }) 25428 }); 25429 } 25430 25431 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/background.js 25432 /** 25433 * WordPress dependencies 25434 */ 25435 25436 25437 25438 25439 /** 25440 * Internal dependencies 25441 */ 25442 25443 25444 25445 25446 25447 25448 const BACKGROUND_SUPPORT_KEY = 'background'; 25449 25450 // Initial control values. 25451 const BACKGROUND_BLOCK_DEFAULT_VALUES = { 25452 backgroundSize: 'cover', 25453 backgroundPosition: '50% 50%' // used only when backgroundSize is 'contain'. 25454 }; 25455 25456 /** 25457 * Determine whether there is block support for background. 25458 * 25459 * @param {string} blockName Block name. 25460 * @param {string} feature Background image feature to check for. 25461 * 25462 * @return {boolean} Whether there is support. 25463 */ 25464 function hasBackgroundSupport(blockName, feature = 'any') { 25465 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, BACKGROUND_SUPPORT_KEY); 25466 if (support === true) { 25467 return true; 25468 } 25469 if (feature === 'any') { 25470 return !!support?.backgroundImage || !!support?.backgroundSize || !!support?.backgroundRepeat; 25471 } 25472 return !!support?.[feature]; 25473 } 25474 function setBackgroundStyleDefaults(backgroundStyle) { 25475 if (!backgroundStyle || !backgroundStyle?.backgroundImage?.url) { 25476 return; 25477 } 25478 let backgroundStylesWithDefaults; 25479 25480 // Set block background defaults. 25481 if (!backgroundStyle?.backgroundSize) { 25482 backgroundStylesWithDefaults = { 25483 backgroundSize: BACKGROUND_BLOCK_DEFAULT_VALUES.backgroundSize 25484 }; 25485 } 25486 if ('contain' === backgroundStyle?.backgroundSize && !backgroundStyle?.backgroundPosition) { 25487 backgroundStylesWithDefaults = { 25488 backgroundPosition: BACKGROUND_BLOCK_DEFAULT_VALUES.backgroundPosition 25489 }; 25490 } 25491 return backgroundStylesWithDefaults; 25492 } 25493 function background_useBlockProps({ 25494 name, 25495 style 25496 }) { 25497 if (!hasBackgroundSupport(name) || !style?.background?.backgroundImage) { 25498 return; 25499 } 25500 const backgroundStyles = setBackgroundStyleDefaults(style?.background); 25501 if (!backgroundStyles) { 25502 return; 25503 } 25504 return { 25505 style: { 25506 ...backgroundStyles 25507 } 25508 }; 25509 } 25510 25511 /** 25512 * Generates a CSS class name if an background image is set. 25513 * 25514 * @param {Object} style A block's style attribute. 25515 * 25516 * @return {string} CSS class name. 25517 */ 25518 function getBackgroundImageClasses(style) { 25519 return hasBackgroundImageValue(style) ? 'has-background' : ''; 25520 } 25521 function BackgroundInspectorControl({ 25522 children 25523 }) { 25524 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 25525 return { 25526 ...attributes, 25527 style: { 25528 ...attributes.style, 25529 background: undefined 25530 } 25531 }; 25532 }, []); 25533 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 25534 group: "background", 25535 resetAllFilter: resetAllFilter, 25536 children: children 25537 }); 25538 } 25539 function background_BackgroundImagePanel({ 25540 clientId, 25541 name, 25542 setAttributes, 25543 settings 25544 }) { 25545 const { 25546 style, 25547 inheritedValue 25548 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 25549 const { 25550 getBlockAttributes, 25551 getSettings 25552 } = select(store); 25553 const _settings = getSettings(); 25554 return { 25555 style: getBlockAttributes(clientId)?.style, 25556 /* 25557 * To ensure we pass down the right inherited values: 25558 * @TODO 1. Pass inherited value down to all block style controls, 25559 * See: packages/block-editor/src/hooks/style.js 25560 * @TODO 2. Add support for block style variations, 25561 * See implementation: packages/block-editor/src/hooks/block-style-variation.js 25562 */ 25563 inheritedValue: _settings[globalStylesDataKey]?.blocks?.[name] 25564 }; 25565 }, [clientId, name]); 25566 if (!useHasBackgroundPanel(settings) || !hasBackgroundSupport(name, 'backgroundImage')) { 25567 return null; 25568 } 25569 const onChange = newStyle => { 25570 setAttributes({ 25571 style: utils_cleanEmptyObject(newStyle) 25572 }); 25573 }; 25574 const updatedSettings = { 25575 ...settings, 25576 background: { 25577 ...settings.background, 25578 backgroundSize: settings?.background?.backgroundSize && hasBackgroundSupport(name, 'backgroundSize') 25579 } 25580 }; 25581 const defaultControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [BACKGROUND_SUPPORT_KEY, 'defaultControls']); 25582 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(background_panel_BackgroundImagePanel, { 25583 inheritedValue: inheritedValue, 25584 as: BackgroundInspectorControl, 25585 panelId: clientId, 25586 defaultValues: BACKGROUND_BLOCK_DEFAULT_VALUES, 25587 settings: updatedSettings, 25588 onChange: onChange, 25589 defaultControls: defaultControls, 25590 value: style 25591 }); 25592 } 25593 /* harmony default export */ const background = ({ 25594 useBlockProps: background_useBlockProps, 25595 attributeKeys: ['style'], 25596 hasSupport: hasBackgroundSupport 25597 }); 25598 25599 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/lock.js 25600 /** 25601 * WordPress dependencies 25602 */ 25603 25604 25605 /** 25606 * Filters registered block settings, extending attributes to include `lock`. 25607 * 25608 * @param {Object} settings Original block settings. 25609 * 25610 * @return {Object} Filtered block settings. 25611 */ 25612 function lock_addAttribute(settings) { 25613 var _settings$attributes$; 25614 // Allow blocks to specify their own attribute definition with default values if needed. 25615 if ('type' in ((_settings$attributes$ = settings.attributes?.lock) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 25616 return settings; 25617 } 25618 // Gracefully handle if settings.attributes is undefined. 25619 settings.attributes = { 25620 ...settings.attributes, 25621 lock: { 25622 type: 'object' 25623 } 25624 }; 25625 return settings; 25626 } 25627 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/lock/addAttribute', lock_addAttribute); 25628 25629 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/anchor.js 25630 /** 25631 * WordPress dependencies 25632 */ 25633 25634 25635 25636 25637 25638 25639 /** 25640 * Internal dependencies 25641 */ 25642 25643 25644 25645 /** 25646 * Regular expression matching invalid anchor characters for replacement. 25647 * 25648 * @type {RegExp} 25649 */ 25650 25651 const ANCHOR_REGEX = /[\s#]/g; 25652 const ANCHOR_SCHEMA = { 25653 type: 'string', 25654 source: 'attribute', 25655 attribute: 'id', 25656 selector: '*' 25657 }; 25658 25659 /** 25660 * Filters registered block settings, extending attributes with anchor using ID 25661 * of the first node. 25662 * 25663 * @param {Object} settings Original block settings. 25664 * 25665 * @return {Object} Filtered block settings. 25666 */ 25667 function anchor_addAttribute(settings) { 25668 var _settings$attributes$; 25669 // Allow blocks to specify their own attribute definition with default values if needed. 25670 if ('type' in ((_settings$attributes$ = settings.attributes?.anchor) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 25671 return settings; 25672 } 25673 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'anchor')) { 25674 // Gracefully handle if settings.attributes is undefined. 25675 settings.attributes = { 25676 ...settings.attributes, 25677 anchor: ANCHOR_SCHEMA 25678 }; 25679 } 25680 return settings; 25681 } 25682 function BlockEditAnchorControlPure({ 25683 anchor, 25684 setAttributes 25685 }) { 25686 const blockEditingMode = useBlockEditingMode(); 25687 if (blockEditingMode !== 'default') { 25688 return null; 25689 } 25690 const isWeb = external_wp_element_namespaceObject.Platform.OS === 'web'; 25691 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 25692 group: "advanced", 25693 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 25694 __nextHasNoMarginBottom: true, 25695 __next40pxDefaultSize: true, 25696 className: "html-anchor-control", 25697 label: (0,external_wp_i18n_namespaceObject.__)('HTML anchor'), 25698 help: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 25699 children: [(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 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 25700 children: [' ', /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ExternalLink, { 25701 href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/documentation/article/page-jumps/'), 25702 children: (0,external_wp_i18n_namespaceObject.__)('Learn more about anchors') 25703 })] 25704 })] 25705 }), 25706 value: anchor || '', 25707 placeholder: !isWeb ? (0,external_wp_i18n_namespaceObject.__)('Add an anchor') : null, 25708 onChange: nextValue => { 25709 nextValue = nextValue.replace(ANCHOR_REGEX, '-'); 25710 setAttributes({ 25711 anchor: nextValue 25712 }); 25713 }, 25714 autoCapitalize: "none", 25715 autoComplete: "off" 25716 }) 25717 }); 25718 } 25719 /* harmony default export */ const hooks_anchor = ({ 25720 addSaveProps, 25721 edit: BlockEditAnchorControlPure, 25722 attributeKeys: ['anchor'], 25723 hasSupport(name) { 25724 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'anchor'); 25725 } 25726 }); 25727 25728 /** 25729 * Override props assigned to save component to inject anchor ID, if block 25730 * supports anchor. This is only applied if the block's save result is an 25731 * element and not a markup string. 25732 * 25733 * @param {Object} extraProps Additional props applied to save element. 25734 * @param {Object} blockType Block type. 25735 * @param {Object} attributes Current block attributes. 25736 * 25737 * @return {Object} Filtered props applied to save element. 25738 */ 25739 function addSaveProps(extraProps, blockType, attributes) { 25740 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'anchor')) { 25741 extraProps.id = attributes.anchor === '' ? null : attributes.anchor; 25742 } 25743 return extraProps; 25744 } 25745 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/anchor/attribute', anchor_addAttribute); 25746 25747 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/aria-label.js 25748 /** 25749 * WordPress dependencies 25750 */ 25751 25752 25753 25754 /** 25755 * Filters registered block settings, extending attributes with ariaLabel using aria-label 25756 * of the first node. 25757 * 25758 * @param {Object} settings Original block settings. 25759 * 25760 * @return {Object} Filtered block settings. 25761 */ 25762 function aria_label_addAttribute(settings) { 25763 // Allow blocks to specify their own attribute definition with default values if needed. 25764 if (settings?.attributes?.ariaLabel?.type) { 25765 return settings; 25766 } 25767 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'ariaLabel')) { 25768 // Gracefully handle if settings.attributes is undefined. 25769 settings.attributes = { 25770 ...settings.attributes, 25771 ariaLabel: { 25772 type: 'string' 25773 } 25774 }; 25775 } 25776 return settings; 25777 } 25778 25779 /** 25780 * Override props assigned to save component to inject aria-label, if block 25781 * supports ariaLabel. This is only applied if the block's save result is an 25782 * element and not a markup string. 25783 * 25784 * @param {Object} extraProps Additional props applied to save element. 25785 * @param {Object} blockType Block type. 25786 * @param {Object} attributes Current block attributes. 25787 * 25788 * @return {Object} Filtered props applied to save element. 25789 */ 25790 function aria_label_addSaveProps(extraProps, blockType, attributes) { 25791 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'ariaLabel')) { 25792 extraProps['aria-label'] = attributes.ariaLabel === '' ? null : attributes.ariaLabel; 25793 } 25794 return extraProps; 25795 } 25796 /* harmony default export */ const aria_label = ({ 25797 addSaveProps: aria_label_addSaveProps, 25798 attributeKeys: ['ariaLabel'], 25799 hasSupport(name) { 25800 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'ariaLabel'); 25801 } 25802 }); 25803 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/ariaLabel/attribute', aria_label_addAttribute); 25804 25805 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/custom-class-name.js 25806 /** 25807 * External dependencies 25808 */ 25809 25810 25811 /** 25812 * WordPress dependencies 25813 */ 25814 25815 25816 25817 25818 25819 /** 25820 * Internal dependencies 25821 */ 25822 25823 25824 25825 /** 25826 * Filters registered block settings, extending attributes to include `className`. 25827 * 25828 * @param {Object} settings Original block settings. 25829 * 25830 * @return {Object} Filtered block settings. 25831 */ 25832 25833 function custom_class_name_addAttribute(settings) { 25834 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'customClassName', true)) { 25835 // Gracefully handle if settings.attributes is undefined. 25836 settings.attributes = { 25837 ...settings.attributes, 25838 className: { 25839 type: 'string' 25840 } 25841 }; 25842 } 25843 return settings; 25844 } 25845 function CustomClassNameControlsPure({ 25846 className, 25847 setAttributes 25848 }) { 25849 const blockEditingMode = useBlockEditingMode(); 25850 if (blockEditingMode !== 'default') { 25851 return null; 25852 } 25853 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 25854 group: "advanced", 25855 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 25856 __nextHasNoMarginBottom: true, 25857 __next40pxDefaultSize: true, 25858 autoComplete: "off", 25859 label: (0,external_wp_i18n_namespaceObject.__)('Additional CSS class(es)'), 25860 value: className || '', 25861 onChange: nextValue => { 25862 setAttributes({ 25863 className: nextValue !== '' ? nextValue : undefined 25864 }); 25865 }, 25866 help: (0,external_wp_i18n_namespaceObject.__)('Separate multiple classes with spaces.') 25867 }) 25868 }); 25869 } 25870 /* harmony default export */ const custom_class_name = ({ 25871 edit: CustomClassNameControlsPure, 25872 addSaveProps: custom_class_name_addSaveProps, 25873 attributeKeys: ['className'], 25874 hasSupport(name) { 25875 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'customClassName', true); 25876 } 25877 }); 25878 25879 /** 25880 * Override props assigned to save component to inject the className, if block 25881 * supports customClassName. This is only applied if the block's save result is an 25882 * element and not a markup string. 25883 * 25884 * @param {Object} extraProps Additional props applied to save element. 25885 * @param {Object} blockType Block type. 25886 * @param {Object} attributes Current block attributes. 25887 * 25888 * @return {Object} Filtered props applied to save element. 25889 */ 25890 function custom_class_name_addSaveProps(extraProps, blockType, attributes) { 25891 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'customClassName', true) && attributes.className) { 25892 extraProps.className = dist_clsx(extraProps.className, attributes.className); 25893 } 25894 return extraProps; 25895 } 25896 function addTransforms(result, source, index, results) { 25897 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(result.name, 'customClassName', true)) { 25898 return result; 25899 } 25900 25901 // If the condition verifies we are probably in the presence of a wrapping transform 25902 // e.g: nesting paragraphs in a group or columns and in that case the class should not be kept. 25903 if (results.length === 1 && result.innerBlocks.length === source.length) { 25904 return result; 25905 } 25906 25907 // If we are transforming one block to multiple blocks or multiple blocks to one block, 25908 // we ignore the class during the transform. 25909 if (results.length === 1 && source.length > 1 || results.length > 1 && source.length === 1) { 25910 return result; 25911 } 25912 25913 // If we are in presence of transform between one or more block in the source 25914 // that have one or more blocks in the result 25915 // we apply the class on source N to the result N, 25916 // if source N does not exists we do nothing. 25917 if (source[index]) { 25918 const originClassName = source[index]?.attributes.className; 25919 // Avoid overriding classes if the transformed block already includes them. 25920 if (originClassName && result.attributes.className === undefined) { 25921 return { 25922 ...result, 25923 attributes: { 25924 ...result.attributes, 25925 className: originClassName 25926 } 25927 }; 25928 } 25929 } 25930 return result; 25931 } 25932 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/custom-class-name/attribute', custom_class_name_addAttribute); 25933 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', addTransforms); 25934 25935 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/generated-class-name.js 25936 /** 25937 * WordPress dependencies 25938 */ 25939 25940 25941 25942 /** 25943 * Override props assigned to save component to inject generated className if 25944 * block supports it. This is only applied if the block's save result is an 25945 * element and not a markup string. 25946 * 25947 * @param {Object} extraProps Additional props applied to save element. 25948 * @param {Object} blockType Block type. 25949 * 25950 * @return {Object} Filtered props applied to save element. 25951 */ 25952 function addGeneratedClassName(extraProps, blockType) { 25953 // Adding the generated className. 25954 if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'className', true)) { 25955 if (typeof extraProps.className === 'string') { 25956 // We have some extra classes and want to add the default classname 25957 // We use uniq to prevent duplicate classnames. 25958 25959 extraProps.className = [...new Set([(0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockType.name), ...extraProps.className.split(' ')])].join(' ').trim(); 25960 } else { 25961 // There is no string in the className variable, 25962 // so we just dump the default name in there. 25963 extraProps.className = (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockType.name); 25964 } 25965 } 25966 return extraProps; 25967 } 25968 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/generated-class-name/save-props', addGeneratedClassName); 25969 25970 ;// ./node_modules/colord/index.mjs 25971 var colord_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)*(colord_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()})}; 25972 25973 ;// ./node_modules/colord/plugins/names.mjs 25974 /* 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"])} 25975 25976 ;// ./node_modules/colord/plugins/a11y.mjs 25977 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}} 25978 25979 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors/utils.js 25980 /** 25981 * External dependencies 25982 */ 25983 25984 25985 25986 25987 /** 25988 * WordPress dependencies 25989 */ 25990 25991 25992 /** 25993 * Internal dependencies 25994 */ 25995 25996 k([names, a11y]); 25997 const { 25998 kebabCase 25999 } = unlock(external_wp_components_namespaceObject.privateApis); 26000 26001 /** 26002 * Provided an array of color objects as set by the theme or by the editor defaults, 26003 * and the values of the defined color or custom color returns a color object describing the color. 26004 * 26005 * @param {Array} colors Array of color objects as set by the theme or by the editor defaults. 26006 * @param {?string} definedColor A string containing the color slug. 26007 * @param {?string} customColor A string containing the customColor value. 26008 * 26009 * @return {?Object} If definedColor is passed and the name is found in colors, 26010 * the color object exactly as set by the theme or editor defaults is returned. 26011 * Otherwise, an object that just sets the color is defined. 26012 */ 26013 const getColorObjectByAttributeValues = (colors, definedColor, customColor) => { 26014 if (definedColor) { 26015 const colorObj = colors?.find(color => color.slug === definedColor); 26016 if (colorObj) { 26017 return colorObj; 26018 } 26019 } 26020 return { 26021 color: customColor 26022 }; 26023 }; 26024 26025 /** 26026 * 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. 26027 * 26028 * @param {Array} colors Array of color objects as set by the theme or by the editor defaults. 26029 * @param {?string} colorValue A string containing the color value. 26030 * 26031 * @return {?Object} Color object included in the colors array whose color property equals colorValue. 26032 * Returns undefined if no color object matches this requirement. 26033 */ 26034 const getColorObjectByColorValue = (colors, colorValue) => { 26035 return colors?.find(color => color.color === colorValue); 26036 }; 26037 26038 /** 26039 * Returns a class based on the context a color is being used and its slug. 26040 * 26041 * @param {string} colorContextName Context/place where color is being used e.g: background, text etc... 26042 * @param {string} colorSlug Slug of the color. 26043 * 26044 * @return {?string} String with the class corresponding to the color in the provided context. 26045 * Returns undefined if either colorContextName or colorSlug are not provided. 26046 */ 26047 function getColorClassName(colorContextName, colorSlug) { 26048 if (!colorContextName || !colorSlug) { 26049 return undefined; 26050 } 26051 return `has-$kebabCase(colorSlug)}-$colorContextName}`; 26052 } 26053 26054 /** 26055 * Given an array of color objects and a color value returns the color value of the most readable color in the array. 26056 * 26057 * @param {Array} colors Array of color objects as set by the theme or by the editor defaults. 26058 * @param {?string} colorValue A string containing the color value. 26059 * 26060 * @return {string} String with the color value of the most readable color. 26061 */ 26062 function getMostReadableColor(colors, colorValue) { 26063 const colordColor = w(colorValue); 26064 const getColorContrast = ({ 26065 color 26066 }) => colordColor.contrast(color); 26067 const maxContrast = Math.max(...colors.map(getColorContrast)); 26068 return colors.find(color => getColorContrast(color) === maxContrast).color; 26069 } 26070 26071 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js 26072 /** 26073 * WordPress dependencies 26074 */ 26075 26076 26077 26078 /** 26079 * Internal dependencies 26080 */ 26081 26082 26083 /** 26084 * Retrieves color and gradient related settings. 26085 * 26086 * The arrays for colors and gradients are made up of color palettes from each 26087 * origin i.e. "Core", "Theme", and "User". 26088 * 26089 * @return {Object} Color and gradient related settings. 26090 */ 26091 function useMultipleOriginColorsAndGradients() { 26092 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'); 26093 const colorGradientSettings = { 26094 disableCustomColors: !enableCustomColors, 26095 disableCustomGradients: !enableCustomGradients 26096 }; 26097 colorGradientSettings.colors = (0,external_wp_element_namespaceObject.useMemo)(() => { 26098 const result = []; 26099 if (themeColors && themeColors.length) { 26100 result.push({ 26101 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 26102 slug: 'theme', 26103 colors: themeColors 26104 }); 26105 } 26106 if (shouldDisplayDefaultColors && defaultColors && defaultColors.length) { 26107 result.push({ 26108 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 26109 slug: 'default', 26110 colors: defaultColors 26111 }); 26112 } 26113 if (customColors && customColors.length) { 26114 result.push({ 26115 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 26116 slug: 'custom', 26117 colors: customColors 26118 }); 26119 } 26120 return result; 26121 }, [customColors, themeColors, defaultColors, shouldDisplayDefaultColors]); 26122 colorGradientSettings.gradients = (0,external_wp_element_namespaceObject.useMemo)(() => { 26123 const result = []; 26124 if (themeGradients && themeGradients.length) { 26125 result.push({ 26126 name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'), 26127 slug: 'theme', 26128 gradients: themeGradients 26129 }); 26130 } 26131 if (shouldDisplayDefaultGradients && defaultGradients && defaultGradients.length) { 26132 result.push({ 26133 name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'), 26134 slug: 'default', 26135 gradients: defaultGradients 26136 }); 26137 } 26138 if (customGradients && customGradients.length) { 26139 result.push({ 26140 name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'), 26141 slug: 'custom', 26142 gradients: customGradients 26143 }); 26144 } 26145 return result; 26146 }, [customGradients, themeGradients, defaultGradients, shouldDisplayDefaultGradients]); 26147 colorGradientSettings.hasColorsOrGradients = !!colorGradientSettings.colors.length || !!colorGradientSettings.gradients.length; 26148 return colorGradientSettings; 26149 } 26150 26151 ;// ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/utils.js 26152 /** 26153 * WordPress dependencies 26154 */ 26155 26156 26157 /** 26158 * Gets the (non-undefined) item with the highest occurrence within an array 26159 * Based in part on: https://stackoverflow.com/a/20762713 26160 * 26161 * Undefined values are always sorted to the end by `sort`, so this function 26162 * returns the first element, to always prioritize real values over undefined 26163 * values. 26164 * 26165 * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description 26166 * 26167 * @param {Array<any>} inputArray Array of items to check. 26168 * @return {any} The item with the most occurrences. 26169 */ 26170 function mode(inputArray) { 26171 const arr = [...inputArray]; 26172 return arr.sort((a, b) => inputArray.filter(v => v === b).length - inputArray.filter(v => v === a).length).shift(); 26173 } 26174 26175 /** 26176 * Returns the most common CSS unit from the current CSS unit selections. 26177 * 26178 * - If a single flat border radius is set, its unit will be used 26179 * - If individual corner selections, the most common of those will be used 26180 * - Failing any unit selections a default of 'px' is returned. 26181 * 26182 * @param {Object} selectedUnits Unit selections for flat radius & each corner. 26183 * @return {string} Most common CSS unit from current selections. Default: `px`. 26184 */ 26185 function getAllUnit(selectedUnits = {}) { 26186 const { 26187 flat, 26188 ...cornerUnits 26189 } = selectedUnits; 26190 return flat || mode(Object.values(cornerUnits).filter(Boolean)) || 'px'; 26191 } 26192 26193 /** 26194 * Gets the 'all' input value and unit from values data. 26195 * 26196 * @param {Object|string} values Radius values. 26197 * @return {string} A value + unit for the 'all' input. 26198 */ 26199 function getAllValue(values = {}) { 26200 /** 26201 * Border radius support was originally a single pixel value. 26202 * 26203 * To maintain backwards compatibility treat this case as the all value. 26204 */ 26205 if (typeof values === 'string') { 26206 return values; 26207 } 26208 const parsedQuantitiesAndUnits = Object.values(values).map(value => (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value)); 26209 const allValues = parsedQuantitiesAndUnits.map(value => { 26210 var _value$; 26211 return (_value$ = value[0]) !== null && _value$ !== void 0 ? _value$ : ''; 26212 }); 26213 const allUnits = parsedQuantitiesAndUnits.map(value => value[1]); 26214 const value = allValues.every(v => v === allValues[0]) ? allValues[0] : ''; 26215 const unit = mode(allUnits); 26216 const allValue = value === 0 || value ? `$value}$unit}` : undefined; 26217 return allValue; 26218 } 26219 26220 /** 26221 * Checks to determine if values are mixed. 26222 * 26223 * @param {Object} values Radius values. 26224 * @return {boolean} Whether values are mixed. 26225 */ 26226 function hasMixedValues(values = {}) { 26227 const allValue = getAllValue(values); 26228 const isMixed = typeof values === 'string' ? false : isNaN(parseFloat(allValue)); 26229 return isMixed; 26230 } 26231 26232 /** 26233 * Checks to determine if values are defined. 26234 * 26235 * @param {Object} values Radius values. 26236 * @return {boolean} Whether values are mixed. 26237 */ 26238 function hasDefinedValues(values) { 26239 if (!values) { 26240 return false; 26241 } 26242 26243 // A string value represents a shorthand value. 26244 if (typeof values === 'string') { 26245 return true; 26246 } 26247 26248 // An object represents longhand border radius values, if any are set 26249 // flag values as being defined. 26250 const filteredValues = Object.values(values).filter(value => { 26251 return !!value || value === 0; 26252 }); 26253 return !!filteredValues.length; 26254 } 26255 26256 ;// ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/all-input-control.js 26257 /** 26258 * WordPress dependencies 26259 */ 26260 26261 26262 26263 /** 26264 * Internal dependencies 26265 */ 26266 26267 26268 function AllInputControl({ 26269 onChange, 26270 selectedUnits, 26271 setSelectedUnits, 26272 values, 26273 ...props 26274 }) { 26275 let allValue = getAllValue(values); 26276 if (allValue === undefined) { 26277 // If we don't have any value set the unit to any current selection 26278 // or the most common unit from the individual radii values. 26279 allValue = getAllUnit(selectedUnits); 26280 } 26281 const hasValues = hasDefinedValues(values); 26282 const isMixed = hasValues && hasMixedValues(values); 26283 const allPlaceholder = isMixed ? (0,external_wp_i18n_namespaceObject.__)('Mixed') : null; 26284 26285 // Filter out CSS-unit-only values to prevent invalid styles. 26286 const handleOnChange = next => { 26287 const isNumeric = !isNaN(parseFloat(next)); 26288 const nextValue = isNumeric ? next : undefined; 26289 onChange(nextValue); 26290 }; 26291 26292 // Store current unit selection for use as fallback for individual 26293 // radii controls. 26294 const handleOnUnitChange = unit => { 26295 setSelectedUnits({ 26296 topLeft: unit, 26297 topRight: unit, 26298 bottomLeft: unit, 26299 bottomRight: unit 26300 }); 26301 }; 26302 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 26303 ...props, 26304 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Border radius'), 26305 disableUnits: isMixed, 26306 isOnly: true, 26307 value: allValue, 26308 onChange: handleOnChange, 26309 onUnitChange: handleOnUnitChange, 26310 placeholder: allPlaceholder, 26311 size: "__unstable-large" 26312 }); 26313 } 26314 26315 ;// ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/input-controls.js 26316 /** 26317 * WordPress dependencies 26318 */ 26319 26320 26321 26322 const CORNERS = { 26323 topLeft: (0,external_wp_i18n_namespaceObject.__)('Top left'), 26324 topRight: (0,external_wp_i18n_namespaceObject.__)('Top right'), 26325 bottomLeft: (0,external_wp_i18n_namespaceObject.__)('Bottom left'), 26326 bottomRight: (0,external_wp_i18n_namespaceObject.__)('Bottom right') 26327 }; 26328 function BoxInputControls({ 26329 onChange, 26330 selectedUnits, 26331 setSelectedUnits, 26332 values: valuesProp, 26333 ...props 26334 }) { 26335 const createHandleOnChange = corner => next => { 26336 if (!onChange) { 26337 return; 26338 } 26339 26340 // Filter out CSS-unit-only values to prevent invalid styles. 26341 const isNumeric = !isNaN(parseFloat(next)); 26342 const nextValue = isNumeric ? next : undefined; 26343 onChange({ 26344 ...values, 26345 [corner]: nextValue 26346 }); 26347 }; 26348 const createHandleOnUnitChange = side => next => { 26349 const newUnits = { 26350 ...selectedUnits 26351 }; 26352 newUnits[side] = next; 26353 setSelectedUnits(newUnits); 26354 }; 26355 26356 // For shorthand style & backwards compatibility, handle flat string value. 26357 const values = typeof valuesProp !== 'string' ? valuesProp : { 26358 topLeft: valuesProp, 26359 topRight: valuesProp, 26360 bottomLeft: valuesProp, 26361 bottomRight: valuesProp 26362 }; 26363 26364 // Controls are wrapped in tooltips as visible labels aren't desired here. 26365 // Tooltip rendering also requires the UnitControl to be wrapped. See: 26366 // https://github.com/WordPress/gutenberg/pull/24966#issuecomment-685875026 26367 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 26368 className: "components-border-radius-control__input-controls-wrapper", 26369 children: Object.entries(CORNERS).map(([corner, label]) => { 26370 const [parsedQuantity, parsedUnit] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values[corner]); 26371 const computedUnit = values[corner] ? parsedUnit : selectedUnits[corner] || selectedUnits.flat; 26372 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tooltip, { 26373 text: label, 26374 placement: "top", 26375 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 26376 className: "components-border-radius-control__tooltip-wrapper", 26377 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 26378 ...props, 26379 "aria-label": label, 26380 value: [parsedQuantity, computedUnit].join(''), 26381 onChange: createHandleOnChange(corner), 26382 onUnitChange: createHandleOnUnitChange(corner), 26383 size: "__unstable-large" 26384 }) 26385 }) 26386 }, corner); 26387 }) 26388 }); 26389 } 26390 26391 ;// ./node_modules/@wordpress/icons/build-module/library/link.js 26392 /** 26393 * WordPress dependencies 26394 */ 26395 26396 26397 const link_link = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 26398 xmlns: "http://www.w3.org/2000/svg", 26399 viewBox: "0 0 24 24", 26400 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 26401 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" 26402 }) 26403 }); 26404 /* harmony default export */ const library_link = (link_link); 26405 26406 ;// ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/linked-button.js 26407 /** 26408 * WordPress dependencies 26409 */ 26410 26411 26412 26413 26414 function LinkedButton({ 26415 isLinked, 26416 ...props 26417 }) { 26418 const label = isLinked ? (0,external_wp_i18n_namespaceObject.__)('Unlink radii') : (0,external_wp_i18n_namespaceObject.__)('Link radii'); 26419 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 26420 ...props, 26421 className: "component-border-radius-control__linked-button", 26422 size: "small", 26423 icon: isLinked ? library_link : link_off, 26424 iconSize: 24, 26425 label: label 26426 }); 26427 } 26428 26429 ;// ./node_modules/@wordpress/block-editor/build-module/components/border-radius-control/index.js 26430 /** 26431 * WordPress dependencies 26432 */ 26433 26434 26435 26436 26437 /** 26438 * Internal dependencies 26439 */ 26440 26441 26442 26443 26444 26445 26446 const border_radius_control_DEFAULT_VALUES = { 26447 topLeft: undefined, 26448 topRight: undefined, 26449 bottomLeft: undefined, 26450 bottomRight: undefined 26451 }; 26452 const MIN_BORDER_RADIUS_VALUE = 0; 26453 const MAX_BORDER_RADIUS_VALUES = { 26454 px: 100, 26455 em: 20, 26456 rem: 20 26457 }; 26458 26459 /** 26460 * Control to display border radius options. 26461 * 26462 * @param {Object} props Component props. 26463 * @param {Function} props.onChange Callback to handle onChange. 26464 * @param {Object} props.values Border radius values. 26465 * 26466 * @return {Element} Custom border radius control. 26467 */ 26468 function BorderRadiusControl({ 26469 onChange, 26470 values 26471 }) { 26472 const [isLinked, setIsLinked] = (0,external_wp_element_namespaceObject.useState)(!hasDefinedValues(values) || !hasMixedValues(values)); 26473 26474 // Tracking selected units via internal state allows filtering of CSS unit 26475 // only values from being saved while maintaining preexisting unit selection 26476 // behaviour. Filtering CSS unit only values prevents invalid style values. 26477 const [selectedUnits, setSelectedUnits] = (0,external_wp_element_namespaceObject.useState)({ 26478 flat: typeof values === 'string' ? (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values)[1] : undefined, 26479 topLeft: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.topLeft)[1], 26480 topRight: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.topRight)[1], 26481 bottomLeft: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.bottomLeft)[1], 26482 bottomRight: (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(values?.bottomRight)[1] 26483 }); 26484 const [availableUnits] = use_settings_useSettings('spacing.units'); 26485 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 26486 availableUnits: availableUnits || ['px', 'em', 'rem'] 26487 }); 26488 const unit = getAllUnit(selectedUnits); 26489 const unitConfig = units && units.find(item => item.value === unit); 26490 const step = unitConfig?.step || 1; 26491 const [allValue] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(getAllValue(values)); 26492 const toggleLinked = () => setIsLinked(!isLinked); 26493 const handleSliderChange = next => { 26494 onChange(next !== undefined ? `$next}$unit}` : undefined); 26495 }; 26496 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 26497 className: "components-border-radius-control", 26498 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 26499 as: "legend", 26500 children: (0,external_wp_i18n_namespaceObject.__)('Radius') 26501 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 26502 className: "components-border-radius-control__wrapper", 26503 children: [isLinked ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 26504 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AllInputControl, { 26505 className: "components-border-radius-control__unit-control", 26506 values: values, 26507 min: MIN_BORDER_RADIUS_VALUE, 26508 onChange: onChange, 26509 selectedUnits: selectedUnits, 26510 setSelectedUnits: setSelectedUnits, 26511 units: units 26512 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 26513 __next40pxDefaultSize: true, 26514 label: (0,external_wp_i18n_namespaceObject.__)('Border radius'), 26515 hideLabelFromVision: true, 26516 className: "components-border-radius-control__range-control", 26517 value: allValue !== null && allValue !== void 0 ? allValue : '', 26518 min: MIN_BORDER_RADIUS_VALUE, 26519 max: MAX_BORDER_RADIUS_VALUES[unit], 26520 initialPosition: 0, 26521 withInputField: false, 26522 onChange: handleSliderChange, 26523 step: step, 26524 __nextHasNoMarginBottom: true 26525 })] 26526 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BoxInputControls, { 26527 min: MIN_BORDER_RADIUS_VALUE, 26528 onChange: onChange, 26529 selectedUnits: selectedUnits, 26530 setSelectedUnits: setSelectedUnits, 26531 values: values || border_radius_control_DEFAULT_VALUES, 26532 units: units 26533 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkedButton, { 26534 onClick: toggleLinked, 26535 isLinked: isLinked 26536 })] 26537 })] 26538 }); 26539 } 26540 26541 ;// ./node_modules/@wordpress/icons/build-module/library/check.js 26542 /** 26543 * WordPress dependencies 26544 */ 26545 26546 26547 const check_check = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 26548 xmlns: "http://www.w3.org/2000/svg", 26549 viewBox: "0 0 24 24", 26550 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 26551 d: "M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z" 26552 }) 26553 }); 26554 /* harmony default export */ const library_check = (check_check); 26555 26556 ;// ./node_modules/@wordpress/icons/build-module/library/shadow.js 26557 /** 26558 * WordPress dependencies 26559 */ 26560 26561 26562 const shadow = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 26563 viewBox: "0 0 24 24", 26564 xmlns: "http://www.w3.org/2000/svg", 26565 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 26566 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" 26567 }) 26568 }); 26569 /* harmony default export */ const library_shadow = (shadow); 26570 26571 ;// ./node_modules/@wordpress/icons/build-module/library/reset.js 26572 /** 26573 * WordPress dependencies 26574 */ 26575 26576 26577 const reset_reset = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 26578 xmlns: "http://www.w3.org/2000/svg", 26579 viewBox: "0 0 24 24", 26580 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 26581 d: "M7 11.5h10V13H7z" 26582 }) 26583 }); 26584 /* harmony default export */ const library_reset = (reset_reset); 26585 26586 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/shadow-panel-components.js 26587 /** 26588 * WordPress dependencies 26589 */ 26590 26591 26592 26593 26594 26595 /** 26596 * External dependencies 26597 */ 26598 26599 26600 /** 26601 * Shared reference to an empty array for cases where it is important to avoid 26602 * returning a new array reference on every invocation. 26603 * 26604 * @type {Array} 26605 */ 26606 26607 const shadow_panel_components_EMPTY_ARRAY = []; 26608 function ShadowPopoverContainer({ 26609 shadow, 26610 onShadowChange, 26611 settings 26612 }) { 26613 const shadows = useShadowPresets(settings); 26614 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 26615 className: "block-editor-global-styles__shadow-popover-container", 26616 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 26617 spacing: 4, 26618 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalHeading, { 26619 level: 5, 26620 children: (0,external_wp_i18n_namespaceObject.__)('Drop shadow') 26621 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ShadowPresets, { 26622 presets: shadows, 26623 activeShadow: shadow, 26624 onSelect: onShadowChange 26625 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 26626 className: "block-editor-global-styles__clear-shadow", 26627 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 26628 __next40pxDefaultSize: true, 26629 variant: "tertiary", 26630 onClick: () => onShadowChange(undefined), 26631 disabled: !shadow, 26632 accessibleWhenDisabled: true, 26633 children: (0,external_wp_i18n_namespaceObject.__)('Clear') 26634 }) 26635 })] 26636 }) 26637 }); 26638 } 26639 function ShadowPresets({ 26640 presets, 26641 activeShadow, 26642 onSelect 26643 }) { 26644 return !presets ? null : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite, { 26645 role: "listbox", 26646 className: "block-editor-global-styles__shadow__list", 26647 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Drop shadows'), 26648 children: presets.map(({ 26649 name, 26650 slug, 26651 shadow 26652 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ShadowIndicator, { 26653 label: name, 26654 isActive: shadow === activeShadow, 26655 type: slug === 'unset' ? 'unset' : 'preset', 26656 onSelect: () => onSelect(shadow === activeShadow ? undefined : shadow), 26657 shadow: shadow 26658 }, slug)) 26659 }); 26660 } 26661 function ShadowIndicator({ 26662 type, 26663 label, 26664 isActive, 26665 onSelect, 26666 shadow 26667 }) { 26668 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tooltip, { 26669 text: label, 26670 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite.Item, { 26671 role: "option", 26672 "aria-label": label, 26673 "aria-selected": isActive, 26674 className: dist_clsx('block-editor-global-styles__shadow__item', { 26675 'is-active': isActive 26676 }), 26677 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("button", { 26678 className: dist_clsx('block-editor-global-styles__shadow-indicator', { 26679 unset: type === 'unset' 26680 }), 26681 onClick: onSelect, 26682 style: { 26683 boxShadow: shadow 26684 }, 26685 "aria-label": label, 26686 children: isActive && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 26687 icon: library_check 26688 }) 26689 }) 26690 }) 26691 }); 26692 } 26693 function ShadowPopover({ 26694 shadow, 26695 onShadowChange, 26696 settings 26697 }) { 26698 const popoverProps = { 26699 placement: 'left-start', 26700 offset: 36, 26701 shift: true 26702 }; 26703 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 26704 popoverProps: popoverProps, 26705 className: "block-editor-global-styles__shadow-dropdown", 26706 renderToggle: renderShadowToggle(shadow, onShadowChange), 26707 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 26708 paddingSize: "medium", 26709 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ShadowPopoverContainer, { 26710 shadow: shadow, 26711 onShadowChange: onShadowChange, 26712 settings: settings 26713 }) 26714 }) 26715 }); 26716 } 26717 function renderShadowToggle(shadow, onShadowChange) { 26718 return ({ 26719 onToggle, 26720 isOpen 26721 }) => { 26722 const shadowButtonRef = (0,external_wp_element_namespaceObject.useRef)(undefined); 26723 const toggleProps = { 26724 onClick: onToggle, 26725 className: dist_clsx({ 26726 'is-open': isOpen 26727 }), 26728 'aria-expanded': isOpen, 26729 ref: shadowButtonRef 26730 }; 26731 const removeButtonProps = { 26732 onClick: () => { 26733 if (isOpen) { 26734 onToggle(); 26735 } 26736 onShadowChange(undefined); 26737 // Return focus to parent button. 26738 shadowButtonRef.current?.focus(); 26739 }, 26740 className: dist_clsx('block-editor-global-styles__shadow-editor__remove-button', { 26741 'is-open': isOpen 26742 }), 26743 label: (0,external_wp_i18n_namespaceObject.__)('Remove') 26744 }; 26745 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 26746 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 26747 __next40pxDefaultSize: true, 26748 ...toggleProps, 26749 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 26750 justify: "flex-start", 26751 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 26752 className: "block-editor-global-styles__toggle-icon", 26753 icon: library_shadow, 26754 size: 24 26755 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 26756 children: (0,external_wp_i18n_namespaceObject.__)('Drop shadow') 26757 })] 26758 }) 26759 }), !!shadow && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 26760 __next40pxDefaultSize: true, 26761 size: "small", 26762 icon: library_reset, 26763 ...removeButtonProps 26764 })] 26765 }); 26766 }; 26767 } 26768 function useShadowPresets(settings) { 26769 return (0,external_wp_element_namespaceObject.useMemo)(() => { 26770 var _settings$shadow$pres; 26771 if (!settings?.shadow) { 26772 return shadow_panel_components_EMPTY_ARRAY; 26773 } 26774 const defaultPresetsEnabled = settings?.shadow?.defaultPresets; 26775 const { 26776 default: defaultShadows, 26777 theme: themeShadows, 26778 custom: customShadows 26779 } = (_settings$shadow$pres = settings?.shadow?.presets) !== null && _settings$shadow$pres !== void 0 ? _settings$shadow$pres : {}; 26780 const unsetShadow = { 26781 name: (0,external_wp_i18n_namespaceObject.__)('Unset'), 26782 slug: 'unset', 26783 shadow: 'none' 26784 }; 26785 const shadowPresets = [...(defaultPresetsEnabled && defaultShadows || shadow_panel_components_EMPTY_ARRAY), ...(themeShadows || shadow_panel_components_EMPTY_ARRAY), ...(customShadows || shadow_panel_components_EMPTY_ARRAY)]; 26786 if (shadowPresets.length) { 26787 shadowPresets.unshift(unsetShadow); 26788 } 26789 return shadowPresets; 26790 }, [settings]); 26791 } 26792 26793 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/border-panel.js 26794 /** 26795 * WordPress dependencies 26796 */ 26797 26798 26799 26800 26801 /** 26802 * Internal dependencies 26803 */ 26804 26805 26806 26807 26808 26809 26810 26811 function useHasBorderPanel(settings) { 26812 const controls = Object.values(useHasBorderPanelControls(settings)); 26813 return controls.some(Boolean); 26814 } 26815 function useHasBorderPanelControls(settings) { 26816 const controls = { 26817 hasBorderColor: useHasBorderColorControl(settings), 26818 hasBorderRadius: useHasBorderRadiusControl(settings), 26819 hasBorderStyle: useHasBorderStyleControl(settings), 26820 hasBorderWidth: useHasBorderWidthControl(settings), 26821 hasShadow: useHasShadowControl(settings) 26822 }; 26823 return controls; 26824 } 26825 function useHasBorderColorControl(settings) { 26826 return settings?.border?.color; 26827 } 26828 function useHasBorderRadiusControl(settings) { 26829 return settings?.border?.radius; 26830 } 26831 function useHasBorderStyleControl(settings) { 26832 return settings?.border?.style; 26833 } 26834 function useHasBorderWidthControl(settings) { 26835 return settings?.border?.width; 26836 } 26837 function useHasShadowControl(settings) { 26838 const shadows = useShadowPresets(settings); 26839 return !!settings?.shadow && shadows.length > 0; 26840 } 26841 function BorderToolsPanel({ 26842 resetAllFilter, 26843 onChange, 26844 value, 26845 panelId, 26846 children, 26847 label 26848 }) { 26849 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 26850 const resetAll = () => { 26851 const updatedValue = resetAllFilter(value); 26852 onChange(updatedValue); 26853 }; 26854 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 26855 label: label, 26856 resetAll: resetAll, 26857 panelId: panelId, 26858 dropdownMenuProps: dropdownMenuProps, 26859 children: children 26860 }); 26861 } 26862 const border_panel_DEFAULT_CONTROLS = { 26863 radius: true, 26864 color: true, 26865 width: true, 26866 shadow: true 26867 }; 26868 function BorderPanel({ 26869 as: Wrapper = BorderToolsPanel, 26870 value, 26871 onChange, 26872 inheritedValue = value, 26873 settings, 26874 panelId, 26875 name, 26876 defaultControls = border_panel_DEFAULT_CONTROLS 26877 }) { 26878 var _settings$shadow$pres, _ref, _ref2, _shadowPresets$custom; 26879 const colors = useColorsPerOrigin(settings); 26880 const decodeValue = (0,external_wp_element_namespaceObject.useCallback)(rawValue => getValueFromVariable({ 26881 settings 26882 }, '', rawValue), [settings]); 26883 const encodeColorValue = colorValue => { 26884 const allColors = colors.flatMap(({ 26885 colors: originColors 26886 }) => originColors); 26887 const colorObject = allColors.find(({ 26888 color 26889 }) => color === colorValue); 26890 return colorObject ? 'var:preset|color|' + colorObject.slug : colorValue; 26891 }; 26892 const border = (0,external_wp_element_namespaceObject.useMemo)(() => { 26893 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(inheritedValue?.border)) { 26894 const borderValue = { 26895 ...inheritedValue?.border 26896 }; 26897 ['top', 'right', 'bottom', 'left'].forEach(side => { 26898 borderValue[side] = { 26899 ...borderValue[side], 26900 color: decodeValue(borderValue[side]?.color) 26901 }; 26902 }); 26903 return borderValue; 26904 } 26905 return { 26906 ...inheritedValue?.border, 26907 color: inheritedValue?.border?.color ? decodeValue(inheritedValue?.border?.color) : undefined 26908 }; 26909 }, [inheritedValue?.border, decodeValue]); 26910 const setBorder = newBorder => onChange({ 26911 ...value, 26912 border: newBorder 26913 }); 26914 const showBorderColor = useHasBorderColorControl(settings); 26915 const showBorderStyle = useHasBorderStyleControl(settings); 26916 const showBorderWidth = useHasBorderWidthControl(settings); 26917 26918 // Border radius. 26919 const showBorderRadius = useHasBorderRadiusControl(settings); 26920 const borderRadiusValues = decodeValue(border?.radius); 26921 const setBorderRadius = newBorderRadius => setBorder({ 26922 ...border, 26923 radius: newBorderRadius 26924 }); 26925 const hasBorderRadius = () => { 26926 const borderValues = value?.border?.radius; 26927 if (typeof borderValues === 'object') { 26928 return Object.entries(borderValues).some(Boolean); 26929 } 26930 return !!borderValues; 26931 }; 26932 const hasShadowControl = useHasShadowControl(settings); 26933 26934 // Shadow 26935 const shadow = decodeValue(inheritedValue?.shadow); 26936 const shadowPresets = (_settings$shadow$pres = settings?.shadow?.presets) !== null && _settings$shadow$pres !== void 0 ? _settings$shadow$pres : {}; 26937 const mergedShadowPresets = (_ref = (_ref2 = (_shadowPresets$custom = shadowPresets.custom) !== null && _shadowPresets$custom !== void 0 ? _shadowPresets$custom : shadowPresets.theme) !== null && _ref2 !== void 0 ? _ref2 : shadowPresets.default) !== null && _ref !== void 0 ? _ref : []; 26938 const setShadow = newValue => { 26939 const slug = mergedShadowPresets?.find(({ 26940 shadow: shadowName 26941 }) => shadowName === newValue)?.slug; 26942 onChange(setImmutably(value, ['shadow'], slug ? `var:preset|shadow|$slug}` : newValue || undefined)); 26943 }; 26944 const hasShadow = () => !!value?.shadow; 26945 const resetShadow = () => setShadow(undefined); 26946 const resetBorder = () => { 26947 if (hasBorderRadius()) { 26948 return setBorder({ 26949 radius: value?.border?.radius 26950 }); 26951 } 26952 setBorder(undefined); 26953 }; 26954 const onBorderChange = newBorder => { 26955 // Ensure we have a visible border style when a border width or 26956 // color is being selected. 26957 const updatedBorder = { 26958 ...newBorder 26959 }; 26960 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(updatedBorder)) { 26961 ['top', 'right', 'bottom', 'left'].forEach(side => { 26962 if (updatedBorder[side]) { 26963 updatedBorder[side] = { 26964 ...updatedBorder[side], 26965 color: encodeColorValue(updatedBorder[side]?.color) 26966 }; 26967 } 26968 }); 26969 } else if (updatedBorder) { 26970 updatedBorder.color = encodeColorValue(updatedBorder.color); 26971 } 26972 26973 // As radius is maintained separately to color, style, and width 26974 // maintain its value. Undefined values here will be cleaned when 26975 // global styles are saved. 26976 setBorder({ 26977 radius: border?.radius, 26978 ...updatedBorder 26979 }); 26980 }; 26981 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 26982 return { 26983 ...previousValue, 26984 border: undefined, 26985 shadow: undefined 26986 }; 26987 }, []); 26988 const showBorderByDefault = defaultControls?.color || defaultControls?.width; 26989 const hasBorderControl = showBorderColor || showBorderStyle || showBorderWidth || showBorderRadius; 26990 const label = useBorderPanelLabel({ 26991 blockName: name, 26992 hasShadowControl, 26993 hasBorderControl 26994 }); 26995 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Wrapper, { 26996 resetAllFilter: resetAllFilter, 26997 value: value, 26998 onChange: onChange, 26999 panelId: panelId, 27000 label: label, 27001 children: [(showBorderWidth || showBorderColor) && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 27002 hasValue: () => (0,external_wp_components_namespaceObject.__experimentalIsDefinedBorder)(value?.border), 27003 label: (0,external_wp_i18n_namespaceObject.__)('Border'), 27004 onDeselect: () => resetBorder(), 27005 isShownByDefault: showBorderByDefault, 27006 panelId: panelId, 27007 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BorderBoxControl, { 27008 colors: colors, 27009 enableAlpha: true, 27010 enableStyle: showBorderStyle, 27011 onChange: onBorderChange, 27012 popoverOffset: 40, 27013 popoverPlacement: "left-start", 27014 value: border, 27015 __experimentalIsRenderedInSidebar: true, 27016 size: "__unstable-large", 27017 hideLabelFromVision: !hasShadowControl, 27018 label: (0,external_wp_i18n_namespaceObject.__)('Border') 27019 }) 27020 }), showBorderRadius && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 27021 hasValue: hasBorderRadius, 27022 label: (0,external_wp_i18n_namespaceObject.__)('Radius'), 27023 onDeselect: () => setBorderRadius(undefined), 27024 isShownByDefault: defaultControls.radius, 27025 panelId: panelId, 27026 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BorderRadiusControl, { 27027 values: borderRadiusValues, 27028 onChange: newValue => { 27029 setBorderRadius(newValue || undefined); 27030 } 27031 }) 27032 }), hasShadowControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 27033 label: (0,external_wp_i18n_namespaceObject.__)('Shadow'), 27034 hasValue: hasShadow, 27035 onDeselect: resetShadow, 27036 isShownByDefault: defaultControls.shadow, 27037 panelId: panelId, 27038 children: [hasBorderControl ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 27039 as: "legend", 27040 children: (0,external_wp_i18n_namespaceObject.__)('Shadow') 27041 }) : null, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalItemGroup, { 27042 isBordered: true, 27043 isSeparated: true, 27044 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ShadowPopover, { 27045 shadow: shadow, 27046 onShadowChange: setShadow, 27047 settings: settings 27048 }) 27049 })] 27050 })] 27051 }); 27052 } 27053 27054 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/border.js 27055 /** 27056 * External dependencies 27057 */ 27058 27059 27060 /** 27061 * WordPress dependencies 27062 */ 27063 27064 27065 27066 27067 27068 27069 /** 27070 * Internal dependencies 27071 */ 27072 27073 27074 27075 27076 27077 27078 27079 27080 const BORDER_SUPPORT_KEY = '__experimentalBorder'; 27081 const SHADOW_SUPPORT_KEY = 'shadow'; 27082 const getColorByProperty = (colors, property, value) => { 27083 let matchedColor; 27084 colors.some(origin => origin.colors.some(color => { 27085 if (color[property] === value) { 27086 matchedColor = color; 27087 return true; 27088 } 27089 return false; 27090 })); 27091 return matchedColor; 27092 }; 27093 const getMultiOriginColor = ({ 27094 colors, 27095 namedColor, 27096 customColor 27097 }) => { 27098 // Search each origin (default, theme, or user) for matching color by name. 27099 if (namedColor) { 27100 const colorObject = getColorByProperty(colors, 'slug', namedColor); 27101 if (colorObject) { 27102 return colorObject; 27103 } 27104 } 27105 27106 // Skip if no custom color or matching named color. 27107 if (!customColor) { 27108 return { 27109 color: undefined 27110 }; 27111 } 27112 27113 // Attempt to find color via custom color value or build new object. 27114 const colorObject = getColorByProperty(colors, 'color', customColor); 27115 return colorObject ? colorObject : { 27116 color: customColor 27117 }; 27118 }; 27119 function getColorSlugFromVariable(value) { 27120 const namedColor = /var:preset\|color\|(.+)/.exec(value); 27121 if (namedColor && namedColor[1]) { 27122 return namedColor[1]; 27123 } 27124 return null; 27125 } 27126 function styleToAttributes(style) { 27127 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(style?.border)) { 27128 return { 27129 style, 27130 borderColor: undefined 27131 }; 27132 } 27133 const borderColorValue = style?.border?.color; 27134 const borderColorSlug = borderColorValue?.startsWith('var:preset|color|') ? borderColorValue.substring('var:preset|color|'.length) : undefined; 27135 const updatedStyle = { 27136 ...style 27137 }; 27138 updatedStyle.border = { 27139 ...updatedStyle.border, 27140 color: borderColorSlug ? undefined : borderColorValue 27141 }; 27142 return { 27143 style: utils_cleanEmptyObject(updatedStyle), 27144 borderColor: borderColorSlug 27145 }; 27146 } 27147 function attributesToStyle(attributes) { 27148 if ((0,external_wp_components_namespaceObject.__experimentalHasSplitBorders)(attributes.style?.border)) { 27149 return attributes.style; 27150 } 27151 return { 27152 ...attributes.style, 27153 border: { 27154 ...attributes.style?.border, 27155 color: attributes.borderColor ? 'var:preset|color|' + attributes.borderColor : attributes.style?.border?.color 27156 } 27157 }; 27158 } 27159 function BordersInspectorControl({ 27160 label, 27161 children, 27162 resetAllFilter 27163 }) { 27164 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 27165 const existingStyle = attributesToStyle(attributes); 27166 const updatedStyle = resetAllFilter(existingStyle); 27167 return { 27168 ...attributes, 27169 ...styleToAttributes(updatedStyle) 27170 }; 27171 }, [resetAllFilter]); 27172 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 27173 group: "border", 27174 resetAllFilter: attributesResetAllFilter, 27175 label: label, 27176 children: children 27177 }); 27178 } 27179 function border_BorderPanel({ 27180 clientId, 27181 name, 27182 setAttributes, 27183 settings 27184 }) { 27185 const isEnabled = useHasBorderPanel(settings); 27186 function selector(select) { 27187 const { 27188 style, 27189 borderColor 27190 } = select(store).getBlockAttributes(clientId) || {}; 27191 return { 27192 style, 27193 borderColor 27194 }; 27195 } 27196 const { 27197 style, 27198 borderColor 27199 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 27200 const value = (0,external_wp_element_namespaceObject.useMemo)(() => { 27201 return attributesToStyle({ 27202 style, 27203 borderColor 27204 }); 27205 }, [style, borderColor]); 27206 const onChange = newStyle => { 27207 setAttributes(styleToAttributes(newStyle)); 27208 }; 27209 if (!isEnabled) { 27210 return null; 27211 } 27212 const defaultControls = { 27213 ...(0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [BORDER_SUPPORT_KEY, '__experimentalDefaultControls']), 27214 ...(0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [SHADOW_SUPPORT_KEY, '__experimentalDefaultControls']) 27215 }; 27216 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BorderPanel, { 27217 as: BordersInspectorControl, 27218 panelId: clientId, 27219 settings: settings, 27220 value: value, 27221 onChange: onChange, 27222 defaultControls: defaultControls 27223 }); 27224 } 27225 27226 /** 27227 * Determine whether there is block support for border properties. 27228 * 27229 * @param {string} blockName Block name. 27230 * @param {string} feature Border feature to check support for. 27231 * 27232 * @return {boolean} Whether there is support. 27233 */ 27234 function hasBorderSupport(blockName, feature = 'any') { 27235 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 27236 return false; 27237 } 27238 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, BORDER_SUPPORT_KEY); 27239 if (support === true) { 27240 return true; 27241 } 27242 if (feature === 'any') { 27243 return !!(support?.color || support?.radius || support?.width || support?.style); 27244 } 27245 return !!support?.[feature]; 27246 } 27247 27248 /** 27249 * Determine whether there is block support for shadow properties. 27250 * 27251 * @param {string} blockName Block name. 27252 * 27253 * @return {boolean} Whether there is support. 27254 */ 27255 function hasShadowSupport(blockName) { 27256 return hasBlockSupport(blockName, SHADOW_SUPPORT_KEY); 27257 } 27258 function useBorderPanelLabel({ 27259 blockName, 27260 hasBorderControl, 27261 hasShadowControl 27262 } = {}) { 27263 const settings = useBlockSettings(blockName); 27264 const controls = useHasBorderPanelControls(settings); 27265 if (!hasBorderControl && !hasShadowControl && blockName) { 27266 hasBorderControl = controls?.hasBorderColor || controls?.hasBorderStyle || controls?.hasBorderWidth || controls?.hasBorderRadius; 27267 hasShadowControl = controls?.hasShadow; 27268 } 27269 if (hasBorderControl && hasShadowControl) { 27270 return (0,external_wp_i18n_namespaceObject.__)('Border & Shadow'); 27271 } 27272 if (hasShadowControl) { 27273 return (0,external_wp_i18n_namespaceObject.__)('Shadow'); 27274 } 27275 return (0,external_wp_i18n_namespaceObject.__)('Border'); 27276 } 27277 27278 /** 27279 * Returns a new style object where the specified border attribute has been 27280 * removed. 27281 * 27282 * @param {Object} style Styles from block attributes. 27283 * @param {string} attribute The border style attribute to clear. 27284 * 27285 * @return {Object} Style object with the specified attribute removed. 27286 */ 27287 function removeBorderAttribute(style, attribute) { 27288 return cleanEmptyObject({ 27289 ...style, 27290 border: { 27291 ...style?.border, 27292 [attribute]: undefined 27293 } 27294 }); 27295 } 27296 27297 /** 27298 * Filters registered block settings, extending attributes to include 27299 * `borderColor` if needed. 27300 * 27301 * @param {Object} settings Original block settings. 27302 * 27303 * @return {Object} Updated block settings. 27304 */ 27305 function addAttributes(settings) { 27306 if (!hasBorderSupport(settings, 'color')) { 27307 return settings; 27308 } 27309 27310 // Allow blocks to specify default value if needed. 27311 if (settings.attributes.borderColor) { 27312 return settings; 27313 } 27314 27315 // Add new borderColor attribute to block settings. 27316 return { 27317 ...settings, 27318 attributes: { 27319 ...settings.attributes, 27320 borderColor: { 27321 type: 'string' 27322 } 27323 } 27324 }; 27325 } 27326 27327 /** 27328 * Override props assigned to save component to inject border color. 27329 * 27330 * @param {Object} props Additional props applied to save element. 27331 * @param {Object|string} blockNameOrType Block type definition. 27332 * @param {Object} attributes Block's attributes. 27333 * 27334 * @return {Object} Filtered props to apply to save element. 27335 */ 27336 function border_addSaveProps(props, blockNameOrType, attributes) { 27337 if (!hasBorderSupport(blockNameOrType, 'color') || shouldSkipSerialization(blockNameOrType, BORDER_SUPPORT_KEY, 'color')) { 27338 return props; 27339 } 27340 const borderClasses = getBorderClasses(attributes); 27341 const newClassName = dist_clsx(props.className, borderClasses); 27342 27343 // If we are clearing the last of the previous classes in `className` 27344 // set it to `undefined` to avoid rendering empty DOM attributes. 27345 props.className = newClassName ? newClassName : undefined; 27346 return props; 27347 } 27348 27349 /** 27350 * Generates a CSS class name consisting of all the applicable border color 27351 * classes given the current block attributes. 27352 * 27353 * @param {Object} attributes Block's attributes. 27354 * 27355 * @return {string} CSS class name. 27356 */ 27357 function getBorderClasses(attributes) { 27358 const { 27359 borderColor, 27360 style 27361 } = attributes; 27362 const borderColorClass = getColorClassName('border-color', borderColor); 27363 return dist_clsx({ 27364 'has-border-color': borderColor || style?.border?.color, 27365 [borderColorClass]: !!borderColorClass 27366 }); 27367 } 27368 function border_useBlockProps({ 27369 name, 27370 borderColor, 27371 style 27372 }) { 27373 const { 27374 colors 27375 } = useMultipleOriginColorsAndGradients(); 27376 if (!hasBorderSupport(name, 'color') || shouldSkipSerialization(name, BORDER_SUPPORT_KEY, 'color')) { 27377 return {}; 27378 } 27379 const { 27380 color: borderColorValue 27381 } = getMultiOriginColor({ 27382 colors, 27383 namedColor: borderColor 27384 }); 27385 const { 27386 color: borderTopColor 27387 } = getMultiOriginColor({ 27388 colors, 27389 namedColor: getColorSlugFromVariable(style?.border?.top?.color) 27390 }); 27391 const { 27392 color: borderRightColor 27393 } = getMultiOriginColor({ 27394 colors, 27395 namedColor: getColorSlugFromVariable(style?.border?.right?.color) 27396 }); 27397 const { 27398 color: borderBottomColor 27399 } = getMultiOriginColor({ 27400 colors, 27401 namedColor: getColorSlugFromVariable(style?.border?.bottom?.color) 27402 }); 27403 const { 27404 color: borderLeftColor 27405 } = getMultiOriginColor({ 27406 colors, 27407 namedColor: getColorSlugFromVariable(style?.border?.left?.color) 27408 }); 27409 const extraStyles = { 27410 borderTopColor: borderTopColor || borderColorValue, 27411 borderRightColor: borderRightColor || borderColorValue, 27412 borderBottomColor: borderBottomColor || borderColorValue, 27413 borderLeftColor: borderLeftColor || borderColorValue 27414 }; 27415 return border_addSaveProps({ 27416 style: utils_cleanEmptyObject(extraStyles) || {} 27417 }, name, { 27418 borderColor, 27419 style 27420 }); 27421 } 27422 /* harmony default export */ const border = ({ 27423 useBlockProps: border_useBlockProps, 27424 addSaveProps: border_addSaveProps, 27425 attributeKeys: ['borderColor', 'style'], 27426 hasSupport(name) { 27427 return hasBorderSupport(name, 'color'); 27428 } 27429 }); 27430 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/border/addAttributes', addAttributes); 27431 27432 ;// ./node_modules/@wordpress/block-editor/build-module/components/gradients/use-gradient.js 27433 /** 27434 * WordPress dependencies 27435 */ 27436 27437 27438 27439 /** 27440 * Internal dependencies 27441 */ 27442 27443 27444 27445 function __experimentalGetGradientClass(gradientSlug) { 27446 if (!gradientSlug) { 27447 return undefined; 27448 } 27449 return `has-$gradientSlug}-gradient-background`; 27450 } 27451 27452 /** 27453 * Retrieves the gradient value per slug. 27454 * 27455 * @param {Array} gradients Gradient Palette 27456 * @param {string} slug Gradient slug 27457 * 27458 * @return {string} Gradient value. 27459 */ 27460 function getGradientValueBySlug(gradients, slug) { 27461 const gradient = gradients?.find(g => g.slug === slug); 27462 return gradient && gradient.gradient; 27463 } 27464 function __experimentalGetGradientObjectByGradientValue(gradients, value) { 27465 const gradient = gradients?.find(g => g.gradient === value); 27466 return gradient; 27467 } 27468 27469 /** 27470 * Retrieves the gradient slug per slug. 27471 * 27472 * @param {Array} gradients Gradient Palette 27473 * @param {string} value Gradient value 27474 * @return {string} Gradient slug. 27475 */ 27476 function getGradientSlugByValue(gradients, value) { 27477 const gradient = __experimentalGetGradientObjectByGradientValue(gradients, value); 27478 return gradient && gradient.slug; 27479 } 27480 function __experimentalUseGradient({ 27481 gradientAttribute = 'gradient', 27482 customGradientAttribute = 'customGradient' 27483 } = {}) { 27484 const { 27485 clientId 27486 } = useBlockEditContext(); 27487 const [userGradientPalette, themeGradientPalette, defaultGradientPalette] = use_settings_useSettings('color.gradients.custom', 'color.gradients.theme', 'color.gradients.default'); 27488 const allGradients = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userGradientPalette || []), ...(themeGradientPalette || []), ...(defaultGradientPalette || [])], [userGradientPalette, themeGradientPalette, defaultGradientPalette]); 27489 const { 27490 gradient, 27491 customGradient 27492 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 27493 const { 27494 getBlockAttributes 27495 } = select(store); 27496 const attributes = getBlockAttributes(clientId) || {}; 27497 return { 27498 customGradient: attributes[customGradientAttribute], 27499 gradient: attributes[gradientAttribute] 27500 }; 27501 }, [clientId, gradientAttribute, customGradientAttribute]); 27502 const { 27503 updateBlockAttributes 27504 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 27505 const setGradient = (0,external_wp_element_namespaceObject.useCallback)(newGradientValue => { 27506 const slug = getGradientSlugByValue(allGradients, newGradientValue); 27507 if (slug) { 27508 updateBlockAttributes(clientId, { 27509 [gradientAttribute]: slug, 27510 [customGradientAttribute]: undefined 27511 }); 27512 return; 27513 } 27514 updateBlockAttributes(clientId, { 27515 [gradientAttribute]: undefined, 27516 [customGradientAttribute]: newGradientValue 27517 }); 27518 }, [allGradients, clientId, updateBlockAttributes]); 27519 const gradientClass = __experimentalGetGradientClass(gradient); 27520 let gradientValue; 27521 if (gradient) { 27522 gradientValue = getGradientValueBySlug(allGradients, gradient); 27523 } else { 27524 gradientValue = customGradient; 27525 } 27526 return { 27527 gradientClass, 27528 gradientValue, 27529 setGradient 27530 }; 27531 } 27532 27533 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/control.js 27534 /** 27535 * External dependencies 27536 */ 27537 27538 27539 /** 27540 * WordPress dependencies 27541 */ 27542 27543 27544 27545 /** 27546 * Internal dependencies 27547 */ 27548 27549 27550 27551 const { 27552 Tabs 27553 } = unlock(external_wp_components_namespaceObject.privateApis); 27554 const colorsAndGradientKeys = ['colors', 'disableCustomColors', 'gradients', 'disableCustomGradients']; 27555 const TAB_IDS = { 27556 color: 'color', 27557 gradient: 'gradient' 27558 }; 27559 function ColorGradientControlInner({ 27560 colors, 27561 gradients, 27562 disableCustomColors, 27563 disableCustomGradients, 27564 __experimentalIsRenderedInSidebar, 27565 className, 27566 label, 27567 onColorChange, 27568 onGradientChange, 27569 colorValue, 27570 gradientValue, 27571 clearable, 27572 showTitle = true, 27573 enableAlpha, 27574 headingLevel 27575 }) { 27576 const canChooseAColor = onColorChange && (colors && colors.length > 0 || !disableCustomColors); 27577 const canChooseAGradient = onGradientChange && (gradients && gradients.length > 0 || !disableCustomGradients); 27578 if (!canChooseAColor && !canChooseAGradient) { 27579 return null; 27580 } 27581 const tabPanels = { 27582 [TAB_IDS.color]: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ColorPalette, { 27583 value: colorValue, 27584 onChange: canChooseAGradient ? newColor => { 27585 onColorChange(newColor); 27586 onGradientChange(); 27587 } : onColorChange, 27588 colors, 27589 disableCustomColors, 27590 __experimentalIsRenderedInSidebar: __experimentalIsRenderedInSidebar, 27591 clearable: clearable, 27592 enableAlpha: enableAlpha, 27593 headingLevel: headingLevel 27594 }), 27595 [TAB_IDS.gradient]: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.GradientPicker, { 27596 value: gradientValue, 27597 onChange: canChooseAColor ? newGradient => { 27598 onGradientChange(newGradient); 27599 onColorChange(); 27600 } : onGradientChange, 27601 gradients, 27602 disableCustomGradients, 27603 __experimentalIsRenderedInSidebar: __experimentalIsRenderedInSidebar, 27604 clearable: clearable, 27605 headingLevel: headingLevel 27606 }) 27607 }; 27608 const renderPanelType = type => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 27609 className: "block-editor-color-gradient-control__panel", 27610 children: tabPanels[type] 27611 }); 27612 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl, { 27613 __nextHasNoMarginBottom: true, 27614 className: dist_clsx('block-editor-color-gradient-control', className), 27615 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("fieldset", { 27616 className: "block-editor-color-gradient-control__fieldset", 27617 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 27618 spacing: 1, 27619 children: [showTitle && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("legend", { 27620 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 27621 className: "block-editor-color-gradient-control__color-indicator", 27622 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 27623 children: label 27624 }) 27625 }) 27626 }), canChooseAColor && canChooseAGradient && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 27627 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Tabs, { 27628 defaultTabId: gradientValue ? TAB_IDS.gradient : !!canChooseAColor && TAB_IDS.color, 27629 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Tabs.TabList, { 27630 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tabs.Tab, { 27631 tabId: TAB_IDS.color, 27632 children: (0,external_wp_i18n_namespaceObject.__)('Color') 27633 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tabs.Tab, { 27634 tabId: TAB_IDS.gradient, 27635 children: (0,external_wp_i18n_namespaceObject.__)('Gradient') 27636 })] 27637 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tabs.TabPanel, { 27638 tabId: TAB_IDS.color, 27639 className: "block-editor-color-gradient-control__panel", 27640 focusable: false, 27641 children: tabPanels.color 27642 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tabs.TabPanel, { 27643 tabId: TAB_IDS.gradient, 27644 className: "block-editor-color-gradient-control__panel", 27645 focusable: false, 27646 children: tabPanels.gradient 27647 })] 27648 }) 27649 }), !canChooseAGradient && renderPanelType(TAB_IDS.color), !canChooseAColor && renderPanelType(TAB_IDS.gradient)] 27650 }) 27651 }) 27652 }); 27653 } 27654 function ColorGradientControlSelect(props) { 27655 const [colors, gradients, customColors, customGradients] = use_settings_useSettings('color.palette', 'color.gradients', 'color.custom', 'color.customGradient'); 27656 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorGradientControlInner, { 27657 colors: colors, 27658 gradients: gradients, 27659 disableCustomColors: !customColors, 27660 disableCustomGradients: !customGradients, 27661 ...props 27662 }); 27663 } 27664 function ColorGradientControl(props) { 27665 if (colorsAndGradientKeys.every(key => props.hasOwnProperty(key))) { 27666 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorGradientControlInner, { 27667 ...props 27668 }); 27669 } 27670 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorGradientControlSelect, { 27671 ...props 27672 }); 27673 } 27674 /* harmony default export */ const control = (ColorGradientControl); 27675 27676 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/color-panel.js 27677 /** 27678 * External dependencies 27679 */ 27680 27681 27682 /** 27683 * WordPress dependencies 27684 */ 27685 27686 27687 27688 27689 /** 27690 * Internal dependencies 27691 */ 27692 27693 27694 27695 27696 27697 27698 27699 function useHasColorPanel(settings) { 27700 const hasTextPanel = useHasTextPanel(settings); 27701 const hasBackgroundPanel = useHasBackgroundColorPanel(settings); 27702 const hasLinkPanel = useHasLinkPanel(settings); 27703 const hasHeadingPanel = useHasHeadingPanel(settings); 27704 const hasButtonPanel = useHasButtonPanel(settings); 27705 const hasCaptionPanel = useHasCaptionPanel(settings); 27706 return hasTextPanel || hasBackgroundPanel || hasLinkPanel || hasHeadingPanel || hasButtonPanel || hasCaptionPanel; 27707 } 27708 function useHasTextPanel(settings) { 27709 const colors = useColorsPerOrigin(settings); 27710 return settings?.color?.text && (colors?.length > 0 || settings?.color?.custom); 27711 } 27712 function useHasLinkPanel(settings) { 27713 const colors = useColorsPerOrigin(settings); 27714 return settings?.color?.link && (colors?.length > 0 || settings?.color?.custom); 27715 } 27716 function useHasCaptionPanel(settings) { 27717 const colors = useColorsPerOrigin(settings); 27718 return settings?.color?.caption && (colors?.length > 0 || settings?.color?.custom); 27719 } 27720 function useHasHeadingPanel(settings) { 27721 const colors = useColorsPerOrigin(settings); 27722 const gradients = useGradientsPerOrigin(settings); 27723 return settings?.color?.heading && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); 27724 } 27725 function useHasButtonPanel(settings) { 27726 const colors = useColorsPerOrigin(settings); 27727 const gradients = useGradientsPerOrigin(settings); 27728 return settings?.color?.button && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); 27729 } 27730 function useHasBackgroundColorPanel(settings) { 27731 const colors = useColorsPerOrigin(settings); 27732 const gradients = useGradientsPerOrigin(settings); 27733 return settings?.color?.background && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); 27734 } 27735 function ColorToolsPanel({ 27736 resetAllFilter, 27737 onChange, 27738 value, 27739 panelId, 27740 children 27741 }) { 27742 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 27743 const resetAll = () => { 27744 const updatedValue = resetAllFilter(value); 27745 onChange(updatedValue); 27746 }; 27747 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 27748 label: (0,external_wp_i18n_namespaceObject.__)('Elements'), 27749 resetAll: resetAll, 27750 panelId: panelId, 27751 hasInnerWrapper: true, 27752 headingLevel: 3, 27753 className: "color-block-support-panel", 27754 __experimentalFirstVisibleItemClass: "first", 27755 __experimentalLastVisibleItemClass: "last", 27756 dropdownMenuProps: dropdownMenuProps, 27757 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 27758 className: "color-block-support-panel__inner-wrapper", 27759 children: children 27760 }) 27761 }); 27762 } 27763 const color_panel_DEFAULT_CONTROLS = { 27764 text: true, 27765 background: true, 27766 link: true, 27767 heading: true, 27768 button: true, 27769 caption: true 27770 }; 27771 const popoverProps = { 27772 placement: 'left-start', 27773 offset: 36, 27774 shift: true 27775 }; 27776 const { 27777 Tabs: color_panel_Tabs 27778 } = unlock(external_wp_components_namespaceObject.privateApis); 27779 const LabeledColorIndicators = ({ 27780 indicators, 27781 label 27782 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 27783 justify: "flex-start", 27784 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalZStack, { 27785 isLayered: false, 27786 offset: -8, 27787 children: indicators.map((indicator, index) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Flex, { 27788 expanded: false, 27789 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ColorIndicator, { 27790 colorValue: indicator 27791 }) 27792 }, index)) 27793 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 27794 className: "block-editor-panel-color-gradient-settings__color-name", 27795 children: label 27796 })] 27797 }); 27798 function ColorPanelTab({ 27799 isGradient, 27800 inheritedValue, 27801 userValue, 27802 setValue, 27803 colorGradientControlSettings 27804 }) { 27805 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(control, { 27806 ...colorGradientControlSettings, 27807 showTitle: false, 27808 enableAlpha: true, 27809 __experimentalIsRenderedInSidebar: true, 27810 colorValue: isGradient ? undefined : inheritedValue, 27811 gradientValue: isGradient ? inheritedValue : undefined, 27812 onColorChange: isGradient ? undefined : setValue, 27813 onGradientChange: isGradient ? setValue : undefined, 27814 clearable: inheritedValue === userValue, 27815 headingLevel: 3 27816 }); 27817 } 27818 function ColorPanelDropdown({ 27819 label, 27820 hasValue, 27821 resetValue, 27822 isShownByDefault, 27823 indicators, 27824 tabs, 27825 colorGradientControlSettings, 27826 panelId 27827 }) { 27828 var _tabs$; 27829 const currentTab = tabs.find(tab => tab.userValue !== undefined); 27830 const { 27831 key: firstTabKey, 27832 ...firstTab 27833 } = (_tabs$ = tabs[0]) !== null && _tabs$ !== void 0 ? _tabs$ : {}; 27834 const colorGradientDropdownButtonRef = (0,external_wp_element_namespaceObject.useRef)(undefined); 27835 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 27836 className: "block-editor-tools-panel-color-gradient-settings__item", 27837 hasValue: hasValue, 27838 label: label, 27839 onDeselect: resetValue, 27840 isShownByDefault: isShownByDefault, 27841 panelId: panelId, 27842 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 27843 popoverProps: popoverProps, 27844 className: "block-editor-tools-panel-color-gradient-settings__dropdown", 27845 renderToggle: ({ 27846 onToggle, 27847 isOpen 27848 }) => { 27849 const toggleProps = { 27850 onClick: onToggle, 27851 className: dist_clsx('block-editor-panel-color-gradient-settings__dropdown', { 27852 'is-open': isOpen 27853 }), 27854 'aria-expanded': isOpen, 27855 ref: colorGradientDropdownButtonRef 27856 }; 27857 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 27858 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 27859 ...toggleProps, 27860 __next40pxDefaultSize: true, 27861 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LabeledColorIndicators, { 27862 indicators: indicators, 27863 label: label 27864 }) 27865 }), hasValue() && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 27866 __next40pxDefaultSize: true, 27867 label: (0,external_wp_i18n_namespaceObject.__)('Reset'), 27868 className: "block-editor-panel-color-gradient-settings__reset", 27869 size: "small", 27870 icon: library_reset, 27871 onClick: () => { 27872 resetValue(); 27873 if (isOpen) { 27874 onToggle(); 27875 } 27876 // Return focus to parent button 27877 colorGradientDropdownButtonRef.current?.focus(); 27878 } 27879 })] 27880 }); 27881 }, 27882 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 27883 paddingSize: "none", 27884 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 27885 className: "block-editor-panel-color-gradient-settings__dropdown-content", 27886 children: [tabs.length === 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorPanelTab, { 27887 ...firstTab, 27888 colorGradientControlSettings: colorGradientControlSettings 27889 }, firstTabKey), tabs.length > 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(color_panel_Tabs, { 27890 defaultTabId: currentTab?.key, 27891 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(color_panel_Tabs.TabList, { 27892 children: tabs.map(tab => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(color_panel_Tabs.Tab, { 27893 tabId: tab.key, 27894 children: tab.label 27895 }, tab.key)) 27896 }), tabs.map(tab => { 27897 const { 27898 key: tabKey, 27899 ...restTabProps 27900 } = tab; 27901 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(color_panel_Tabs.TabPanel, { 27902 tabId: tabKey, 27903 focusable: false, 27904 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorPanelTab, { 27905 ...restTabProps, 27906 colorGradientControlSettings: colorGradientControlSettings 27907 }, tabKey) 27908 }, tabKey); 27909 })] 27910 })] 27911 }) 27912 }) 27913 }) 27914 }); 27915 } 27916 function ColorPanel({ 27917 as: Wrapper = ColorToolsPanel, 27918 value, 27919 onChange, 27920 inheritedValue = value, 27921 settings, 27922 panelId, 27923 defaultControls = color_panel_DEFAULT_CONTROLS, 27924 children 27925 }) { 27926 const colors = useColorsPerOrigin(settings); 27927 const gradients = useGradientsPerOrigin(settings); 27928 const areCustomSolidsEnabled = settings?.color?.custom; 27929 const areCustomGradientsEnabled = settings?.color?.customGradient; 27930 const hasSolidColors = colors.length > 0 || areCustomSolidsEnabled; 27931 const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled; 27932 const decodeValue = rawValue => getValueFromVariable({ 27933 settings 27934 }, '', rawValue); 27935 const encodeColorValue = colorValue => { 27936 const allColors = colors.flatMap(({ 27937 colors: originColors 27938 }) => originColors); 27939 const colorObject = allColors.find(({ 27940 color 27941 }) => color === colorValue); 27942 return colorObject ? 'var:preset|color|' + colorObject.slug : colorValue; 27943 }; 27944 const encodeGradientValue = gradientValue => { 27945 const allGradients = gradients.flatMap(({ 27946 gradients: originGradients 27947 }) => originGradients); 27948 const gradientObject = allGradients.find(({ 27949 gradient 27950 }) => gradient === gradientValue); 27951 return gradientObject ? 'var:preset|gradient|' + gradientObject.slug : gradientValue; 27952 }; 27953 27954 // BackgroundColor 27955 const showBackgroundPanel = useHasBackgroundColorPanel(settings); 27956 const backgroundColor = decodeValue(inheritedValue?.color?.background); 27957 const userBackgroundColor = decodeValue(value?.color?.background); 27958 const gradient = decodeValue(inheritedValue?.color?.gradient); 27959 const userGradient = decodeValue(value?.color?.gradient); 27960 const hasBackground = () => !!userBackgroundColor || !!userGradient; 27961 const setBackgroundColor = newColor => { 27962 const newValue = setImmutably(value, ['color', 'background'], encodeColorValue(newColor)); 27963 newValue.color.gradient = undefined; 27964 onChange(newValue); 27965 }; 27966 const setGradient = newGradient => { 27967 const newValue = setImmutably(value, ['color', 'gradient'], encodeGradientValue(newGradient)); 27968 newValue.color.background = undefined; 27969 onChange(newValue); 27970 }; 27971 const resetBackground = () => { 27972 const newValue = setImmutably(value, ['color', 'background'], undefined); 27973 newValue.color.gradient = undefined; 27974 onChange(newValue); 27975 }; 27976 27977 // Links 27978 const showLinkPanel = useHasLinkPanel(settings); 27979 const linkColor = decodeValue(inheritedValue?.elements?.link?.color?.text); 27980 const userLinkColor = decodeValue(value?.elements?.link?.color?.text); 27981 const setLinkColor = newColor => { 27982 onChange(setImmutably(value, ['elements', 'link', 'color', 'text'], encodeColorValue(newColor))); 27983 }; 27984 const hoverLinkColor = decodeValue(inheritedValue?.elements?.link?.[':hover']?.color?.text); 27985 const userHoverLinkColor = decodeValue(value?.elements?.link?.[':hover']?.color?.text); 27986 const setHoverLinkColor = newColor => { 27987 onChange(setImmutably(value, ['elements', 'link', ':hover', 'color', 'text'], encodeColorValue(newColor))); 27988 }; 27989 const hasLink = () => !!userLinkColor || !!userHoverLinkColor; 27990 const resetLink = () => { 27991 let newValue = setImmutably(value, ['elements', 'link', ':hover', 'color', 'text'], undefined); 27992 newValue = setImmutably(newValue, ['elements', 'link', 'color', 'text'], undefined); 27993 onChange(newValue); 27994 }; 27995 27996 // Text Color 27997 const showTextPanel = useHasTextPanel(settings); 27998 const textColor = decodeValue(inheritedValue?.color?.text); 27999 const userTextColor = decodeValue(value?.color?.text); 28000 const hasTextColor = () => !!userTextColor; 28001 const setTextColor = newColor => { 28002 let changedObject = setImmutably(value, ['color', 'text'], encodeColorValue(newColor)); 28003 if (textColor === linkColor) { 28004 changedObject = setImmutably(changedObject, ['elements', 'link', 'color', 'text'], encodeColorValue(newColor)); 28005 } 28006 onChange(changedObject); 28007 }; 28008 const resetTextColor = () => setTextColor(undefined); 28009 28010 // Elements 28011 const elements = [{ 28012 name: 'caption', 28013 label: (0,external_wp_i18n_namespaceObject.__)('Captions'), 28014 showPanel: useHasCaptionPanel(settings) 28015 }, { 28016 name: 'button', 28017 label: (0,external_wp_i18n_namespaceObject.__)('Button'), 28018 showPanel: useHasButtonPanel(settings) 28019 }, { 28020 name: 'heading', 28021 label: (0,external_wp_i18n_namespaceObject.__)('Heading'), 28022 showPanel: useHasHeadingPanel(settings) 28023 }, { 28024 name: 'h1', 28025 label: (0,external_wp_i18n_namespaceObject.__)('H1'), 28026 showPanel: useHasHeadingPanel(settings) 28027 }, { 28028 name: 'h2', 28029 label: (0,external_wp_i18n_namespaceObject.__)('H2'), 28030 showPanel: useHasHeadingPanel(settings) 28031 }, { 28032 name: 'h3', 28033 label: (0,external_wp_i18n_namespaceObject.__)('H3'), 28034 showPanel: useHasHeadingPanel(settings) 28035 }, { 28036 name: 'h4', 28037 label: (0,external_wp_i18n_namespaceObject.__)('H4'), 28038 showPanel: useHasHeadingPanel(settings) 28039 }, { 28040 name: 'h5', 28041 label: (0,external_wp_i18n_namespaceObject.__)('H5'), 28042 showPanel: useHasHeadingPanel(settings) 28043 }, { 28044 name: 'h6', 28045 label: (0,external_wp_i18n_namespaceObject.__)('H6'), 28046 showPanel: useHasHeadingPanel(settings) 28047 }]; 28048 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 28049 return { 28050 ...previousValue, 28051 color: undefined, 28052 elements: { 28053 ...previousValue?.elements, 28054 link: { 28055 ...previousValue?.elements?.link, 28056 color: undefined, 28057 ':hover': { 28058 color: undefined 28059 } 28060 }, 28061 ...elements.reduce((acc, element) => { 28062 return { 28063 ...acc, 28064 [element.name]: { 28065 ...previousValue?.elements?.[element.name], 28066 color: undefined 28067 } 28068 }; 28069 }, {}) 28070 } 28071 }; 28072 }, []); 28073 const items = [showTextPanel && { 28074 key: 'text', 28075 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 28076 hasValue: hasTextColor, 28077 resetValue: resetTextColor, 28078 isShownByDefault: defaultControls.text, 28079 indicators: [textColor], 28080 tabs: [{ 28081 key: 'text', 28082 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 28083 inheritedValue: textColor, 28084 setValue: setTextColor, 28085 userValue: userTextColor 28086 }] 28087 }, showBackgroundPanel && { 28088 key: 'background', 28089 label: (0,external_wp_i18n_namespaceObject.__)('Background'), 28090 hasValue: hasBackground, 28091 resetValue: resetBackground, 28092 isShownByDefault: defaultControls.background, 28093 indicators: [gradient !== null && gradient !== void 0 ? gradient : backgroundColor], 28094 tabs: [hasSolidColors && { 28095 key: 'background', 28096 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 28097 inheritedValue: backgroundColor, 28098 setValue: setBackgroundColor, 28099 userValue: userBackgroundColor 28100 }, hasGradientColors && { 28101 key: 'gradient', 28102 label: (0,external_wp_i18n_namespaceObject.__)('Gradient'), 28103 inheritedValue: gradient, 28104 setValue: setGradient, 28105 userValue: userGradient, 28106 isGradient: true 28107 }].filter(Boolean) 28108 }, showLinkPanel && { 28109 key: 'link', 28110 label: (0,external_wp_i18n_namespaceObject.__)('Link'), 28111 hasValue: hasLink, 28112 resetValue: resetLink, 28113 isShownByDefault: defaultControls.link, 28114 indicators: [linkColor, hoverLinkColor], 28115 tabs: [{ 28116 key: 'link', 28117 label: (0,external_wp_i18n_namespaceObject.__)('Default'), 28118 inheritedValue: linkColor, 28119 setValue: setLinkColor, 28120 userValue: userLinkColor 28121 }, { 28122 key: 'hover', 28123 label: (0,external_wp_i18n_namespaceObject.__)('Hover'), 28124 inheritedValue: hoverLinkColor, 28125 setValue: setHoverLinkColor, 28126 userValue: userHoverLinkColor 28127 }] 28128 }].filter(Boolean); 28129 elements.forEach(({ 28130 name, 28131 label, 28132 showPanel 28133 }) => { 28134 if (!showPanel) { 28135 return; 28136 } 28137 const elementBackgroundColor = decodeValue(inheritedValue?.elements?.[name]?.color?.background); 28138 const elementGradient = decodeValue(inheritedValue?.elements?.[name]?.color?.gradient); 28139 const elementTextColor = decodeValue(inheritedValue?.elements?.[name]?.color?.text); 28140 const elementBackgroundUserColor = decodeValue(value?.elements?.[name]?.color?.background); 28141 const elementGradientUserColor = decodeValue(value?.elements?.[name]?.color?.gradient); 28142 const elementTextUserColor = decodeValue(value?.elements?.[name]?.color?.text); 28143 const hasElement = () => !!(elementTextUserColor || elementBackgroundUserColor || elementGradientUserColor); 28144 const resetElement = () => { 28145 const newValue = setImmutably(value, ['elements', name, 'color', 'background'], undefined); 28146 newValue.elements[name].color.gradient = undefined; 28147 newValue.elements[name].color.text = undefined; 28148 onChange(newValue); 28149 }; 28150 const setElementTextColor = newTextColor => { 28151 onChange(setImmutably(value, ['elements', name, 'color', 'text'], encodeColorValue(newTextColor))); 28152 }; 28153 const setElementBackgroundColor = newBackgroundColor => { 28154 const newValue = setImmutably(value, ['elements', name, 'color', 'background'], encodeColorValue(newBackgroundColor)); 28155 newValue.elements[name].color.gradient = undefined; 28156 onChange(newValue); 28157 }; 28158 const setElementGradient = newGradient => { 28159 const newValue = setImmutably(value, ['elements', name, 'color', 'gradient'], encodeGradientValue(newGradient)); 28160 newValue.elements[name].color.background = undefined; 28161 onChange(newValue); 28162 }; 28163 const supportsTextColor = true; 28164 // Background color is not supported for `caption` 28165 // as there isn't yet a way to set padding for the element. 28166 const supportsBackground = name !== 'caption'; 28167 items.push({ 28168 key: name, 28169 label, 28170 hasValue: hasElement, 28171 resetValue: resetElement, 28172 isShownByDefault: defaultControls[name], 28173 indicators: supportsTextColor && supportsBackground ? [elementTextColor, elementGradient !== null && elementGradient !== void 0 ? elementGradient : elementBackgroundColor] : [supportsTextColor ? elementTextColor : elementGradient !== null && elementGradient !== void 0 ? elementGradient : elementBackgroundColor], 28174 tabs: [hasSolidColors && supportsTextColor && { 28175 key: 'text', 28176 label: (0,external_wp_i18n_namespaceObject.__)('Text'), 28177 inheritedValue: elementTextColor, 28178 setValue: setElementTextColor, 28179 userValue: elementTextUserColor 28180 }, hasSolidColors && supportsBackground && { 28181 key: 'background', 28182 label: (0,external_wp_i18n_namespaceObject.__)('Background'), 28183 inheritedValue: elementBackgroundColor, 28184 setValue: setElementBackgroundColor, 28185 userValue: elementBackgroundUserColor 28186 }, hasGradientColors && supportsBackground && { 28187 key: 'gradient', 28188 label: (0,external_wp_i18n_namespaceObject.__)('Gradient'), 28189 inheritedValue: elementGradient, 28190 setValue: setElementGradient, 28191 userValue: elementGradientUserColor, 28192 isGradient: true 28193 }].filter(Boolean) 28194 }); 28195 }); 28196 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Wrapper, { 28197 resetAllFilter: resetAllFilter, 28198 value: value, 28199 onChange: onChange, 28200 panelId: panelId, 28201 children: [items.map(item => { 28202 const { 28203 key, 28204 ...restItem 28205 } = item; 28206 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorPanelDropdown, { 28207 ...restItem, 28208 colorGradientControlSettings: { 28209 colors, 28210 disableCustomColors: !areCustomSolidsEnabled, 28211 gradients, 28212 disableCustomGradients: !areCustomGradientsEnabled 28213 }, 28214 panelId: panelId 28215 }, key); 28216 }), children] 28217 }); 28218 } 28219 28220 ;// ./node_modules/@wordpress/block-editor/build-module/components/contrast-checker/index.js 28221 /** 28222 * External dependencies 28223 */ 28224 28225 28226 28227 28228 /** 28229 * WordPress dependencies 28230 */ 28231 28232 28233 28234 28235 k([names, a11y]); 28236 function ContrastChecker({ 28237 backgroundColor, 28238 fallbackBackgroundColor, 28239 fallbackTextColor, 28240 fallbackLinkColor, 28241 fontSize, 28242 // Font size value in pixels. 28243 isLargeText, 28244 textColor, 28245 linkColor, 28246 enableAlphaChecker = false 28247 }) { 28248 const currentBackgroundColor = backgroundColor || fallbackBackgroundColor; 28249 28250 // Must have a background color. 28251 if (!currentBackgroundColor) { 28252 return null; 28253 } 28254 const currentTextColor = textColor || fallbackTextColor; 28255 const currentLinkColor = linkColor || fallbackLinkColor; 28256 28257 // Must have at least one text color. 28258 if (!currentTextColor && !currentLinkColor) { 28259 return null; 28260 } 28261 const textColors = [{ 28262 color: currentTextColor, 28263 description: (0,external_wp_i18n_namespaceObject.__)('text color') 28264 }, { 28265 color: currentLinkColor, 28266 description: (0,external_wp_i18n_namespaceObject.__)('link color') 28267 }]; 28268 const colordBackgroundColor = w(currentBackgroundColor); 28269 const backgroundColorHasTransparency = colordBackgroundColor.alpha() < 1; 28270 const backgroundColorBrightness = colordBackgroundColor.brightness(); 28271 const isReadableOptions = { 28272 level: 'AA', 28273 size: isLargeText || isLargeText !== false && fontSize >= 24 ? 'large' : 'small' 28274 }; 28275 let message = ''; 28276 let speakMessage = ''; 28277 for (const item of textColors) { 28278 // If there is no color, go no further. 28279 if (!item.color) { 28280 continue; 28281 } 28282 const colordTextColor = w(item.color); 28283 const isColordTextReadable = colordTextColor.isReadable(colordBackgroundColor, isReadableOptions); 28284 const textHasTransparency = colordTextColor.alpha() < 1; 28285 28286 // If the contrast is not readable. 28287 if (!isColordTextReadable) { 28288 // Don't show the message if the background or text is transparent. 28289 if (backgroundColorHasTransparency || textHasTransparency) { 28290 continue; 28291 } 28292 message = backgroundColorBrightness < colordTextColor.brightness() ? (0,external_wp_i18n_namespaceObject.sprintf)( 28293 // translators: %s is a type of text color, e.g., "text color" or "link color". 28294 (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)( 28295 // translators: %s is a type of text color, e.g., "text color" or "link color". 28296 (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); 28297 speakMessage = (0,external_wp_i18n_namespaceObject.__)('This color combination may be hard for people to read.'); 28298 // Break from the loop when we have a contrast warning. 28299 // These messages take priority over the transparency warning. 28300 break; 28301 } 28302 28303 // If there is no contrast warning and the text is transparent, 28304 // show the transparent warning if alpha check is enabled. 28305 if (textHasTransparency && enableAlphaChecker) { 28306 message = (0,external_wp_i18n_namespaceObject.__)('Transparent text may be hard for people to read.'); 28307 speakMessage = (0,external_wp_i18n_namespaceObject.__)('Transparent text may be hard for people to read.'); 28308 } 28309 } 28310 if (!message) { 28311 return null; 28312 } 28313 28314 // Note: The `Notice` component can speak messages via its `spokenMessage` 28315 // prop, but the contrast checker requires granular control over when the 28316 // announcements are made. Notably, the message will be re-announced if a 28317 // new color combination is selected and the contrast is still insufficient. 28318 (0,external_wp_a11y_namespaceObject.speak)(speakMessage); 28319 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 28320 className: "block-editor-contrast-checker", 28321 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Notice, { 28322 spokenMessage: null, 28323 status: "warning", 28324 isDismissible: false, 28325 children: message 28326 }) 28327 }); 28328 } 28329 28330 /** 28331 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/contrast-checker/README.md 28332 */ 28333 /* harmony default export */ const contrast_checker = (ContrastChecker); 28334 28335 ;// ./node_modules/@wordpress/block-editor/build-module/components/provider/block-refs-provider.js 28336 /** 28337 * WordPress dependencies 28338 */ 28339 28340 28341 28342 const BlockRefs = (0,external_wp_element_namespaceObject.createContext)({ 28343 refsMap: (0,external_wp_compose_namespaceObject.observableMap)() 28344 }); 28345 function BlockRefsProvider({ 28346 children 28347 }) { 28348 const value = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 28349 refsMap: (0,external_wp_compose_namespaceObject.observableMap)() 28350 }), []); 28351 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockRefs.Provider, { 28352 value: value, 28353 children: children 28354 }); 28355 } 28356 28357 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-refs.js 28358 /** 28359 * WordPress dependencies 28360 */ 28361 28362 28363 28364 /** 28365 * Internal dependencies 28366 */ 28367 28368 28369 /** @typedef {import('@wordpress/element').RefCallback} RefCallback */ 28370 /** @typedef {import('@wordpress/element').Ref} Ref */ 28371 28372 /** 28373 * Provides a ref to the BlockRefs context. 28374 * 28375 * @param {string} clientId The client ID of the element ref. 28376 * 28377 * @return {RefCallback} Ref callback. 28378 */ 28379 function useBlockRefProvider(clientId) { 28380 const { 28381 refsMap 28382 } = (0,external_wp_element_namespaceObject.useContext)(BlockRefs); 28383 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 28384 refsMap.set(clientId, element); 28385 return () => refsMap.delete(clientId); 28386 }, [clientId]); 28387 } 28388 function assignRef(ref, value) { 28389 if (typeof ref === 'function') { 28390 ref(value); 28391 } else if (ref) { 28392 ref.current = value; 28393 } 28394 } 28395 28396 /** 28397 * Tracks the DOM element for the block identified by `clientId` and assigns it to the `ref` 28398 * whenever it changes. 28399 * 28400 * @param {string} clientId The client ID to track. 28401 * @param {Ref} ref The ref object/callback to assign to. 28402 */ 28403 function useBlockElementRef(clientId, ref) { 28404 const { 28405 refsMap 28406 } = (0,external_wp_element_namespaceObject.useContext)(BlockRefs); 28407 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 28408 assignRef(ref, refsMap.get(clientId)); 28409 const unsubscribe = refsMap.subscribe(clientId, () => assignRef(ref, refsMap.get(clientId))); 28410 return () => { 28411 unsubscribe(); 28412 assignRef(ref, null); 28413 }; 28414 }, [refsMap, clientId, ref]); 28415 } 28416 28417 /** 28418 * Return the element for a given client ID. Updates whenever the element 28419 * changes, becomes available, or disappears. 28420 * 28421 * @param {string} clientId The client ID to an element for. 28422 * 28423 * @return {Element|null} The block's wrapper element. 28424 */ 28425 function useBlockElement(clientId) { 28426 const [blockElement, setBlockElement] = (0,external_wp_element_namespaceObject.useState)(null); 28427 useBlockElementRef(clientId, setBlockElement); 28428 return blockElement; 28429 } 28430 28431 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/contrast-checker.js 28432 /** 28433 * WordPress dependencies 28434 */ 28435 28436 28437 /** 28438 * Internal dependencies 28439 */ 28440 28441 28442 28443 function getComputedValue(node, property) { 28444 return node.ownerDocument.defaultView.getComputedStyle(node).getPropertyValue(property); 28445 } 28446 function getBlockElementColors(blockEl) { 28447 if (!blockEl) { 28448 return {}; 28449 } 28450 const firstLinkElement = blockEl.querySelector('a'); 28451 const linkColor = !!firstLinkElement?.innerText ? getComputedValue(firstLinkElement, 'color') : undefined; 28452 const textColor = getComputedValue(blockEl, 'color'); 28453 let backgroundColorNode = blockEl; 28454 let backgroundColor = getComputedValue(backgroundColorNode, 'background-color'); 28455 while (backgroundColor === 'rgba(0, 0, 0, 0)' && backgroundColorNode.parentNode && backgroundColorNode.parentNode.nodeType === backgroundColorNode.parentNode.ELEMENT_NODE) { 28456 backgroundColorNode = backgroundColorNode.parentNode; 28457 backgroundColor = getComputedValue(backgroundColorNode, 'background-color'); 28458 } 28459 return { 28460 textColor, 28461 backgroundColor, 28462 linkColor 28463 }; 28464 } 28465 function contrast_checker_reducer(prevColors, newColors) { 28466 const hasChanged = Object.keys(newColors).some(key => prevColors[key] !== newColors[key]); 28467 28468 // Do not re-render if the colors have not changed. 28469 return hasChanged ? newColors : prevColors; 28470 } 28471 function BlockColorContrastChecker({ 28472 clientId 28473 }) { 28474 const blockEl = useBlockElement(clientId); 28475 const [colors, setColors] = (0,external_wp_element_namespaceObject.useReducer)(contrast_checker_reducer, {}); 28476 28477 // There are so many things that can change the color of a block 28478 // So we perform this check on every render. 28479 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 28480 if (!blockEl) { 28481 return; 28482 } 28483 function updateColors() { 28484 setColors(getBlockElementColors(blockEl)); 28485 } 28486 28487 // Combine `useLayoutEffect` and two rAF calls to ensure that values are read 28488 // after the current paint but before the next paint. 28489 window.requestAnimationFrame(() => window.requestAnimationFrame(updateColors)); 28490 }); 28491 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(contrast_checker, { 28492 backgroundColor: colors.backgroundColor, 28493 textColor: colors.textColor, 28494 linkColor: colors.linkColor, 28495 enableAlphaChecker: true 28496 }); 28497 } 28498 28499 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/color.js 28500 /** 28501 * External dependencies 28502 */ 28503 28504 28505 /** 28506 * WordPress dependencies 28507 */ 28508 28509 28510 28511 28512 28513 /** 28514 * Internal dependencies 28515 */ 28516 28517 28518 28519 28520 28521 28522 28523 28524 28525 28526 const COLOR_SUPPORT_KEY = 'color'; 28527 const hasColorSupport = blockNameOrType => { 28528 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, COLOR_SUPPORT_KEY); 28529 return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false); 28530 }; 28531 const hasLinkColorSupport = blockType => { 28532 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 28533 return false; 28534 } 28535 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); 28536 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link; 28537 }; 28538 const hasGradientSupport = blockNameOrType => { 28539 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, COLOR_SUPPORT_KEY); 28540 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients; 28541 }; 28542 const hasBackgroundColorSupport = blockType => { 28543 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); 28544 return colorSupport && colorSupport.background !== false; 28545 }; 28546 const hasTextColorSupport = blockType => { 28547 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, COLOR_SUPPORT_KEY); 28548 return colorSupport && colorSupport.text !== false; 28549 }; 28550 28551 /** 28552 * Filters registered block settings, extending attributes to include 28553 * `backgroundColor` and `textColor` attribute. 28554 * 28555 * @param {Object} settings Original block settings. 28556 * 28557 * @return {Object} Filtered block settings. 28558 */ 28559 function color_addAttributes(settings) { 28560 if (!hasColorSupport(settings)) { 28561 return settings; 28562 } 28563 28564 // Allow blocks to specify their own attribute definition with default values if needed. 28565 if (!settings.attributes.backgroundColor) { 28566 Object.assign(settings.attributes, { 28567 backgroundColor: { 28568 type: 'string' 28569 } 28570 }); 28571 } 28572 if (!settings.attributes.textColor) { 28573 Object.assign(settings.attributes, { 28574 textColor: { 28575 type: 'string' 28576 } 28577 }); 28578 } 28579 if (hasGradientSupport(settings) && !settings.attributes.gradient) { 28580 Object.assign(settings.attributes, { 28581 gradient: { 28582 type: 'string' 28583 } 28584 }); 28585 } 28586 return settings; 28587 } 28588 28589 /** 28590 * Override props assigned to save component to inject colors classnames. 28591 * 28592 * @param {Object} props Additional props applied to save element. 28593 * @param {Object|string} blockNameOrType Block type. 28594 * @param {Object} attributes Block attributes. 28595 * 28596 * @return {Object} Filtered props applied to save element. 28597 */ 28598 function color_addSaveProps(props, blockNameOrType, attributes) { 28599 if (!hasColorSupport(blockNameOrType) || shouldSkipSerialization(blockNameOrType, COLOR_SUPPORT_KEY)) { 28600 return props; 28601 } 28602 const hasGradient = hasGradientSupport(blockNameOrType); 28603 28604 // I'd have preferred to avoid the "style" attribute usage here 28605 const { 28606 backgroundColor, 28607 textColor, 28608 gradient, 28609 style 28610 } = attributes; 28611 const shouldSerialize = feature => !shouldSkipSerialization(blockNameOrType, COLOR_SUPPORT_KEY, feature); 28612 28613 // Primary color classes must come before the `has-text-color`, 28614 // `has-background` and `has-link-color` classes to maintain backwards 28615 // compatibility and avoid block invalidations. 28616 const textClass = shouldSerialize('text') ? getColorClassName('color', textColor) : undefined; 28617 const gradientClass = shouldSerialize('gradients') ? __experimentalGetGradientClass(gradient) : undefined; 28618 const backgroundClass = shouldSerialize('background') ? getColorClassName('background-color', backgroundColor) : undefined; 28619 const serializeHasBackground = shouldSerialize('background') || shouldSerialize('gradients'); 28620 const hasBackground = backgroundColor || style?.color?.background || hasGradient && (gradient || style?.color?.gradient); 28621 const newClassName = dist_clsx(props.className, textClass, gradientClass, { 28622 // Don't apply the background class if there's a custom gradient. 28623 [backgroundClass]: (!hasGradient || !style?.color?.gradient) && !!backgroundClass, 28624 'has-text-color': shouldSerialize('text') && (textColor || style?.color?.text), 28625 'has-background': serializeHasBackground && hasBackground, 28626 'has-link-color': shouldSerialize('link') && style?.elements?.link?.color 28627 }); 28628 props.className = newClassName ? newClassName : undefined; 28629 return props; 28630 } 28631 function color_styleToAttributes(style) { 28632 const textColorValue = style?.color?.text; 28633 const textColorSlug = textColorValue?.startsWith('var:preset|color|') ? textColorValue.substring('var:preset|color|'.length) : undefined; 28634 const backgroundColorValue = style?.color?.background; 28635 const backgroundColorSlug = backgroundColorValue?.startsWith('var:preset|color|') ? backgroundColorValue.substring('var:preset|color|'.length) : undefined; 28636 const gradientValue = style?.color?.gradient; 28637 const gradientSlug = gradientValue?.startsWith('var:preset|gradient|') ? gradientValue.substring('var:preset|gradient|'.length) : undefined; 28638 const updatedStyle = { 28639 ...style 28640 }; 28641 updatedStyle.color = { 28642 ...updatedStyle.color, 28643 text: textColorSlug ? undefined : textColorValue, 28644 background: backgroundColorSlug ? undefined : backgroundColorValue, 28645 gradient: gradientSlug ? undefined : gradientValue 28646 }; 28647 return { 28648 style: utils_cleanEmptyObject(updatedStyle), 28649 textColor: textColorSlug, 28650 backgroundColor: backgroundColorSlug, 28651 gradient: gradientSlug 28652 }; 28653 } 28654 function color_attributesToStyle(attributes) { 28655 return { 28656 ...attributes.style, 28657 color: { 28658 ...attributes.style?.color, 28659 text: attributes.textColor ? 'var:preset|color|' + attributes.textColor : attributes.style?.color?.text, 28660 background: attributes.backgroundColor ? 'var:preset|color|' + attributes.backgroundColor : attributes.style?.color?.background, 28661 gradient: attributes.gradient ? 'var:preset|gradient|' + attributes.gradient : attributes.style?.color?.gradient 28662 } 28663 }; 28664 } 28665 function ColorInspectorControl({ 28666 children, 28667 resetAllFilter 28668 }) { 28669 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 28670 const existingStyle = color_attributesToStyle(attributes); 28671 const updatedStyle = resetAllFilter(existingStyle); 28672 return { 28673 ...attributes, 28674 ...color_styleToAttributes(updatedStyle) 28675 }; 28676 }, [resetAllFilter]); 28677 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 28678 group: "color", 28679 resetAllFilter: attributesResetAllFilter, 28680 children: children 28681 }); 28682 } 28683 function ColorEdit({ 28684 clientId, 28685 name, 28686 setAttributes, 28687 settings 28688 }) { 28689 const isEnabled = useHasColorPanel(settings); 28690 function selector(select) { 28691 const { 28692 style, 28693 textColor, 28694 backgroundColor, 28695 gradient 28696 } = select(store).getBlockAttributes(clientId) || {}; 28697 return { 28698 style, 28699 textColor, 28700 backgroundColor, 28701 gradient 28702 }; 28703 } 28704 const { 28705 style, 28706 textColor, 28707 backgroundColor, 28708 gradient 28709 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 28710 const value = (0,external_wp_element_namespaceObject.useMemo)(() => { 28711 return color_attributesToStyle({ 28712 style, 28713 textColor, 28714 backgroundColor, 28715 gradient 28716 }); 28717 }, [style, textColor, backgroundColor, gradient]); 28718 const onChange = newStyle => { 28719 setAttributes(color_styleToAttributes(newStyle)); 28720 }; 28721 if (!isEnabled) { 28722 return null; 28723 } 28724 const defaultControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [COLOR_SUPPORT_KEY, '__experimentalDefaultControls']); 28725 const enableContrastChecking = external_wp_element_namespaceObject.Platform.OS === 'web' && !value?.color?.gradient && (settings?.color?.text || settings?.color?.link) && 28726 // Contrast checking is enabled by default. 28727 // Deactivating it requires `enableContrastChecker` to have 28728 // an explicit value of `false`. 28729 false !== (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']); 28730 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorPanel, { 28731 as: ColorInspectorControl, 28732 panelId: clientId, 28733 settings: settings, 28734 value: value, 28735 onChange: onChange, 28736 defaultControls: defaultControls, 28737 enableContrastChecker: false !== (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']), 28738 children: enableContrastChecking && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockColorContrastChecker, { 28739 clientId: clientId 28740 }) 28741 }); 28742 } 28743 function color_useBlockProps({ 28744 name, 28745 backgroundColor, 28746 textColor, 28747 gradient, 28748 style 28749 }) { 28750 const [userPalette, themePalette, defaultPalette] = use_settings_useSettings('color.palette.custom', 'color.palette.theme', 'color.palette.default'); 28751 const colors = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); 28752 if (!hasColorSupport(name) || shouldSkipSerialization(name, COLOR_SUPPORT_KEY)) { 28753 return {}; 28754 } 28755 const extraStyles = {}; 28756 if (textColor && !shouldSkipSerialization(name, COLOR_SUPPORT_KEY, 'text')) { 28757 extraStyles.color = getColorObjectByAttributeValues(colors, textColor)?.color; 28758 } 28759 if (backgroundColor && !shouldSkipSerialization(name, COLOR_SUPPORT_KEY, 'background')) { 28760 extraStyles.backgroundColor = getColorObjectByAttributeValues(colors, backgroundColor)?.color; 28761 } 28762 const saveProps = color_addSaveProps({ 28763 style: extraStyles 28764 }, name, { 28765 textColor, 28766 backgroundColor, 28767 gradient, 28768 style 28769 }); 28770 const hasBackgroundValue = backgroundColor || style?.color?.background || gradient || style?.color?.gradient; 28771 return { 28772 ...saveProps, 28773 className: dist_clsx(saveProps.className, 28774 // Add background image classes in the editor, if not already handled by background color values. 28775 !hasBackgroundValue && getBackgroundImageClasses(style)) 28776 }; 28777 } 28778 /* harmony default export */ const color = ({ 28779 useBlockProps: color_useBlockProps, 28780 addSaveProps: color_addSaveProps, 28781 attributeKeys: ['backgroundColor', 'textColor', 'gradient', 'style'], 28782 hasSupport: hasColorSupport 28783 }); 28784 const MIGRATION_PATHS = { 28785 linkColor: [['style', 'elements', 'link', 'color', 'text']], 28786 textColor: [['textColor'], ['style', 'color', 'text']], 28787 backgroundColor: [['backgroundColor'], ['style', 'color', 'background']], 28788 gradient: [['gradient'], ['style', 'color', 'gradient']] 28789 }; 28790 function color_addTransforms(result, source, index, results) { 28791 const destinationBlockType = result.name; 28792 const activeSupports = { 28793 linkColor: hasLinkColorSupport(destinationBlockType), 28794 textColor: hasTextColorSupport(destinationBlockType), 28795 backgroundColor: hasBackgroundColorSupport(destinationBlockType), 28796 gradient: hasGradientSupport(destinationBlockType) 28797 }; 28798 return transformStyles(activeSupports, MIGRATION_PATHS, result, source, index, results); 28799 } 28800 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/color/addAttribute', color_addAttributes); 28801 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', color_addTransforms); 28802 28803 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-family/index.js 28804 /** 28805 * External dependencies 28806 */ 28807 28808 28809 /** 28810 * WordPress dependencies 28811 */ 28812 28813 28814 28815 28816 /** 28817 * Internal dependencies 28818 */ 28819 28820 28821 function FontFamilyControl({ 28822 /** Start opting into the larger default height that will become the default size in a future version. */ 28823 __next40pxDefaultSize = false, 28824 /** Start opting into the new margin-free styles that will become the default in a future version. */ 28825 __nextHasNoMarginBottom = false, 28826 value = '', 28827 onChange, 28828 fontFamilies, 28829 className, 28830 ...props 28831 }) { 28832 var _options$find; 28833 const [blockLevelFontFamilies] = use_settings_useSettings('typography.fontFamilies'); 28834 if (!fontFamilies) { 28835 fontFamilies = blockLevelFontFamilies; 28836 } 28837 if (!fontFamilies || fontFamilies.length === 0) { 28838 return null; 28839 } 28840 const options = [{ 28841 key: '', 28842 name: (0,external_wp_i18n_namespaceObject.__)('Default') 28843 }, ...fontFamilies.map(({ 28844 fontFamily, 28845 name 28846 }) => ({ 28847 key: fontFamily, 28848 name: name || fontFamily, 28849 style: { 28850 fontFamily 28851 } 28852 }))]; 28853 if (!__nextHasNoMarginBottom) { 28854 external_wp_deprecated_default()('Bottom margin styles for wp.blockEditor.FontFamilyControl', { 28855 since: '6.7', 28856 version: '7.0', 28857 hint: 'Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version' 28858 }); 28859 } 28860 if (!__next40pxDefaultSize && (props.size === undefined || props.size === 'default')) { 28861 external_wp_deprecated_default()(`36px default size for wp.blockEditor.__experimentalFontFamilyControl`, { 28862 since: '6.8', 28863 version: '7.1', 28864 hint: 'Set the `__next40pxDefaultSize` prop to true to start opting into the new default size, which will become the default in a future version.' 28865 }); 28866 } 28867 const selectedValue = (_options$find = options.find(option => option.key === value)) !== null && _options$find !== void 0 ? _options$find : ''; 28868 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CustomSelectControl, { 28869 __next40pxDefaultSize: __next40pxDefaultSize, 28870 __shouldNotWarnDeprecated36pxSize: true, 28871 label: (0,external_wp_i18n_namespaceObject.__)('Font'), 28872 value: selectedValue, 28873 onChange: ({ 28874 selectedItem 28875 }) => onChange(selectedItem.key), 28876 options: options, 28877 className: dist_clsx('block-editor-font-family-control', className, { 28878 'is-next-has-no-margin-bottom': __nextHasNoMarginBottom 28879 }), 28880 ...props 28881 }); 28882 } 28883 28884 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-appearance-control/index.js 28885 /** 28886 * WordPress dependencies 28887 */ 28888 28889 28890 28891 28892 28893 /** 28894 * Internal dependencies 28895 */ 28896 28897 28898 /** 28899 * Adjusts font appearance field label in case either font styles or weights 28900 * are disabled. 28901 * 28902 * @param {boolean} hasFontStyles Whether font styles are enabled and present. 28903 * @param {boolean} hasFontWeights Whether font weights are enabled and present. 28904 * @return {string} A label representing what font appearance is being edited. 28905 */ 28906 28907 const getFontAppearanceLabel = (hasFontStyles, hasFontWeights) => { 28908 if (!hasFontStyles) { 28909 return (0,external_wp_i18n_namespaceObject.__)('Font weight'); 28910 } 28911 if (!hasFontWeights) { 28912 return (0,external_wp_i18n_namespaceObject.__)('Font style'); 28913 } 28914 return (0,external_wp_i18n_namespaceObject.__)('Appearance'); 28915 }; 28916 28917 /** 28918 * Control to display font style and weight options of the active font. 28919 * 28920 * @param {Object} props Component props. 28921 * 28922 * @return {Element} Font appearance control. 28923 */ 28924 function FontAppearanceControl(props) { 28925 const { 28926 /** Start opting into the larger default height that will become the default size in a future version. */ 28927 __next40pxDefaultSize = false, 28928 onChange, 28929 hasFontStyles = true, 28930 hasFontWeights = true, 28931 fontFamilyFaces, 28932 value: { 28933 fontStyle, 28934 fontWeight 28935 }, 28936 ...otherProps 28937 } = props; 28938 const hasStylesOrWeights = hasFontStyles || hasFontWeights; 28939 const label = getFontAppearanceLabel(hasFontStyles, hasFontWeights); 28940 const defaultOption = { 28941 key: 'default', 28942 name: (0,external_wp_i18n_namespaceObject.__)('Default'), 28943 style: { 28944 fontStyle: undefined, 28945 fontWeight: undefined 28946 } 28947 }; 28948 const { 28949 fontStyles, 28950 fontWeights, 28951 combinedStyleAndWeightOptions 28952 } = getFontStylesAndWeights(fontFamilyFaces); 28953 28954 // Generates select options for combined font styles and weights. 28955 const combineOptions = () => { 28956 const combinedOptions = [defaultOption]; 28957 if (combinedStyleAndWeightOptions) { 28958 combinedOptions.push(...combinedStyleAndWeightOptions); 28959 } 28960 return combinedOptions; 28961 }; 28962 28963 // Generates select options for font styles only. 28964 const styleOptions = () => { 28965 const combinedOptions = [defaultOption]; 28966 fontStyles.forEach(({ 28967 name, 28968 value 28969 }) => { 28970 combinedOptions.push({ 28971 key: value, 28972 name, 28973 style: { 28974 fontStyle: value, 28975 fontWeight: undefined 28976 } 28977 }); 28978 }); 28979 return combinedOptions; 28980 }; 28981 28982 // Generates select options for font weights only. 28983 const weightOptions = () => { 28984 const combinedOptions = [defaultOption]; 28985 fontWeights.forEach(({ 28986 name, 28987 value 28988 }) => { 28989 combinedOptions.push({ 28990 key: value, 28991 name, 28992 style: { 28993 fontStyle: undefined, 28994 fontWeight: value 28995 } 28996 }); 28997 }); 28998 return combinedOptions; 28999 }; 29000 29001 // Map font styles and weights to select options. 29002 const selectOptions = (0,external_wp_element_namespaceObject.useMemo)(() => { 29003 // Display combined available font style and weight options. 29004 if (hasFontStyles && hasFontWeights) { 29005 return combineOptions(); 29006 } 29007 29008 // Display only font style options or font weight options. 29009 return hasFontStyles ? styleOptions() : weightOptions(); 29010 }, [props.options, fontStyles, fontWeights, combinedStyleAndWeightOptions]); 29011 29012 // Find current selection by comparing font style & weight against options, 29013 // and fall back to the Default option if there is no matching option. 29014 const currentSelection = selectOptions.find(option => option.style.fontStyle === fontStyle && option.style.fontWeight === fontWeight) || selectOptions[0]; 29015 29016 // Adjusts screen reader description based on styles or weights. 29017 const getDescribedBy = () => { 29018 if (!currentSelection) { 29019 return (0,external_wp_i18n_namespaceObject.__)('No selected font appearance'); 29020 } 29021 if (!hasFontStyles) { 29022 return (0,external_wp_i18n_namespaceObject.sprintf)( 29023 // translators: %s: Currently selected font weight. 29024 (0,external_wp_i18n_namespaceObject.__)('Currently selected font weight: %s'), currentSelection.name); 29025 } 29026 if (!hasFontWeights) { 29027 return (0,external_wp_i18n_namespaceObject.sprintf)( 29028 // translators: %s: Currently selected font style. 29029 (0,external_wp_i18n_namespaceObject.__)('Currently selected font style: %s'), currentSelection.name); 29030 } 29031 return (0,external_wp_i18n_namespaceObject.sprintf)( 29032 // translators: %s: Currently selected font appearance. 29033 (0,external_wp_i18n_namespaceObject.__)('Currently selected font appearance: %s'), currentSelection.name); 29034 }; 29035 if (!__next40pxDefaultSize && (otherProps.size === undefined || otherProps.size === 'default')) { 29036 external_wp_deprecated_default()(`36px default size for wp.blockEditor.__experimentalFontAppearanceControl`, { 29037 since: '6.8', 29038 version: '7.1', 29039 hint: 'Set the `__next40pxDefaultSize` prop to true to start opting into the new default size, which will become the default in a future version.' 29040 }); 29041 } 29042 return hasStylesOrWeights && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CustomSelectControl, { 29043 ...otherProps, 29044 className: "components-font-appearance-control", 29045 __next40pxDefaultSize: __next40pxDefaultSize, 29046 __shouldNotWarnDeprecated36pxSize: true, 29047 label: label, 29048 describedBy: getDescribedBy(), 29049 options: selectOptions, 29050 value: currentSelection, 29051 onChange: ({ 29052 selectedItem 29053 }) => onChange(selectedItem.style) 29054 }); 29055 } 29056 29057 ;// ./node_modules/@wordpress/block-editor/build-module/components/line-height-control/utils.js 29058 const BASE_DEFAULT_VALUE = 1.5; 29059 const STEP = 0.01; 29060 /** 29061 * A spin factor of 10 allows the spin controls to increment/decrement by 0.1. 29062 * e.g. A line-height value of 1.55 will increment to 1.65. 29063 */ 29064 const SPIN_FACTOR = 10; 29065 /** 29066 * There are varying value types within LineHeightControl: 29067 * 29068 * {undefined} Initial value. No changes from the user. 29069 * {string} Input value. Value consumed/outputted by the input. Empty would be ''. 29070 * {number} Block attribute type. Input value needs to be converted for attribute setting. 29071 * 29072 * Note: If the value is undefined, the input requires it to be an empty string ('') 29073 * in order to be considered "controlled" by props (rather than internal state). 29074 */ 29075 const RESET_VALUE = ''; 29076 29077 /** 29078 * Determines if the lineHeight attribute has been properly defined. 29079 * 29080 * @param {any} lineHeight The value to check. 29081 * 29082 * @return {boolean} Whether the lineHeight attribute is valid. 29083 */ 29084 function isLineHeightDefined(lineHeight) { 29085 return lineHeight !== undefined && lineHeight !== RESET_VALUE; 29086 } 29087 29088 ;// ./node_modules/@wordpress/block-editor/build-module/components/line-height-control/index.js 29089 /** 29090 * WordPress dependencies 29091 */ 29092 29093 29094 29095 29096 /** 29097 * Internal dependencies 29098 */ 29099 29100 29101 const line_height_control_LineHeightControl = ({ 29102 /** Start opting into the larger default height that will become the default size in a future version. */ 29103 __next40pxDefaultSize = false, 29104 value: lineHeight, 29105 onChange, 29106 __unstableInputWidth = '60px', 29107 ...otherProps 29108 }) => { 29109 const isDefined = isLineHeightDefined(lineHeight); 29110 const adjustNextValue = (nextValue, wasTypedOrPasted) => { 29111 // Set the next value without modification if lineHeight has been defined. 29112 if (isDefined) { 29113 return nextValue; 29114 } 29115 29116 /** 29117 * The following logic handles the initial spin up/down action 29118 * (from an undefined value state) so that the next values are better suited for 29119 * line-height rendering. For example, the first spin up should immediately 29120 * go to 1.6, rather than the normally expected 0.1. 29121 * 29122 * Spin up/down actions can be triggered by keydowns of the up/down arrow keys, 29123 * dragging the input or by clicking the spin buttons. 29124 */ 29125 const spin = STEP * SPIN_FACTOR; 29126 switch (`$nextValue}`) { 29127 case `$spin}`: 29128 // Increment by spin value. 29129 return BASE_DEFAULT_VALUE + spin; 29130 case '0': 29131 { 29132 // This means the user explicitly input '0', rather than using the 29133 // spin down action from an undefined value state. 29134 if (wasTypedOrPasted) { 29135 return nextValue; 29136 } 29137 // Decrement by spin value. 29138 return BASE_DEFAULT_VALUE - spin; 29139 } 29140 case '': 29141 return BASE_DEFAULT_VALUE; 29142 default: 29143 return nextValue; 29144 } 29145 }; 29146 const stateReducer = (state, action) => { 29147 // Be careful when changing this — cross-browser behavior of the 29148 // `inputType` field in `input` events are inconsistent. 29149 // For example, Firefox emits an input event with inputType="insertReplacementText" 29150 // on spin button clicks, while other browsers do not even emit an input event. 29151 const wasTypedOrPasted = ['insertText', 'insertFromPaste'].includes(action.payload.event.nativeEvent?.inputType); 29152 const value = adjustNextValue(state.value, wasTypedOrPasted); 29153 return { 29154 ...state, 29155 value 29156 }; 29157 }; 29158 const value = isDefined ? lineHeight : RESET_VALUE; 29159 const handleOnChange = (nextValue, { 29160 event 29161 }) => { 29162 if (nextValue === '') { 29163 onChange(); 29164 return; 29165 } 29166 if (event.type === 'click') { 29167 onChange(adjustNextValue(`$nextValue}`, false)); 29168 return; 29169 } 29170 onChange(`$nextValue}`); 29171 }; 29172 if (!__next40pxDefaultSize && (otherProps.size === undefined || otherProps.size === 'default')) { 29173 external_wp_deprecated_default()(`36px default size for wp.blockEditor.LineHeightControl`, { 29174 since: '6.8', 29175 version: '7.1', 29176 hint: 'Set the `__next40pxDefaultSize` prop to true to start opting into the new default size, which will become the default in a future version.' 29177 }); 29178 } 29179 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 29180 className: "block-editor-line-height-control", 29181 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, { 29182 ...otherProps, 29183 __shouldNotWarnDeprecated36pxSize: true, 29184 __next40pxDefaultSize: __next40pxDefaultSize, 29185 __unstableInputWidth: __unstableInputWidth, 29186 __unstableStateReducer: stateReducer, 29187 onChange: handleOnChange, 29188 label: (0,external_wp_i18n_namespaceObject.__)('Line height'), 29189 placeholder: BASE_DEFAULT_VALUE, 29190 step: STEP, 29191 spinFactor: SPIN_FACTOR, 29192 value: value, 29193 min: 0, 29194 spinControls: "custom" 29195 }) 29196 }); 29197 }; 29198 29199 /** 29200 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/line-height-control/README.md 29201 */ 29202 /* harmony default export */ const line_height_control = (line_height_control_LineHeightControl); 29203 29204 ;// ./node_modules/@wordpress/block-editor/build-module/components/letter-spacing-control/index.js 29205 /** 29206 * WordPress dependencies 29207 */ 29208 29209 29210 29211 29212 /** 29213 * Internal dependencies 29214 */ 29215 29216 29217 /** 29218 * Control for letter-spacing. 29219 * 29220 * @param {Object} props Component props. 29221 * @param {boolean} props.__next40pxDefaultSize Start opting into the larger default height that will become the default size in a future version. 29222 * @param {string} props.value Currently selected letter-spacing. 29223 * @param {Function} props.onChange Handles change in letter-spacing selection. 29224 * @param {string|number|undefined} props.__unstableInputWidth Input width to pass through to inner UnitControl. Should be a valid CSS value. 29225 * 29226 * @return {Element} Letter-spacing control. 29227 */ 29228 29229 function LetterSpacingControl({ 29230 __next40pxDefaultSize = false, 29231 value, 29232 onChange, 29233 __unstableInputWidth = '60px', 29234 ...otherProps 29235 }) { 29236 const [availableUnits] = use_settings_useSettings('spacing.units'); 29237 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 29238 availableUnits: availableUnits || ['px', 'em', 'rem'], 29239 defaultValues: { 29240 px: 2, 29241 em: 0.2, 29242 rem: 0.2 29243 } 29244 }); 29245 if (!__next40pxDefaultSize && (otherProps.size === undefined || otherProps.size === 'default')) { 29246 external_wp_deprecated_default()(`36px default size for wp.blockEditor.__experimentalLetterSpacingControl`, { 29247 since: '6.8', 29248 version: '7.1', 29249 hint: 'Set the `__next40pxDefaultSize` prop to true to start opting into the new default size, which will become the default in a future version.' 29250 }); 29251 } 29252 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 29253 __next40pxDefaultSize: __next40pxDefaultSize, 29254 __shouldNotWarnDeprecated36pxSize: true, 29255 ...otherProps, 29256 label: (0,external_wp_i18n_namespaceObject.__)('Letter spacing'), 29257 value: value, 29258 __unstableInputWidth: __unstableInputWidth, 29259 units: units, 29260 onChange: onChange 29261 }); 29262 } 29263 29264 ;// ./node_modules/@wordpress/icons/build-module/library/align-left.js 29265 /** 29266 * WordPress dependencies 29267 */ 29268 29269 29270 const alignLeft = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29271 xmlns: "http://www.w3.org/2000/svg", 29272 viewBox: "0 0 24 24", 29273 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29274 d: "M13 5.5H4V4h9v1.5Zm7 7H4V11h16v1.5Zm-7 7H4V18h9v1.5Z" 29275 }) 29276 }); 29277 /* harmony default export */ const align_left = (alignLeft); 29278 29279 ;// ./node_modules/@wordpress/icons/build-module/library/align-center.js 29280 /** 29281 * WordPress dependencies 29282 */ 29283 29284 29285 const alignCenter = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29286 xmlns: "http://www.w3.org/2000/svg", 29287 viewBox: "0 0 24 24", 29288 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29289 d: "M7.5 5.5h9V4h-9v1.5Zm-3.5 7h16V11H4v1.5Zm3.5 7h9V18h-9v1.5Z" 29290 }) 29291 }); 29292 /* harmony default export */ const align_center = (alignCenter); 29293 29294 ;// ./node_modules/@wordpress/icons/build-module/library/align-right.js 29295 /** 29296 * WordPress dependencies 29297 */ 29298 29299 29300 const alignRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29301 xmlns: "http://www.w3.org/2000/svg", 29302 viewBox: "0 0 24 24", 29303 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29304 d: "M11.111 5.5H20V4h-8.889v1.5ZM4 12.5h16V11H4v1.5Zm7.111 7H20V18h-8.889v1.5Z" 29305 }) 29306 }); 29307 /* harmony default export */ const align_right = (alignRight); 29308 29309 ;// ./node_modules/@wordpress/icons/build-module/library/align-justify.js 29310 /** 29311 * WordPress dependencies 29312 */ 29313 29314 29315 const alignJustify = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29316 xmlns: "http://www.w3.org/2000/svg", 29317 viewBox: "0 0 24 24", 29318 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29319 d: "M4 12.8h16v-1.5H4v1.5zm0 7h12.4v-1.5H4v1.5zM4 4.3v1.5h16V4.3H4z" 29320 }) 29321 }); 29322 /* harmony default export */ const align_justify = (alignJustify); 29323 29324 ;// ./node_modules/@wordpress/block-editor/build-module/components/text-alignment-control/index.js 29325 /** 29326 * External dependencies 29327 */ 29328 29329 29330 /** 29331 * WordPress dependencies 29332 */ 29333 29334 29335 29336 29337 29338 const TEXT_ALIGNMENT_OPTIONS = [{ 29339 label: (0,external_wp_i18n_namespaceObject.__)('Align text left'), 29340 value: 'left', 29341 icon: align_left 29342 }, { 29343 label: (0,external_wp_i18n_namespaceObject.__)('Align text center'), 29344 value: 'center', 29345 icon: align_center 29346 }, { 29347 label: (0,external_wp_i18n_namespaceObject.__)('Align text right'), 29348 value: 'right', 29349 icon: align_right 29350 }, { 29351 label: (0,external_wp_i18n_namespaceObject.__)('Justify text'), 29352 value: 'justify', 29353 icon: align_justify 29354 }]; 29355 const DEFAULT_OPTIONS = ['left', 'center', 'right']; 29356 29357 /** 29358 * Control to facilitate text alignment selections. 29359 * 29360 * @param {Object} props Component props. 29361 * @param {string} props.className Class name to add to the control. 29362 * @param {string} props.value Currently selected text alignment. 29363 * @param {Function} props.onChange Handles change in text alignment selection. 29364 * @param {string[]} props.options Array of text alignment options to display. 29365 * 29366 * @return {Element} Text alignment control. 29367 */ 29368 function TextAlignmentControl({ 29369 className, 29370 value, 29371 onChange, 29372 options = DEFAULT_OPTIONS 29373 }) { 29374 const validOptions = (0,external_wp_element_namespaceObject.useMemo)(() => TEXT_ALIGNMENT_OPTIONS.filter(option => options.includes(option.value)), [options]); 29375 if (!validOptions.length) { 29376 return null; 29377 } 29378 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 29379 isDeselectable: true, 29380 __nextHasNoMarginBottom: true, 29381 __next40pxDefaultSize: true, 29382 label: (0,external_wp_i18n_namespaceObject.__)('Text alignment'), 29383 className: dist_clsx('block-editor-text-alignment-control', className), 29384 value: value, 29385 onChange: newValue => { 29386 onChange(newValue === value ? undefined : newValue); 29387 }, 29388 children: validOptions.map(option => { 29389 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 29390 value: option.value, 29391 icon: option.icon, 29392 label: option.label 29393 }, option.value); 29394 }) 29395 }); 29396 } 29397 29398 ;// ./node_modules/@wordpress/icons/build-module/library/format-uppercase.js 29399 /** 29400 * WordPress dependencies 29401 */ 29402 29403 29404 const formatUppercase = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29405 xmlns: "http://www.w3.org/2000/svg", 29406 viewBox: "0 0 24 24", 29407 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29408 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" 29409 }) 29410 }); 29411 /* harmony default export */ const format_uppercase = (formatUppercase); 29412 29413 ;// ./node_modules/@wordpress/icons/build-module/library/format-lowercase.js 29414 /** 29415 * WordPress dependencies 29416 */ 29417 29418 29419 const formatLowercase = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29420 xmlns: "http://www.w3.org/2000/svg", 29421 viewBox: "0 0 24 24", 29422 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29423 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" 29424 }) 29425 }); 29426 /* harmony default export */ const format_lowercase = (formatLowercase); 29427 29428 ;// ./node_modules/@wordpress/icons/build-module/library/format-capitalize.js 29429 /** 29430 * WordPress dependencies 29431 */ 29432 29433 29434 const formatCapitalize = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29435 xmlns: "http://www.w3.org/2000/svg", 29436 viewBox: "0 0 24 24", 29437 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29438 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" 29439 }) 29440 }); 29441 /* harmony default export */ const format_capitalize = (formatCapitalize); 29442 29443 ;// ./node_modules/@wordpress/block-editor/build-module/components/text-transform-control/index.js 29444 /** 29445 * External dependencies 29446 */ 29447 29448 29449 /** 29450 * WordPress dependencies 29451 */ 29452 29453 29454 29455 29456 const TEXT_TRANSFORMS = [{ 29457 label: (0,external_wp_i18n_namespaceObject.__)('None'), 29458 value: 'none', 29459 icon: library_reset 29460 }, { 29461 label: (0,external_wp_i18n_namespaceObject.__)('Uppercase'), 29462 value: 'uppercase', 29463 icon: format_uppercase 29464 }, { 29465 label: (0,external_wp_i18n_namespaceObject.__)('Lowercase'), 29466 value: 'lowercase', 29467 icon: format_lowercase 29468 }, { 29469 label: (0,external_wp_i18n_namespaceObject.__)('Capitalize'), 29470 value: 'capitalize', 29471 icon: format_capitalize 29472 }]; 29473 29474 /** 29475 * Control to facilitate text transform selections. 29476 * 29477 * @param {Object} props Component props. 29478 * @param {string} props.className Class name to add to the control. 29479 * @param {string} props.value Currently selected text transform. 29480 * @param {Function} props.onChange Handles change in text transform selection. 29481 * 29482 * @return {Element} Text transform control. 29483 */ 29484 function TextTransformControl({ 29485 className, 29486 value, 29487 onChange 29488 }) { 29489 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 29490 isDeselectable: true, 29491 __nextHasNoMarginBottom: true, 29492 __next40pxDefaultSize: true, 29493 label: (0,external_wp_i18n_namespaceObject.__)('Letter case'), 29494 className: dist_clsx('block-editor-text-transform-control', className), 29495 value: value, 29496 onChange: newValue => { 29497 onChange(newValue === value ? undefined : newValue); 29498 }, 29499 children: TEXT_TRANSFORMS.map(option => { 29500 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 29501 value: option.value, 29502 icon: option.icon, 29503 label: option.label 29504 }, option.value); 29505 }) 29506 }); 29507 } 29508 29509 ;// ./node_modules/@wordpress/icons/build-module/library/format-underline.js 29510 /** 29511 * WordPress dependencies 29512 */ 29513 29514 29515 const formatUnderline = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29516 xmlns: "http://www.w3.org/2000/svg", 29517 viewBox: "0 0 24 24", 29518 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29519 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" 29520 }) 29521 }); 29522 /* harmony default export */ const format_underline = (formatUnderline); 29523 29524 ;// ./node_modules/@wordpress/icons/build-module/library/format-strikethrough.js 29525 /** 29526 * WordPress dependencies 29527 */ 29528 29529 29530 const formatStrikethrough = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29531 xmlns: "http://www.w3.org/2000/svg", 29532 viewBox: "0 0 24 24", 29533 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29534 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" 29535 }) 29536 }); 29537 /* harmony default export */ const format_strikethrough = (formatStrikethrough); 29538 29539 ;// ./node_modules/@wordpress/block-editor/build-module/components/text-decoration-control/index.js 29540 /** 29541 * External dependencies 29542 */ 29543 29544 29545 /** 29546 * WordPress dependencies 29547 */ 29548 29549 29550 29551 29552 const TEXT_DECORATIONS = [{ 29553 label: (0,external_wp_i18n_namespaceObject.__)('None'), 29554 value: 'none', 29555 icon: library_reset 29556 }, { 29557 label: (0,external_wp_i18n_namespaceObject.__)('Underline'), 29558 value: 'underline', 29559 icon: format_underline 29560 }, { 29561 label: (0,external_wp_i18n_namespaceObject.__)('Strikethrough'), 29562 value: 'line-through', 29563 icon: format_strikethrough 29564 }]; 29565 29566 /** 29567 * Control to facilitate text decoration selections. 29568 * 29569 * @param {Object} props Component props. 29570 * @param {string} props.value Currently selected text decoration. 29571 * @param {Function} props.onChange Handles change in text decoration selection. 29572 * @param {string} props.className Additional class name to apply. 29573 * 29574 * @return {Element} Text decoration control. 29575 */ 29576 function TextDecorationControl({ 29577 value, 29578 onChange, 29579 className 29580 }) { 29581 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 29582 isDeselectable: true, 29583 __nextHasNoMarginBottom: true, 29584 __next40pxDefaultSize: true, 29585 label: (0,external_wp_i18n_namespaceObject.__)('Decoration'), 29586 className: dist_clsx('block-editor-text-decoration-control', className), 29587 value: value, 29588 onChange: newValue => { 29589 onChange(newValue === value ? undefined : newValue); 29590 }, 29591 children: TEXT_DECORATIONS.map(option => { 29592 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 29593 value: option.value, 29594 icon: option.icon, 29595 label: option.label 29596 }, option.value); 29597 }) 29598 }); 29599 } 29600 29601 ;// ./node_modules/@wordpress/icons/build-module/library/text-horizontal.js 29602 /** 29603 * WordPress dependencies 29604 */ 29605 29606 29607 const textHorizontal = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29608 xmlns: "http://www.w3.org/2000/svg", 29609 viewBox: "0 0 24 24", 29610 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29611 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" 29612 }) 29613 }); 29614 /* harmony default export */ const text_horizontal = (textHorizontal); 29615 29616 ;// ./node_modules/@wordpress/icons/build-module/library/text-vertical.js 29617 /** 29618 * WordPress dependencies 29619 */ 29620 29621 29622 const textVertical = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 29623 xmlns: "http://www.w3.org/2000/svg", 29624 viewBox: "0 0 24 24", 29625 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 29626 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" 29627 }) 29628 }); 29629 /* harmony default export */ const text_vertical = (textVertical); 29630 29631 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-mode-control/index.js 29632 /** 29633 * External dependencies 29634 */ 29635 29636 29637 /** 29638 * WordPress dependencies 29639 */ 29640 29641 29642 29643 29644 const WRITING_MODES = [{ 29645 label: (0,external_wp_i18n_namespaceObject.__)('Horizontal'), 29646 value: 'horizontal-tb', 29647 icon: text_horizontal 29648 }, { 29649 label: (0,external_wp_i18n_namespaceObject.__)('Vertical'), 29650 value: (0,external_wp_i18n_namespaceObject.isRTL)() ? 'vertical-lr' : 'vertical-rl', 29651 icon: text_vertical 29652 }]; 29653 29654 /** 29655 * Control to facilitate writing mode selections. 29656 * 29657 * @param {Object} props Component props. 29658 * @param {string} props.className Class name to add to the control. 29659 * @param {string} props.value Currently selected writing mode. 29660 * @param {Function} props.onChange Handles change in the writing mode selection. 29661 * 29662 * @return {Element} Writing Mode control. 29663 */ 29664 function WritingModeControl({ 29665 className, 29666 value, 29667 onChange 29668 }) { 29669 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 29670 isDeselectable: true, 29671 __nextHasNoMarginBottom: true, 29672 __next40pxDefaultSize: true, 29673 label: (0,external_wp_i18n_namespaceObject.__)('Orientation'), 29674 className: dist_clsx('block-editor-writing-mode-control', className), 29675 value: value, 29676 onChange: newValue => { 29677 onChange(newValue === value ? undefined : newValue); 29678 }, 29679 children: WRITING_MODES.map(option => { 29680 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 29681 value: option.value, 29682 icon: option.icon, 29683 label: option.label 29684 }, option.value); 29685 }) 29686 }); 29687 } 29688 29689 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/typography-panel.js 29690 /** 29691 * WordPress dependencies 29692 */ 29693 29694 29695 29696 29697 /** 29698 * Internal dependencies 29699 */ 29700 29701 29702 29703 29704 29705 29706 29707 29708 29709 29710 29711 29712 const MIN_TEXT_COLUMNS = 1; 29713 const MAX_TEXT_COLUMNS = 6; 29714 function useHasTypographyPanel(settings) { 29715 const hasFontFamily = useHasFontFamilyControl(settings); 29716 const hasLineHeight = useHasLineHeightControl(settings); 29717 const hasFontAppearance = useHasAppearanceControl(settings); 29718 const hasLetterSpacing = useHasLetterSpacingControl(settings); 29719 const hasTextAlign = useHasTextAlignmentControl(settings); 29720 const hasTextTransform = useHasTextTransformControl(settings); 29721 const hasTextDecoration = useHasTextDecorationControl(settings); 29722 const hasWritingMode = useHasWritingModeControl(settings); 29723 const hasTextColumns = useHasTextColumnsControl(settings); 29724 const hasFontSize = useHasFontSizeControl(settings); 29725 return hasFontFamily || hasLineHeight || hasFontAppearance || hasLetterSpacing || hasTextAlign || hasTextTransform || hasFontSize || hasTextDecoration || hasWritingMode || hasTextColumns; 29726 } 29727 function useHasFontSizeControl(settings) { 29728 return settings?.typography?.defaultFontSizes !== false && settings?.typography?.fontSizes?.default?.length || settings?.typography?.fontSizes?.theme?.length || settings?.typography?.fontSizes?.custom?.length || settings?.typography?.customFontSize; 29729 } 29730 function useHasFontFamilyControl(settings) { 29731 return ['default', 'theme', 'custom'].some(key => settings?.typography?.fontFamilies?.[key]?.length); 29732 } 29733 function useHasLineHeightControl(settings) { 29734 return settings?.typography?.lineHeight; 29735 } 29736 function useHasAppearanceControl(settings) { 29737 return settings?.typography?.fontStyle || settings?.typography?.fontWeight; 29738 } 29739 function useAppearanceControlLabel(settings) { 29740 if (!settings?.typography?.fontStyle) { 29741 return (0,external_wp_i18n_namespaceObject.__)('Font weight'); 29742 } 29743 if (!settings?.typography?.fontWeight) { 29744 return (0,external_wp_i18n_namespaceObject.__)('Font style'); 29745 } 29746 return (0,external_wp_i18n_namespaceObject.__)('Appearance'); 29747 } 29748 function useHasLetterSpacingControl(settings) { 29749 return settings?.typography?.letterSpacing; 29750 } 29751 function useHasTextTransformControl(settings) { 29752 return settings?.typography?.textTransform; 29753 } 29754 function useHasTextAlignmentControl(settings) { 29755 return settings?.typography?.textAlign; 29756 } 29757 function useHasTextDecorationControl(settings) { 29758 return settings?.typography?.textDecoration; 29759 } 29760 function useHasWritingModeControl(settings) { 29761 return settings?.typography?.writingMode; 29762 } 29763 function useHasTextColumnsControl(settings) { 29764 return settings?.typography?.textColumns; 29765 } 29766 29767 /** 29768 * Concatenate all the font sizes into a single list for the font size picker. 29769 * 29770 * @param {Object} settings The global styles settings. 29771 * 29772 * @return {Array} The merged font sizes. 29773 */ 29774 function getMergedFontSizes(settings) { 29775 var _fontSizes$custom, _fontSizes$theme, _fontSizes$default; 29776 const fontSizes = settings?.typography?.fontSizes; 29777 const defaultFontSizesEnabled = !!settings?.typography?.defaultFontSizes; 29778 return [...((_fontSizes$custom = fontSizes?.custom) !== null && _fontSizes$custom !== void 0 ? _fontSizes$custom : []), ...((_fontSizes$theme = fontSizes?.theme) !== null && _fontSizes$theme !== void 0 ? _fontSizes$theme : []), ...(defaultFontSizesEnabled ? (_fontSizes$default = fontSizes?.default) !== null && _fontSizes$default !== void 0 ? _fontSizes$default : [] : [])]; 29779 } 29780 function TypographyToolsPanel({ 29781 resetAllFilter, 29782 onChange, 29783 value, 29784 panelId, 29785 children 29786 }) { 29787 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 29788 const resetAll = () => { 29789 const updatedValue = resetAllFilter(value); 29790 onChange(updatedValue); 29791 }; 29792 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 29793 label: (0,external_wp_i18n_namespaceObject.__)('Typography'), 29794 resetAll: resetAll, 29795 panelId: panelId, 29796 dropdownMenuProps: dropdownMenuProps, 29797 children: children 29798 }); 29799 } 29800 const typography_panel_DEFAULT_CONTROLS = { 29801 fontFamily: true, 29802 fontSize: true, 29803 fontAppearance: true, 29804 lineHeight: true, 29805 letterSpacing: true, 29806 textAlign: true, 29807 textTransform: true, 29808 textDecoration: true, 29809 writingMode: true, 29810 textColumns: true 29811 }; 29812 function TypographyPanel({ 29813 as: Wrapper = TypographyToolsPanel, 29814 value, 29815 onChange, 29816 inheritedValue = value, 29817 settings, 29818 panelId, 29819 defaultControls = typography_panel_DEFAULT_CONTROLS 29820 }) { 29821 const decodeValue = rawValue => getValueFromVariable({ 29822 settings 29823 }, '', rawValue); 29824 29825 // Font Family 29826 const hasFontFamilyEnabled = useHasFontFamilyControl(settings); 29827 const fontFamily = decodeValue(inheritedValue?.typography?.fontFamily); 29828 const { 29829 fontFamilies, 29830 fontFamilyFaces 29831 } = (0,external_wp_element_namespaceObject.useMemo)(() => { 29832 return getMergedFontFamiliesAndFontFamilyFaces(settings, fontFamily); 29833 }, [settings, fontFamily]); 29834 const setFontFamily = newValue => { 29835 const slug = fontFamilies?.find(({ 29836 fontFamily: f 29837 }) => f === newValue)?.slug; 29838 onChange(setImmutably(value, ['typography', 'fontFamily'], slug ? `var:preset|font-family|$slug}` : newValue || undefined)); 29839 }; 29840 const hasFontFamily = () => !!value?.typography?.fontFamily; 29841 const resetFontFamily = () => setFontFamily(undefined); 29842 29843 // Font Size 29844 const hasFontSizeEnabled = useHasFontSizeControl(settings); 29845 const disableCustomFontSizes = !settings?.typography?.customFontSize; 29846 const mergedFontSizes = getMergedFontSizes(settings); 29847 const fontSize = decodeValue(inheritedValue?.typography?.fontSize); 29848 const setFontSize = (newValue, metadata) => { 29849 const actualValue = !!metadata?.slug ? `var:preset|font-size|$metadata?.slug}` : newValue; 29850 onChange(setImmutably(value, ['typography', 'fontSize'], actualValue || undefined)); 29851 }; 29852 const hasFontSize = () => !!value?.typography?.fontSize; 29853 const resetFontSize = () => setFontSize(undefined); 29854 29855 // Appearance 29856 const hasAppearanceControl = useHasAppearanceControl(settings); 29857 const appearanceControlLabel = useAppearanceControlLabel(settings); 29858 const hasFontStyles = settings?.typography?.fontStyle; 29859 const hasFontWeights = settings?.typography?.fontWeight; 29860 const fontStyle = decodeValue(inheritedValue?.typography?.fontStyle); 29861 const fontWeight = decodeValue(inheritedValue?.typography?.fontWeight); 29862 const { 29863 nearestFontStyle, 29864 nearestFontWeight 29865 } = findNearestStyleAndWeight(fontFamilyFaces, fontStyle, fontWeight); 29866 const setFontAppearance = (0,external_wp_element_namespaceObject.useCallback)(({ 29867 fontStyle: newFontStyle, 29868 fontWeight: newFontWeight 29869 }) => { 29870 // Only update the font style and weight if they have changed. 29871 if (newFontStyle !== fontStyle || newFontWeight !== fontWeight) { 29872 onChange({ 29873 ...value, 29874 typography: { 29875 ...value?.typography, 29876 fontStyle: newFontStyle || undefined, 29877 fontWeight: newFontWeight || undefined 29878 } 29879 }); 29880 } 29881 }, [fontStyle, fontWeight, onChange, value]); 29882 const hasFontAppearance = () => !!value?.typography?.fontStyle || !!value?.typography?.fontWeight; 29883 const resetFontAppearance = (0,external_wp_element_namespaceObject.useCallback)(() => { 29884 setFontAppearance({}); 29885 }, [setFontAppearance]); 29886 29887 // Check if previous font style and weight values are available in the new font family. 29888 (0,external_wp_element_namespaceObject.useEffect)(() => { 29889 if (nearestFontStyle && nearestFontWeight) { 29890 setFontAppearance({ 29891 fontStyle: nearestFontStyle, 29892 fontWeight: nearestFontWeight 29893 }); 29894 } else { 29895 // Reset font appearance if there are no available styles or weights. 29896 resetFontAppearance(); 29897 } 29898 }, [nearestFontStyle, nearestFontWeight, resetFontAppearance, setFontAppearance]); 29899 29900 // Line Height 29901 const hasLineHeightEnabled = useHasLineHeightControl(settings); 29902 const lineHeight = decodeValue(inheritedValue?.typography?.lineHeight); 29903 const setLineHeight = newValue => { 29904 onChange(setImmutably(value, ['typography', 'lineHeight'], newValue || undefined)); 29905 }; 29906 const hasLineHeight = () => value?.typography?.lineHeight !== undefined; 29907 const resetLineHeight = () => setLineHeight(undefined); 29908 29909 // Letter Spacing 29910 const hasLetterSpacingControl = useHasLetterSpacingControl(settings); 29911 const letterSpacing = decodeValue(inheritedValue?.typography?.letterSpacing); 29912 const setLetterSpacing = newValue => { 29913 onChange(setImmutably(value, ['typography', 'letterSpacing'], newValue || undefined)); 29914 }; 29915 const hasLetterSpacing = () => !!value?.typography?.letterSpacing; 29916 const resetLetterSpacing = () => setLetterSpacing(undefined); 29917 29918 // Text Columns 29919 const hasTextColumnsControl = useHasTextColumnsControl(settings); 29920 const textColumns = decodeValue(inheritedValue?.typography?.textColumns); 29921 const setTextColumns = newValue => { 29922 onChange(setImmutably(value, ['typography', 'textColumns'], newValue || undefined)); 29923 }; 29924 const hasTextColumns = () => !!value?.typography?.textColumns; 29925 const resetTextColumns = () => setTextColumns(undefined); 29926 29927 // Text Transform 29928 const hasTextTransformControl = useHasTextTransformControl(settings); 29929 const textTransform = decodeValue(inheritedValue?.typography?.textTransform); 29930 const setTextTransform = newValue => { 29931 onChange(setImmutably(value, ['typography', 'textTransform'], newValue || undefined)); 29932 }; 29933 const hasTextTransform = () => !!value?.typography?.textTransform; 29934 const resetTextTransform = () => setTextTransform(undefined); 29935 29936 // Text Decoration 29937 const hasTextDecorationControl = useHasTextDecorationControl(settings); 29938 const textDecoration = decodeValue(inheritedValue?.typography?.textDecoration); 29939 const setTextDecoration = newValue => { 29940 onChange(setImmutably(value, ['typography', 'textDecoration'], newValue || undefined)); 29941 }; 29942 const hasTextDecoration = () => !!value?.typography?.textDecoration; 29943 const resetTextDecoration = () => setTextDecoration(undefined); 29944 29945 // Text Orientation 29946 const hasWritingModeControl = useHasWritingModeControl(settings); 29947 const writingMode = decodeValue(inheritedValue?.typography?.writingMode); 29948 const setWritingMode = newValue => { 29949 onChange(setImmutably(value, ['typography', 'writingMode'], newValue || undefined)); 29950 }; 29951 const hasWritingMode = () => !!value?.typography?.writingMode; 29952 const resetWritingMode = () => setWritingMode(undefined); 29953 29954 // Text Alignment 29955 const hasTextAlignmentControl = useHasTextAlignmentControl(settings); 29956 const textAlign = decodeValue(inheritedValue?.typography?.textAlign); 29957 const setTextAlign = newValue => { 29958 onChange(setImmutably(value, ['typography', 'textAlign'], newValue || undefined)); 29959 }; 29960 const hasTextAlign = () => !!value?.typography?.textAlign; 29961 const resetTextAlign = () => setTextAlign(undefined); 29962 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 29963 return { 29964 ...previousValue, 29965 typography: {} 29966 }; 29967 }, []); 29968 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Wrapper, { 29969 resetAllFilter: resetAllFilter, 29970 value: value, 29971 onChange: onChange, 29972 panelId: panelId, 29973 children: [hasFontFamilyEnabled && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 29974 label: (0,external_wp_i18n_namespaceObject.__)('Font'), 29975 hasValue: hasFontFamily, 29976 onDeselect: resetFontFamily, 29977 isShownByDefault: defaultControls.fontFamily, 29978 panelId: panelId, 29979 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FontFamilyControl, { 29980 fontFamilies: fontFamilies, 29981 value: fontFamily, 29982 onChange: setFontFamily, 29983 size: "__unstable-large", 29984 __nextHasNoMarginBottom: true 29985 }) 29986 }), hasFontSizeEnabled && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 29987 label: (0,external_wp_i18n_namespaceObject.__)('Size'), 29988 hasValue: hasFontSize, 29989 onDeselect: resetFontSize, 29990 isShownByDefault: defaultControls.fontSize, 29991 panelId: panelId, 29992 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FontSizePicker, { 29993 value: fontSize, 29994 onChange: setFontSize, 29995 fontSizes: mergedFontSizes, 29996 disableCustomFontSizes: disableCustomFontSizes, 29997 withReset: false, 29998 withSlider: true, 29999 size: "__unstable-large" 30000 }) 30001 }), hasAppearanceControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30002 className: "single-column", 30003 label: appearanceControlLabel, 30004 hasValue: hasFontAppearance, 30005 onDeselect: resetFontAppearance, 30006 isShownByDefault: defaultControls.fontAppearance, 30007 panelId: panelId, 30008 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FontAppearanceControl, { 30009 value: { 30010 fontStyle, 30011 fontWeight 30012 }, 30013 onChange: setFontAppearance, 30014 hasFontStyles: hasFontStyles, 30015 hasFontWeights: hasFontWeights, 30016 fontFamilyFaces: fontFamilyFaces, 30017 size: "__unstable-large" 30018 }) 30019 }), hasLineHeightEnabled && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30020 className: "single-column", 30021 label: (0,external_wp_i18n_namespaceObject.__)('Line height'), 30022 hasValue: hasLineHeight, 30023 onDeselect: resetLineHeight, 30024 isShownByDefault: defaultControls.lineHeight, 30025 panelId: panelId, 30026 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(line_height_control, { 30027 __unstableInputWidth: "auto", 30028 value: lineHeight, 30029 onChange: setLineHeight, 30030 size: "__unstable-large" 30031 }) 30032 }), hasLetterSpacingControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30033 className: "single-column", 30034 label: (0,external_wp_i18n_namespaceObject.__)('Letter spacing'), 30035 hasValue: hasLetterSpacing, 30036 onDeselect: resetLetterSpacing, 30037 isShownByDefault: defaultControls.letterSpacing, 30038 panelId: panelId, 30039 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LetterSpacingControl, { 30040 value: letterSpacing, 30041 onChange: setLetterSpacing, 30042 size: "__unstable-large", 30043 __unstableInputWidth: "auto" 30044 }) 30045 }), hasTextColumnsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30046 className: "single-column", 30047 label: (0,external_wp_i18n_namespaceObject.__)('Columns'), 30048 hasValue: hasTextColumns, 30049 onDeselect: resetTextColumns, 30050 isShownByDefault: defaultControls.textColumns, 30051 panelId: panelId, 30052 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, { 30053 label: (0,external_wp_i18n_namespaceObject.__)('Columns'), 30054 max: MAX_TEXT_COLUMNS, 30055 min: MIN_TEXT_COLUMNS, 30056 onChange: setTextColumns, 30057 size: "__unstable-large", 30058 spinControls: "custom", 30059 value: textColumns, 30060 initialPosition: 1 30061 }) 30062 }), hasTextDecorationControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30063 className: "single-column", 30064 label: (0,external_wp_i18n_namespaceObject.__)('Decoration'), 30065 hasValue: hasTextDecoration, 30066 onDeselect: resetTextDecoration, 30067 isShownByDefault: defaultControls.textDecoration, 30068 panelId: panelId, 30069 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TextDecorationControl, { 30070 value: textDecoration, 30071 onChange: setTextDecoration, 30072 size: "__unstable-large", 30073 __unstableInputWidth: "auto" 30074 }) 30075 }), hasWritingModeControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30076 className: "single-column", 30077 label: (0,external_wp_i18n_namespaceObject.__)('Orientation'), 30078 hasValue: hasWritingMode, 30079 onDeselect: resetWritingMode, 30080 isShownByDefault: defaultControls.writingMode, 30081 panelId: panelId, 30082 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WritingModeControl, { 30083 value: writingMode, 30084 onChange: setWritingMode, 30085 size: "__unstable-large", 30086 __nextHasNoMarginBottom: true 30087 }) 30088 }), hasTextTransformControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30089 label: (0,external_wp_i18n_namespaceObject.__)('Letter case'), 30090 hasValue: hasTextTransform, 30091 onDeselect: resetTextTransform, 30092 isShownByDefault: defaultControls.textTransform, 30093 panelId: panelId, 30094 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TextTransformControl, { 30095 value: textTransform, 30096 onChange: setTextTransform, 30097 showNone: true, 30098 isBlock: true, 30099 size: "__unstable-large", 30100 __nextHasNoMarginBottom: true 30101 }) 30102 }), hasTextAlignmentControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 30103 label: (0,external_wp_i18n_namespaceObject.__)('Text alignment'), 30104 hasValue: hasTextAlign, 30105 onDeselect: resetTextAlign, 30106 isShownByDefault: defaultControls.textAlign, 30107 panelId: panelId, 30108 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TextAlignmentControl, { 30109 value: textAlign, 30110 onChange: setTextAlign, 30111 size: "__unstable-large", 30112 __nextHasNoMarginBottom: true 30113 }) 30114 })] 30115 }); 30116 } 30117 30118 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/line-height.js 30119 /** 30120 * WordPress dependencies 30121 */ 30122 30123 30124 /** 30125 * Internal dependencies 30126 */ 30127 30128 30129 30130 30131 const LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; 30132 30133 /** 30134 * Inspector control panel containing the line height related configuration 30135 * 30136 * @param {Object} props 30137 * 30138 * @return {Element} Line height edit element. 30139 */ 30140 function LineHeightEdit(props) { 30141 const { 30142 attributes: { 30143 style 30144 }, 30145 setAttributes 30146 } = props; 30147 const onChange = newLineHeightValue => { 30148 const newStyle = { 30149 ...style, 30150 typography: { 30151 ...style?.typography, 30152 lineHeight: newLineHeightValue 30153 } 30154 }; 30155 setAttributes({ 30156 style: cleanEmptyObject(newStyle) 30157 }); 30158 }; 30159 return /*#__PURE__*/_jsx(LineHeightControl, { 30160 __unstableInputWidth: "100%", 30161 value: style?.typography?.lineHeight, 30162 onChange: onChange, 30163 size: "__unstable-large" 30164 }); 30165 } 30166 30167 /** 30168 * Custom hook that checks if line-height settings have been disabled. 30169 * 30170 * @param {string} name The name of the block. 30171 * @return {boolean} Whether setting is disabled. 30172 */ 30173 function useIsLineHeightDisabled({ 30174 name: blockName 30175 } = {}) { 30176 const [isEnabled] = useSettings('typography.lineHeight'); 30177 return !isEnabled || !hasBlockSupport(blockName, LINE_HEIGHT_SUPPORT_KEY); 30178 } 30179 30180 ;// external ["wp","tokenList"] 30181 const external_wp_tokenList_namespaceObject = window["wp"]["tokenList"]; 30182 var external_wp_tokenList_default = /*#__PURE__*/__webpack_require__.n(external_wp_tokenList_namespaceObject); 30183 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/font-family.js 30184 /** 30185 * WordPress dependencies 30186 */ 30187 30188 30189 30190 30191 30192 /** 30193 * Internal dependencies 30194 */ 30195 30196 30197 30198 const FONT_FAMILY_SUPPORT_KEY = 'typography.__experimentalFontFamily'; 30199 const { 30200 kebabCase: font_family_kebabCase 30201 } = unlock(external_wp_components_namespaceObject.privateApis); 30202 30203 /** 30204 * Filters registered block settings, extending attributes to include 30205 * the `fontFamily` attribute. 30206 * 30207 * @param {Object} settings Original block settings 30208 * @return {Object} Filtered block settings 30209 */ 30210 function font_family_addAttributes(settings) { 30211 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, FONT_FAMILY_SUPPORT_KEY)) { 30212 return settings; 30213 } 30214 30215 // Allow blocks to specify a default value if needed. 30216 if (!settings.attributes.fontFamily) { 30217 Object.assign(settings.attributes, { 30218 fontFamily: { 30219 type: 'string' 30220 } 30221 }); 30222 } 30223 return settings; 30224 } 30225 30226 /** 30227 * Override props assigned to save component to inject font family. 30228 * 30229 * @param {Object} props Additional props applied to save element 30230 * @param {Object} blockType Block type 30231 * @param {Object} attributes Block attributes 30232 * @return {Object} Filtered props applied to save element 30233 */ 30234 function font_family_addSaveProps(props, blockType, attributes) { 30235 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, FONT_FAMILY_SUPPORT_KEY)) { 30236 return props; 30237 } 30238 if (shouldSkipSerialization(blockType, TYPOGRAPHY_SUPPORT_KEY, 'fontFamily')) { 30239 return props; 30240 } 30241 if (!attributes?.fontFamily) { 30242 return props; 30243 } 30244 30245 // Use TokenList to dedupe classes. 30246 const classes = new (external_wp_tokenList_default())(props.className); 30247 classes.add(`has-$font_family_kebabCase(attributes?.fontFamily)}-font-family`); 30248 const newClassName = classes.value; 30249 props.className = newClassName ? newClassName : undefined; 30250 return props; 30251 } 30252 function font_family_useBlockProps({ 30253 name, 30254 fontFamily 30255 }) { 30256 return font_family_addSaveProps({}, name, { 30257 fontFamily 30258 }); 30259 } 30260 /* harmony default export */ const font_family = ({ 30261 useBlockProps: font_family_useBlockProps, 30262 addSaveProps: font_family_addSaveProps, 30263 attributeKeys: ['fontFamily'], 30264 hasSupport(name) { 30265 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, FONT_FAMILY_SUPPORT_KEY); 30266 } 30267 }); 30268 30269 /** 30270 * Resets the font family block support attribute. This can be used when 30271 * disabling the font family support controls for a block via a progressive 30272 * discovery panel. 30273 * 30274 * @param {Object} props Block props. 30275 * @param {Object} props.setAttributes Function to set block's attributes. 30276 */ 30277 function resetFontFamily({ 30278 setAttributes 30279 }) { 30280 setAttributes({ 30281 fontFamily: undefined 30282 }); 30283 } 30284 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/fontFamily/addAttribute', font_family_addAttributes); 30285 30286 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/utils.js 30287 /** 30288 * WordPress dependencies 30289 */ 30290 30291 30292 /** 30293 * Internal dependencies 30294 */ 30295 30296 const { 30297 kebabCase: utils_kebabCase 30298 } = unlock(external_wp_components_namespaceObject.privateApis); 30299 30300 /** 30301 * Returns the font size object based on an array of named font sizes and the namedFontSize and customFontSize values. 30302 * If namedFontSize is undefined or not found in fontSizes an object with just the size value based on customFontSize is returned. 30303 * 30304 * @param {Array} fontSizes Array of font size objects containing at least the "name" and "size" values as properties. 30305 * @param {?string} fontSizeAttribute Content of the font size attribute (slug). 30306 * @param {?number} customFontSizeAttribute Contents of the custom font size attribute (value). 30307 * 30308 * @return {?Object} If fontSizeAttribute is set and an equal slug is found in fontSizes it returns the font size object for that slug. 30309 * Otherwise, an object with just the size value based on customFontSize is returned. 30310 */ 30311 const utils_getFontSize = (fontSizes, fontSizeAttribute, customFontSizeAttribute) => { 30312 if (fontSizeAttribute) { 30313 const fontSizeObject = fontSizes?.find(({ 30314 slug 30315 }) => slug === fontSizeAttribute); 30316 if (fontSizeObject) { 30317 return fontSizeObject; 30318 } 30319 } 30320 return { 30321 size: customFontSizeAttribute 30322 }; 30323 }; 30324 30325 /** 30326 * Returns the corresponding font size object for a given value. 30327 * 30328 * @param {Array} fontSizes Array of font size objects. 30329 * @param {number} value Font size value. 30330 * 30331 * @return {Object} Font size object. 30332 */ 30333 function utils_getFontSizeObjectByValue(fontSizes, value) { 30334 const fontSizeObject = fontSizes?.find(({ 30335 size 30336 }) => size === value); 30337 if (fontSizeObject) { 30338 return fontSizeObject; 30339 } 30340 return { 30341 size: value 30342 }; 30343 } 30344 30345 /** 30346 * Returns a class based on fontSizeName. 30347 * 30348 * @param {string} fontSizeSlug Slug of the fontSize. 30349 * 30350 * @return {string | undefined} String with the class corresponding to the fontSize passed. 30351 * The class is generated by appending 'has-' followed by fontSizeSlug in kebabCase and ending with '-font-size'. 30352 */ 30353 function getFontSizeClass(fontSizeSlug) { 30354 if (!fontSizeSlug) { 30355 return; 30356 } 30357 return `has-$utils_kebabCase(fontSizeSlug)}-font-size`; 30358 } 30359 30360 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/font-size.js 30361 /** 30362 * WordPress dependencies 30363 */ 30364 30365 30366 30367 30368 /** 30369 * Internal dependencies 30370 */ 30371 30372 30373 30374 30375 30376 30377 const FONT_SIZE_SUPPORT_KEY = 'typography.fontSize'; 30378 30379 /** 30380 * Filters registered block settings, extending attributes to include 30381 * `fontSize` and `fontWeight` attributes. 30382 * 30383 * @param {Object} settings Original block settings. 30384 * 30385 * @return {Object} Filtered block settings. 30386 */ 30387 function font_size_addAttributes(settings) { 30388 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, FONT_SIZE_SUPPORT_KEY)) { 30389 return settings; 30390 } 30391 30392 // Allow blocks to specify a default value if needed. 30393 if (!settings.attributes.fontSize) { 30394 Object.assign(settings.attributes, { 30395 fontSize: { 30396 type: 'string' 30397 } 30398 }); 30399 } 30400 return settings; 30401 } 30402 30403 /** 30404 * Override props assigned to save component to inject font size. 30405 * 30406 * @param {Object} props Additional props applied to save element. 30407 * @param {Object} blockNameOrType Block type. 30408 * @param {Object} attributes Block attributes. 30409 * 30410 * @return {Object} Filtered props applied to save element. 30411 */ 30412 function font_size_addSaveProps(props, blockNameOrType, attributes) { 30413 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockNameOrType, FONT_SIZE_SUPPORT_KEY)) { 30414 return props; 30415 } 30416 if (shouldSkipSerialization(blockNameOrType, TYPOGRAPHY_SUPPORT_KEY, 'fontSize')) { 30417 return props; 30418 } 30419 30420 // Use TokenList to dedupe classes. 30421 const classes = new (external_wp_tokenList_default())(props.className); 30422 classes.add(getFontSizeClass(attributes.fontSize)); 30423 const newClassName = classes.value; 30424 props.className = newClassName ? newClassName : undefined; 30425 return props; 30426 } 30427 30428 /** 30429 * Inspector control panel containing the font size related configuration 30430 * 30431 * @param {Object} props 30432 * 30433 * @return {Element} Font size edit element. 30434 */ 30435 function FontSizeEdit(props) { 30436 const { 30437 attributes: { 30438 fontSize, 30439 style 30440 }, 30441 setAttributes 30442 } = props; 30443 const [fontSizes] = useSettings('typography.fontSizes'); 30444 const onChange = value => { 30445 const fontSizeSlug = getFontSizeObjectByValue(fontSizes, value).slug; 30446 setAttributes({ 30447 style: cleanEmptyObject({ 30448 ...style, 30449 typography: { 30450 ...style?.typography, 30451 fontSize: fontSizeSlug ? undefined : value 30452 } 30453 }), 30454 fontSize: fontSizeSlug 30455 }); 30456 }; 30457 const fontSizeObject = getFontSize(fontSizes, fontSize, style?.typography?.fontSize); 30458 const fontSizeValue = fontSizeObject?.size || style?.typography?.fontSize || fontSize; 30459 return /*#__PURE__*/_jsx(FontSizePicker, { 30460 onChange: onChange, 30461 value: fontSizeValue, 30462 withReset: false, 30463 withSlider: true, 30464 size: "__unstable-large" 30465 }); 30466 } 30467 30468 /** 30469 * Custom hook that checks if font-size settings have been disabled. 30470 * 30471 * @param {string} name The name of the block. 30472 * @return {boolean} Whether setting is disabled. 30473 */ 30474 function useIsFontSizeDisabled({ 30475 name: blockName 30476 } = {}) { 30477 const [fontSizes] = useSettings('typography.fontSizes'); 30478 const hasFontSizes = !!fontSizes?.length; 30479 return !hasBlockSupport(blockName, FONT_SIZE_SUPPORT_KEY) || !hasFontSizes; 30480 } 30481 function font_size_useBlockProps({ 30482 name, 30483 fontSize, 30484 style 30485 }) { 30486 const [fontSizes, fluidTypographySettings, layoutSettings] = use_settings_useSettings('typography.fontSizes', 'typography.fluid', 'layout'); 30487 30488 /* 30489 * Only add inline styles if the block supports font sizes, 30490 * doesn't skip serialization of font sizes, 30491 * and has either a custom font size or a preset font size. 30492 */ 30493 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, FONT_SIZE_SUPPORT_KEY) || shouldSkipSerialization(name, TYPOGRAPHY_SUPPORT_KEY, 'fontSize') || !fontSize && !style?.typography?.fontSize) { 30494 return; 30495 } 30496 let props; 30497 if (style?.typography?.fontSize) { 30498 props = { 30499 style: { 30500 fontSize: getTypographyFontSizeValue({ 30501 size: style.typography.fontSize 30502 }, { 30503 typography: { 30504 fluid: fluidTypographySettings 30505 }, 30506 layout: layoutSettings 30507 }) 30508 } 30509 }; 30510 } 30511 if (fontSize) { 30512 props = { 30513 style: { 30514 fontSize: utils_getFontSize(fontSizes, fontSize, style?.typography?.fontSize).size 30515 } 30516 }; 30517 } 30518 if (!props) { 30519 return; 30520 } 30521 return font_size_addSaveProps(props, name, { 30522 fontSize 30523 }); 30524 } 30525 /* harmony default export */ const font_size = ({ 30526 useBlockProps: font_size_useBlockProps, 30527 addSaveProps: font_size_addSaveProps, 30528 attributeKeys: ['fontSize', 'style'], 30529 hasSupport(name) { 30530 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, FONT_SIZE_SUPPORT_KEY); 30531 } 30532 }); 30533 const font_size_MIGRATION_PATHS = { 30534 fontSize: [['fontSize'], ['style', 'typography', 'fontSize']] 30535 }; 30536 function font_size_addTransforms(result, source, index, results) { 30537 const destinationBlockType = result.name; 30538 const activeSupports = { 30539 fontSize: (0,external_wp_blocks_namespaceObject.hasBlockSupport)(destinationBlockType, FONT_SIZE_SUPPORT_KEY) 30540 }; 30541 return transformStyles(activeSupports, font_size_MIGRATION_PATHS, result, source, index, results); 30542 } 30543 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/font/addAttribute', font_size_addAttributes); 30544 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/font-size/addTransforms', font_size_addTransforms); 30545 30546 ;// ./node_modules/@wordpress/block-editor/build-module/components/alignment-control/ui.js 30547 /** 30548 * WordPress dependencies 30549 */ 30550 30551 30552 30553 30554 const DEFAULT_ALIGNMENT_CONTROLS = [{ 30555 icon: align_left, 30556 title: (0,external_wp_i18n_namespaceObject.__)('Align text left'), 30557 align: 'left' 30558 }, { 30559 icon: align_center, 30560 title: (0,external_wp_i18n_namespaceObject.__)('Align text center'), 30561 align: 'center' 30562 }, { 30563 icon: align_right, 30564 title: (0,external_wp_i18n_namespaceObject.__)('Align text right'), 30565 align: 'right' 30566 }]; 30567 const ui_POPOVER_PROPS = { 30568 placement: 'bottom-start' 30569 }; 30570 function AlignmentUI({ 30571 value, 30572 onChange, 30573 alignmentControls = DEFAULT_ALIGNMENT_CONTROLS, 30574 label = (0,external_wp_i18n_namespaceObject.__)('Align text'), 30575 description = (0,external_wp_i18n_namespaceObject.__)('Change text alignment'), 30576 isCollapsed = true, 30577 isToolbar 30578 }) { 30579 function applyOrUnset(align) { 30580 return () => onChange(value === align ? undefined : align); 30581 } 30582 const activeAlignment = alignmentControls.find(control => control.align === value); 30583 function setIcon() { 30584 if (activeAlignment) { 30585 return activeAlignment.icon; 30586 } 30587 return (0,external_wp_i18n_namespaceObject.isRTL)() ? align_right : align_left; 30588 } 30589 const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu; 30590 const extraProps = isToolbar ? { 30591 isCollapsed 30592 } : { 30593 toggleProps: { 30594 description 30595 }, 30596 popoverProps: ui_POPOVER_PROPS 30597 }; 30598 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(UIComponent, { 30599 icon: setIcon(), 30600 label: label, 30601 controls: alignmentControls.map(control => { 30602 const { 30603 align 30604 } = control; 30605 const isActive = value === align; 30606 return { 30607 ...control, 30608 isActive, 30609 role: isCollapsed ? 'menuitemradio' : undefined, 30610 onClick: applyOrUnset(align) 30611 }; 30612 }), 30613 ...extraProps 30614 }); 30615 } 30616 /* harmony default export */ const alignment_control_ui = (AlignmentUI); 30617 30618 ;// ./node_modules/@wordpress/block-editor/build-module/components/alignment-control/index.js 30619 /** 30620 * Internal dependencies 30621 */ 30622 30623 30624 const AlignmentControl = props => { 30625 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(alignment_control_ui, { 30626 ...props, 30627 isToolbar: false 30628 }); 30629 }; 30630 const AlignmentToolbar = props => { 30631 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(alignment_control_ui, { 30632 ...props, 30633 isToolbar: true 30634 }); 30635 }; 30636 30637 /** 30638 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/alignment-control/README.md 30639 */ 30640 30641 30642 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/text-align.js 30643 /** 30644 * External dependencies 30645 */ 30646 30647 30648 /** 30649 * WordPress dependencies 30650 */ 30651 30652 30653 30654 30655 /** 30656 * Internal dependencies 30657 */ 30658 30659 30660 30661 30662 30663 const TEXT_ALIGN_SUPPORT_KEY = 'typography.textAlign'; 30664 const text_align_TEXT_ALIGNMENT_OPTIONS = [{ 30665 icon: align_left, 30666 title: (0,external_wp_i18n_namespaceObject.__)('Align text left'), 30667 align: 'left' 30668 }, { 30669 icon: align_center, 30670 title: (0,external_wp_i18n_namespaceObject.__)('Align text center'), 30671 align: 'center' 30672 }, { 30673 icon: align_right, 30674 title: (0,external_wp_i18n_namespaceObject.__)('Align text right'), 30675 align: 'right' 30676 }]; 30677 const VALID_TEXT_ALIGNMENTS = ['left', 'center', 'right']; 30678 const NO_TEXT_ALIGNMENTS = []; 30679 30680 /** 30681 * Returns the valid text alignments. 30682 * Takes into consideration the text aligns supported by a block. 30683 * Exported just for testing purposes, not exported outside the module. 30684 * 30685 * @param {?boolean|string[]} blockTextAlign Text aligns supported by the block. 30686 * 30687 * @return {string[]} Valid text alignments. 30688 */ 30689 function getValidTextAlignments(blockTextAlign) { 30690 if (Array.isArray(blockTextAlign)) { 30691 return VALID_TEXT_ALIGNMENTS.filter(textAlign => blockTextAlign.includes(textAlign)); 30692 } 30693 return blockTextAlign === true ? VALID_TEXT_ALIGNMENTS : NO_TEXT_ALIGNMENTS; 30694 } 30695 function BlockEditTextAlignmentToolbarControlsPure({ 30696 style, 30697 name: blockName, 30698 setAttributes 30699 }) { 30700 const settings = useBlockSettings(blockName); 30701 const hasTextAlignControl = settings?.typography?.textAlign; 30702 const blockEditingMode = useBlockEditingMode(); 30703 if (!hasTextAlignControl || blockEditingMode !== 'default') { 30704 return null; 30705 } 30706 const validTextAlignments = getValidTextAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, TEXT_ALIGN_SUPPORT_KEY)); 30707 if (!validTextAlignments.length) { 30708 return null; 30709 } 30710 const textAlignmentControls = text_align_TEXT_ALIGNMENT_OPTIONS.filter(control => validTextAlignments.includes(control.align)); 30711 const onChange = newTextAlignValue => { 30712 const newStyle = { 30713 ...style, 30714 typography: { 30715 ...style?.typography, 30716 textAlign: newTextAlignValue 30717 } 30718 }; 30719 setAttributes({ 30720 style: utils_cleanEmptyObject(newStyle) 30721 }); 30722 }; 30723 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 30724 group: "block", 30725 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AlignmentControl, { 30726 value: style?.typography?.textAlign, 30727 onChange: onChange, 30728 alignmentControls: textAlignmentControls 30729 }) 30730 }); 30731 } 30732 /* harmony default export */ const text_align = ({ 30733 edit: BlockEditTextAlignmentToolbarControlsPure, 30734 useBlockProps: text_align_useBlockProps, 30735 addSaveProps: addAssignedTextAlign, 30736 attributeKeys: ['style'], 30737 hasSupport(name) { 30738 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, TEXT_ALIGN_SUPPORT_KEY, false); 30739 } 30740 }); 30741 function text_align_useBlockProps({ 30742 name, 30743 style 30744 }) { 30745 if (!style?.typography?.textAlign) { 30746 return null; 30747 } 30748 const validTextAlignments = getValidTextAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(name, TEXT_ALIGN_SUPPORT_KEY)); 30749 if (!validTextAlignments.length) { 30750 return null; 30751 } 30752 if (shouldSkipSerialization(name, TYPOGRAPHY_SUPPORT_KEY, 'textAlign')) { 30753 return null; 30754 } 30755 const textAlign = style.typography.textAlign; 30756 const className = dist_clsx({ 30757 [`has-text-align-$textAlign}`]: textAlign 30758 }); 30759 return { 30760 className 30761 }; 30762 } 30763 30764 /** 30765 * Override props assigned to save component to inject text alignment class 30766 * name if block supports it. 30767 * 30768 * @param {Object} props Additional props applied to save element. 30769 * @param {Object} blockType Block type. 30770 * @param {Object} attributes Block attributes. 30771 * 30772 * @return {Object} Filtered props applied to save element. 30773 */ 30774 function addAssignedTextAlign(props, blockType, attributes) { 30775 if (!attributes?.style?.typography?.textAlign) { 30776 return props; 30777 } 30778 const { 30779 textAlign 30780 } = attributes.style.typography; 30781 const blockTextAlign = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, TEXT_ALIGN_SUPPORT_KEY); 30782 const isTextAlignValid = getValidTextAlignments(blockTextAlign).includes(textAlign); 30783 if (isTextAlignValid && !shouldSkipSerialization(blockType, TYPOGRAPHY_SUPPORT_KEY, 'textAlign')) { 30784 props.className = dist_clsx(`has-text-align-$textAlign}`, props.className); 30785 } 30786 return props; 30787 } 30788 30789 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/typography.js 30790 /** 30791 * WordPress dependencies 30792 */ 30793 30794 30795 30796 30797 /** 30798 * Internal dependencies 30799 */ 30800 30801 30802 30803 30804 30805 30806 30807 30808 30809 function omit(object, keys) { 30810 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 30811 } 30812 const LETTER_SPACING_SUPPORT_KEY = 'typography.__experimentalLetterSpacing'; 30813 const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform'; 30814 const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration'; 30815 const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns'; 30816 const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle'; 30817 const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight'; 30818 const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode'; 30819 const TYPOGRAPHY_SUPPORT_KEY = 'typography'; 30820 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_ALIGN_SUPPORT_KEY, TEXT_COLUMNS_SUPPORT_KEY, TEXT_DECORATION_SUPPORT_KEY, WRITING_MODE_SUPPORT_KEY, TEXT_TRANSFORM_SUPPORT_KEY, LETTER_SPACING_SUPPORT_KEY]; 30821 function typography_styleToAttributes(style) { 30822 const updatedStyle = { 30823 ...omit(style, ['fontFamily']) 30824 }; 30825 const fontSizeValue = style?.typography?.fontSize; 30826 const fontFamilyValue = style?.typography?.fontFamily; 30827 const fontSizeSlug = fontSizeValue?.startsWith('var:preset|font-size|') ? fontSizeValue.substring('var:preset|font-size|'.length) : undefined; 30828 const fontFamilySlug = fontFamilyValue?.startsWith('var:preset|font-family|') ? fontFamilyValue.substring('var:preset|font-family|'.length) : undefined; 30829 updatedStyle.typography = { 30830 ...omit(updatedStyle.typography, ['fontFamily']), 30831 fontSize: fontSizeSlug ? undefined : fontSizeValue 30832 }; 30833 return { 30834 style: utils_cleanEmptyObject(updatedStyle), 30835 fontFamily: fontFamilySlug, 30836 fontSize: fontSizeSlug 30837 }; 30838 } 30839 function typography_attributesToStyle(attributes) { 30840 return { 30841 ...attributes.style, 30842 typography: { 30843 ...attributes.style?.typography, 30844 fontFamily: attributes.fontFamily ? 'var:preset|font-family|' + attributes.fontFamily : undefined, 30845 fontSize: attributes.fontSize ? 'var:preset|font-size|' + attributes.fontSize : attributes.style?.typography?.fontSize 30846 } 30847 }; 30848 } 30849 function TypographyInspectorControl({ 30850 children, 30851 resetAllFilter 30852 }) { 30853 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 30854 const existingStyle = typography_attributesToStyle(attributes); 30855 const updatedStyle = resetAllFilter(existingStyle); 30856 return { 30857 ...attributes, 30858 ...typography_styleToAttributes(updatedStyle) 30859 }; 30860 }, [resetAllFilter]); 30861 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 30862 group: "typography", 30863 resetAllFilter: attributesResetAllFilter, 30864 children: children 30865 }); 30866 } 30867 function typography_TypographyPanel({ 30868 clientId, 30869 name, 30870 setAttributes, 30871 settings 30872 }) { 30873 function selector(select) { 30874 const { 30875 style, 30876 fontFamily, 30877 fontSize 30878 } = select(store).getBlockAttributes(clientId) || {}; 30879 return { 30880 style, 30881 fontFamily, 30882 fontSize 30883 }; 30884 } 30885 const { 30886 style, 30887 fontFamily, 30888 fontSize 30889 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 30890 const isEnabled = useHasTypographyPanel(settings); 30891 const value = (0,external_wp_element_namespaceObject.useMemo)(() => typography_attributesToStyle({ 30892 style, 30893 fontFamily, 30894 fontSize 30895 }), [style, fontSize, fontFamily]); 30896 const onChange = newStyle => { 30897 setAttributes(typography_styleToAttributes(newStyle)); 30898 }; 30899 if (!isEnabled) { 30900 return null; 30901 } 30902 const defaultControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [TYPOGRAPHY_SUPPORT_KEY, '__experimentalDefaultControls']); 30903 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TypographyPanel, { 30904 as: TypographyInspectorControl, 30905 panelId: clientId, 30906 settings: settings, 30907 value: value, 30908 onChange: onChange, 30909 defaultControls: defaultControls 30910 }); 30911 } 30912 const hasTypographySupport = blockName => { 30913 return TYPOGRAPHY_SUPPORT_KEYS.some(key => hasBlockSupport(blockName, key)); 30914 }; 30915 30916 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/hooks/use-spacing-sizes.js 30917 /** 30918 * WordPress dependencies 30919 */ 30920 30921 30922 30923 /** 30924 * Internal dependencies 30925 */ 30926 30927 30928 const use_spacing_sizes_EMPTY_ARRAY = []; 30929 const compare = new Intl.Collator('und', { 30930 numeric: true 30931 }).compare; 30932 function useSpacingSizes() { 30933 const [customSpacingSizes, themeSpacingSizes, defaultSpacingSizes, defaultSpacingSizesEnabled] = use_settings_useSettings('spacing.spacingSizes.custom', 'spacing.spacingSizes.theme', 'spacing.spacingSizes.default', 'spacing.defaultSpacingSizes'); 30934 const customSizes = customSpacingSizes !== null && customSpacingSizes !== void 0 ? customSpacingSizes : use_spacing_sizes_EMPTY_ARRAY; 30935 const themeSizes = themeSpacingSizes !== null && themeSpacingSizes !== void 0 ? themeSpacingSizes : use_spacing_sizes_EMPTY_ARRAY; 30936 const defaultSizes = defaultSpacingSizes && defaultSpacingSizesEnabled !== false ? defaultSpacingSizes : use_spacing_sizes_EMPTY_ARRAY; 30937 return (0,external_wp_element_namespaceObject.useMemo)(() => { 30938 const sizes = [{ 30939 name: (0,external_wp_i18n_namespaceObject.__)('None'), 30940 slug: '0', 30941 size: 0 30942 }, ...customSizes, ...themeSizes, ...defaultSizes]; 30943 30944 // Using numeric slugs opts-in to sorting by slug. 30945 if (sizes.every(({ 30946 slug 30947 }) => /^[0-9]/.test(slug))) { 30948 sizes.sort((a, b) => compare(a.slug, b.slug)); 30949 } 30950 return sizes.length > RANGE_CONTROL_MAX_SIZE ? [{ 30951 name: (0,external_wp_i18n_namespaceObject.__)('Default'), 30952 slug: 'default', 30953 size: undefined 30954 }, ...sizes] : sizes; 30955 }, [customSizes, themeSizes, defaultSizes]); 30956 } 30957 30958 ;// ./node_modules/@wordpress/icons/build-module/library/settings.js 30959 /** 30960 * WordPress dependencies 30961 */ 30962 30963 30964 const settings_settings = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_primitives_namespaceObject.SVG, { 30965 xmlns: "http://www.w3.org/2000/svg", 30966 viewBox: "0 0 24 24", 30967 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 30968 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" 30969 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 30970 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" 30971 })] 30972 }); 30973 /* harmony default export */ const library_settings = (settings_settings); 30974 30975 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/spacing-input-control.js 30976 /** 30977 * WordPress dependencies 30978 */ 30979 30980 30981 30982 30983 30984 30985 30986 /** 30987 * Internal dependencies 30988 */ 30989 30990 30991 30992 30993 const CUSTOM_VALUE_SETTINGS = { 30994 px: { 30995 max: 300, 30996 steps: 1 30997 }, 30998 '%': { 30999 max: 100, 31000 steps: 1 31001 }, 31002 vw: { 31003 max: 100, 31004 steps: 1 31005 }, 31006 vh: { 31007 max: 100, 31008 steps: 1 31009 }, 31010 em: { 31011 max: 10, 31012 steps: 0.1 31013 }, 31014 rm: { 31015 max: 10, 31016 steps: 0.1 31017 }, 31018 svw: { 31019 max: 100, 31020 steps: 1 31021 }, 31022 lvw: { 31023 max: 100, 31024 steps: 1 31025 }, 31026 dvw: { 31027 max: 100, 31028 steps: 1 31029 }, 31030 svh: { 31031 max: 100, 31032 steps: 1 31033 }, 31034 lvh: { 31035 max: 100, 31036 steps: 1 31037 }, 31038 dvh: { 31039 max: 100, 31040 steps: 1 31041 }, 31042 vi: { 31043 max: 100, 31044 steps: 1 31045 }, 31046 svi: { 31047 max: 100, 31048 steps: 1 31049 }, 31050 lvi: { 31051 max: 100, 31052 steps: 1 31053 }, 31054 dvi: { 31055 max: 100, 31056 steps: 1 31057 }, 31058 vb: { 31059 max: 100, 31060 steps: 1 31061 }, 31062 svb: { 31063 max: 100, 31064 steps: 1 31065 }, 31066 lvb: { 31067 max: 100, 31068 steps: 1 31069 }, 31070 dvb: { 31071 max: 100, 31072 steps: 1 31073 }, 31074 vmin: { 31075 max: 100, 31076 steps: 1 31077 }, 31078 svmin: { 31079 max: 100, 31080 steps: 1 31081 }, 31082 lvmin: { 31083 max: 100, 31084 steps: 1 31085 }, 31086 dvmin: { 31087 max: 100, 31088 steps: 1 31089 }, 31090 vmax: { 31091 max: 100, 31092 steps: 1 31093 }, 31094 svmax: { 31095 max: 100, 31096 steps: 1 31097 }, 31098 lvmax: { 31099 max: 100, 31100 steps: 1 31101 }, 31102 dvmax: { 31103 max: 100, 31104 steps: 1 31105 } 31106 }; 31107 function SpacingInputControl({ 31108 icon, 31109 isMixed = false, 31110 minimumCustomValue, 31111 onChange, 31112 onMouseOut, 31113 onMouseOver, 31114 showSideInLabel = true, 31115 side, 31116 spacingSizes, 31117 type, 31118 value 31119 }) { 31120 var _CUSTOM_VALUE_SETTING, _CUSTOM_VALUE_SETTING2; 31121 // Treat value as a preset value if the passed in value matches the value of one of the spacingSizes. 31122 value = getPresetValueFromCustomValue(value, spacingSizes); 31123 let selectListSizes = spacingSizes; 31124 const showRangeControl = spacingSizes.length <= RANGE_CONTROL_MAX_SIZE; 31125 const disableCustomSpacingSizes = (0,external_wp_data_namespaceObject.useSelect)(select => { 31126 const editorSettings = select(store).getSettings(); 31127 return editorSettings?.disableCustomSpacingSizes; 31128 }); 31129 const [showCustomValueControl, setShowCustomValueControl] = (0,external_wp_element_namespaceObject.useState)(!disableCustomSpacingSizes && value !== undefined && !isValueSpacingPreset(value)); 31130 const [minValue, setMinValue] = (0,external_wp_element_namespaceObject.useState)(minimumCustomValue); 31131 const previousValue = (0,external_wp_compose_namespaceObject.usePrevious)(value); 31132 if (!!value && previousValue !== value && !isValueSpacingPreset(value) && showCustomValueControl !== true) { 31133 setShowCustomValueControl(true); 31134 } 31135 const [availableUnits] = use_settings_useSettings('spacing.units'); 31136 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 31137 availableUnits: availableUnits || ['px', 'em', 'rem'] 31138 }); 31139 let currentValue = null; 31140 const showCustomValueInSelectList = !showRangeControl && !showCustomValueControl && value !== undefined && (!isValueSpacingPreset(value) || isValueSpacingPreset(value) && isMixed); 31141 if (showCustomValueInSelectList) { 31142 selectListSizes = [...spacingSizes, { 31143 name: !isMixed ? 31144 // translators: %s: A custom measurement, e.g. a number followed by a unit like 12px. 31145 (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Custom (%s)'), value) : (0,external_wp_i18n_namespaceObject.__)('Mixed'), 31146 slug: 'custom', 31147 size: value 31148 }]; 31149 currentValue = selectListSizes.length - 1; 31150 } else if (!isMixed) { 31151 currentValue = !showCustomValueControl ? getSliderValueFromPreset(value, spacingSizes) : getCustomValueFromPreset(value, spacingSizes); 31152 } 31153 const selectedUnit = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(currentValue), [currentValue])[1] || units[0]?.value; 31154 const setInitialValue = () => { 31155 if (value === undefined) { 31156 onChange('0'); 31157 } 31158 }; 31159 const customTooltipContent = newValue => value === undefined ? undefined : spacingSizes[newValue]?.name; 31160 const customRangeValue = parseFloat(currentValue, 10); 31161 const getNewCustomValue = newSize => { 31162 const isNumeric = !isNaN(parseFloat(newSize)); 31163 const nextValue = isNumeric ? newSize : undefined; 31164 return nextValue; 31165 }; 31166 const getNewPresetValue = (newSize, controlType) => { 31167 const size = parseInt(newSize, 10); 31168 if (controlType === 'selectList') { 31169 if (size === 0) { 31170 return undefined; 31171 } 31172 if (size === 1) { 31173 return '0'; 31174 } 31175 } else if (size === 0) { 31176 return '0'; 31177 } 31178 return `var:preset|spacing|$spacingSizes[newSize]?.slug}`; 31179 }; 31180 const handleCustomValueSliderChange = next => { 31181 onChange([next, selectedUnit].join('')); 31182 }; 31183 const allPlaceholder = isMixed ? (0,external_wp_i18n_namespaceObject.__)('Mixed') : null; 31184 const options = selectListSizes.map((size, index) => ({ 31185 key: index, 31186 name: size.name 31187 })); 31188 const marks = spacingSizes.slice(1, spacingSizes.length - 1).map((_newValue, index) => ({ 31189 value: index + 1, 31190 label: undefined 31191 })); 31192 const sideLabel = ALL_SIDES.includes(side) && showSideInLabel ? LABELS[side] : ''; 31193 const typeLabel = showSideInLabel ? type?.toLowerCase() : type; 31194 const ariaLabel = (0,external_wp_i18n_namespaceObject.sprintf)( 31195 // translators: 1: The side of the block being modified (top, bottom, left etc.). 2. Type of spacing being modified (padding, margin, etc). 31196 (0,external_wp_i18n_namespaceObject._x)('%1$s %2$s', 'spacing'), sideLabel, typeLabel).trim(); 31197 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 31198 className: "spacing-sizes-control__wrapper", 31199 children: [icon && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 31200 className: "spacing-sizes-control__icon", 31201 icon: icon, 31202 size: 24 31203 }), showCustomValueControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 31204 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 31205 onMouseOver: onMouseOver, 31206 onMouseOut: onMouseOut, 31207 onFocus: onMouseOver, 31208 onBlur: onMouseOut, 31209 onChange: newSize => onChange(getNewCustomValue(newSize)), 31210 value: currentValue, 31211 units: units, 31212 min: minValue, 31213 placeholder: allPlaceholder, 31214 disableUnits: isMixed, 31215 label: ariaLabel, 31216 hideLabelFromVision: true, 31217 className: "spacing-sizes-control__custom-value-input", 31218 size: "__unstable-large", 31219 onDragStart: () => { 31220 if (value?.charAt(0) === '-') { 31221 setMinValue(0); 31222 } 31223 }, 31224 onDrag: () => { 31225 if (value?.charAt(0) === '-') { 31226 setMinValue(0); 31227 } 31228 }, 31229 onDragEnd: () => { 31230 setMinValue(minimumCustomValue); 31231 } 31232 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 31233 __next40pxDefaultSize: true, 31234 onMouseOver: onMouseOver, 31235 onMouseOut: onMouseOut, 31236 onFocus: onMouseOver, 31237 onBlur: onMouseOut, 31238 value: customRangeValue, 31239 min: 0, 31240 max: (_CUSTOM_VALUE_SETTING = CUSTOM_VALUE_SETTINGS[selectedUnit]?.max) !== null && _CUSTOM_VALUE_SETTING !== void 0 ? _CUSTOM_VALUE_SETTING : 10, 31241 step: (_CUSTOM_VALUE_SETTING2 = CUSTOM_VALUE_SETTINGS[selectedUnit]?.steps) !== null && _CUSTOM_VALUE_SETTING2 !== void 0 ? _CUSTOM_VALUE_SETTING2 : 0.1, 31242 withInputField: false, 31243 onChange: handleCustomValueSliderChange, 31244 className: "spacing-sizes-control__custom-value-range", 31245 __nextHasNoMarginBottom: true, 31246 label: ariaLabel, 31247 hideLabelFromVision: true 31248 })] 31249 }), showRangeControl && !showCustomValueControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 31250 __next40pxDefaultSize: true, 31251 onMouseOver: onMouseOver, 31252 onMouseOut: onMouseOut, 31253 className: "spacing-sizes-control__range-control", 31254 value: currentValue, 31255 onChange: newSize => onChange(getNewPresetValue(newSize)), 31256 onMouseDown: event => { 31257 // If mouse down is near start of range set initial value to 0, which 31258 // prevents the user have to drag right then left to get 0 setting. 31259 if (event?.nativeEvent?.offsetX < 35) { 31260 setInitialValue(); 31261 } 31262 }, 31263 withInputField: false, 31264 "aria-valuenow": currentValue, 31265 "aria-valuetext": spacingSizes[currentValue]?.name, 31266 renderTooltipContent: customTooltipContent, 31267 min: 0, 31268 max: spacingSizes.length - 1, 31269 marks: marks, 31270 label: ariaLabel, 31271 hideLabelFromVision: true, 31272 __nextHasNoMarginBottom: true, 31273 onFocus: onMouseOver, 31274 onBlur: onMouseOut 31275 }), !showRangeControl && !showCustomValueControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CustomSelectControl, { 31276 className: "spacing-sizes-control__custom-select-control", 31277 value: 31278 // passing empty string as a fallback to continue using the 31279 // component in controlled mode 31280 options.find(option => option.key === currentValue) || '', 31281 onChange: selection => { 31282 onChange(getNewPresetValue(selection.selectedItem.key, 'selectList')); 31283 }, 31284 options: options, 31285 label: ariaLabel, 31286 hideLabelFromVision: true, 31287 size: "__unstable-large", 31288 onMouseOver: onMouseOver, 31289 onMouseOut: onMouseOut, 31290 onFocus: onMouseOver, 31291 onBlur: onMouseOut 31292 }), !disableCustomSpacingSizes && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 31293 label: showCustomValueControl ? (0,external_wp_i18n_namespaceObject.__)('Use size preset') : (0,external_wp_i18n_namespaceObject.__)('Set custom size'), 31294 icon: library_settings, 31295 onClick: () => { 31296 setShowCustomValueControl(!showCustomValueControl); 31297 }, 31298 isPressed: showCustomValueControl, 31299 size: "small", 31300 className: "spacing-sizes-control__custom-toggle", 31301 iconSize: 24 31302 })] 31303 }); 31304 } 31305 31306 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/axial.js 31307 /** 31308 * Internal dependencies 31309 */ 31310 31311 31312 31313 const groupedSides = ['vertical', 'horizontal']; 31314 function AxialInputControls({ 31315 minimumCustomValue, 31316 onChange, 31317 onMouseOut, 31318 onMouseOver, 31319 sides, 31320 spacingSizes, 31321 type, 31322 values 31323 }) { 31324 const createHandleOnChange = side => next => { 31325 if (!onChange) { 31326 return; 31327 } 31328 31329 // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. 31330 const nextValues = { 31331 ...Object.keys(values).reduce((acc, key) => { 31332 acc[key] = getPresetValueFromCustomValue(values[key], spacingSizes); 31333 return acc; 31334 }, {}) 31335 }; 31336 if (side === 'vertical') { 31337 nextValues.top = next; 31338 nextValues.bottom = next; 31339 } 31340 if (side === 'horizontal') { 31341 nextValues.left = next; 31342 nextValues.right = next; 31343 } 31344 onChange(nextValues); 31345 }; 31346 31347 // Filter sides if custom configuration provided, maintaining default order. 31348 const filteredSides = sides?.length ? groupedSides.filter(side => hasAxisSupport(sides, side)) : groupedSides; 31349 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 31350 children: filteredSides.map(side => { 31351 const axisValue = side === 'vertical' ? values.top : values.left; 31352 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingInputControl, { 31353 icon: ICONS[side], 31354 label: LABELS[side], 31355 minimumCustomValue: minimumCustomValue, 31356 onChange: createHandleOnChange(side), 31357 onMouseOut: onMouseOut, 31358 onMouseOver: onMouseOver, 31359 side: side, 31360 spacingSizes: spacingSizes, 31361 type: type, 31362 value: axisValue, 31363 withInputField: false 31364 }, `spacing-sizes-control-$side}`); 31365 }) 31366 }); 31367 } 31368 31369 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/separated.js 31370 /** 31371 * Internal dependencies 31372 */ 31373 31374 31375 31376 function SeparatedInputControls({ 31377 minimumCustomValue, 31378 onChange, 31379 onMouseOut, 31380 onMouseOver, 31381 sides, 31382 spacingSizes, 31383 type, 31384 values 31385 }) { 31386 // Filter sides if custom configuration provided, maintaining default order. 31387 const filteredSides = sides?.length ? ALL_SIDES.filter(side => sides.includes(side)) : ALL_SIDES; 31388 const createHandleOnChange = side => next => { 31389 // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. 31390 const nextValues = { 31391 ...Object.keys(values).reduce((acc, key) => { 31392 acc[key] = getPresetValueFromCustomValue(values[key], spacingSizes); 31393 return acc; 31394 }, {}) 31395 }; 31396 nextValues[side] = next; 31397 onChange(nextValues); 31398 }; 31399 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 31400 children: filteredSides.map(side => { 31401 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingInputControl, { 31402 icon: ICONS[side], 31403 label: LABELS[side], 31404 minimumCustomValue: minimumCustomValue, 31405 onChange: createHandleOnChange(side), 31406 onMouseOut: onMouseOut, 31407 onMouseOver: onMouseOver, 31408 side: side, 31409 spacingSizes: spacingSizes, 31410 type: type, 31411 value: values[side], 31412 withInputField: false 31413 }, `spacing-sizes-control-$side}`); 31414 }) 31415 }); 31416 } 31417 31418 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/input-controls/single.js 31419 /** 31420 * Internal dependencies 31421 */ 31422 31423 31424 31425 function SingleInputControl({ 31426 minimumCustomValue, 31427 onChange, 31428 onMouseOut, 31429 onMouseOver, 31430 showSideInLabel, 31431 side, 31432 spacingSizes, 31433 type, 31434 values 31435 }) { 31436 const createHandleOnChange = currentSide => next => { 31437 // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. 31438 const nextValues = { 31439 ...Object.keys(values).reduce((acc, key) => { 31440 acc[key] = getPresetValueFromCustomValue(values[key], spacingSizes); 31441 return acc; 31442 }, {}) 31443 }; 31444 nextValues[currentSide] = next; 31445 onChange(nextValues); 31446 }; 31447 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingInputControl, { 31448 label: LABELS[side], 31449 minimumCustomValue: minimumCustomValue, 31450 onChange: createHandleOnChange(side), 31451 onMouseOut: onMouseOut, 31452 onMouseOver: onMouseOver, 31453 showSideInLabel: showSideInLabel, 31454 side: side, 31455 spacingSizes: spacingSizes, 31456 type: type, 31457 value: values[side], 31458 withInputField: false 31459 }); 31460 } 31461 31462 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/linked-button.js 31463 /** 31464 * WordPress dependencies 31465 */ 31466 31467 31468 31469 31470 function linked_button_LinkedButton({ 31471 isLinked, 31472 ...props 31473 }) { 31474 const label = isLinked ? (0,external_wp_i18n_namespaceObject.__)('Unlink sides') : (0,external_wp_i18n_namespaceObject.__)('Link sides'); 31475 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 31476 ...props, 31477 size: "small", 31478 icon: isLinked ? library_link : link_off, 31479 iconSize: 24, 31480 label: label 31481 }); 31482 } 31483 31484 ;// ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/index.js 31485 /** 31486 * WordPress dependencies 31487 */ 31488 31489 31490 31491 31492 /** 31493 * Internal dependencies 31494 */ 31495 31496 31497 31498 31499 31500 31501 31502 /** 31503 * A flexible control for managing spacing values in the block editor. Supports single, axial, 31504 * and separated input controls for different spacing configurations with automatic view selection 31505 * based on current values and available sides. 31506 * 31507 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/spacing-sizes-control/README.md 31508 * 31509 * @example 31510 * ```jsx 31511 * import { __experimentalSpacingSizesControl as SpacingSizesControl } from '@wordpress/block-editor'; 31512 * import { useState } from '@wordpress/element'; 31513 * 31514 * function Example() { 31515 * const [ sides, setSides ] = useState( { 31516 * top: '0px', 31517 * right: '0px', 31518 * bottom: '0px', 31519 * left: '0px', 31520 * } ); 31521 * 31522 * return ( 31523 * <SpacingSizesControl 31524 * values={ sides } 31525 * onChange={ setSides } 31526 * label="Sides" 31527 * /> 31528 * ); 31529 * } 31530 * ``` 31531 * 31532 * @param {Object} props Component props. 31533 * @param {Object} props.inputProps Additional props for input controls. 31534 * @param {string} props.label Label for the control. 31535 * @param {number} props.minimumCustomValue Minimum value for custom input. 31536 * @param {Function} props.onChange Called when spacing values change. 31537 * @param {Function} props.onMouseOut Called when mouse leaves the control. 31538 * @param {Function} props.onMouseOver Called when mouse enters the control. 31539 * @param {boolean} props.showSideInLabel Show side in control label. 31540 * @param {Array} props.sides Available sides for control. 31541 * @param {boolean} props.useSelect Use select control for predefined values. 31542 * @param {Object} props.values Current spacing values. 31543 * @return {Element} Spacing sizes control component. 31544 */ 31545 31546 function SpacingSizesControl({ 31547 inputProps, 31548 label: labelProp, 31549 minimumCustomValue = 0, 31550 onChange, 31551 onMouseOut, 31552 onMouseOver, 31553 showSideInLabel = true, 31554 sides = ALL_SIDES, 31555 useSelect, 31556 values 31557 }) { 31558 const spacingSizes = useSpacingSizes(); 31559 const inputValues = values || DEFAULT_VALUES; 31560 const hasOneSide = sides?.length === 1; 31561 const hasOnlyAxialSides = sides?.includes('horizontal') && sides?.includes('vertical') && sides?.length === 2; 31562 const [view, setView] = (0,external_wp_element_namespaceObject.useState)(getInitialView(inputValues, sides)); 31563 const toggleLinked = () => { 31564 setView(view === VIEWS.axial ? VIEWS.custom : VIEWS.axial); 31565 }; 31566 const handleOnChange = nextValue => { 31567 const newValues = { 31568 ...values, 31569 ...nextValue 31570 }; 31571 onChange(newValues); 31572 }; 31573 const inputControlProps = { 31574 ...inputProps, 31575 minimumCustomValue, 31576 onChange: handleOnChange, 31577 onMouseOut, 31578 onMouseOver, 31579 sides, 31580 spacingSizes, 31581 type: labelProp, 31582 useSelect, 31583 values: inputValues 31584 }; 31585 const renderControls = () => { 31586 if (view === VIEWS.axial) { 31587 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AxialInputControls, { 31588 ...inputControlProps 31589 }); 31590 } 31591 if (view === VIEWS.custom) { 31592 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SeparatedInputControls, { 31593 ...inputControlProps 31594 }); 31595 } 31596 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SingleInputControl, { 31597 side: view, 31598 ...inputControlProps, 31599 showSideInLabel: showSideInLabel 31600 }); 31601 }; 31602 const sideLabel = ALL_SIDES.includes(view) && showSideInLabel ? LABELS[view] : ''; 31603 const label = (0,external_wp_i18n_namespaceObject.sprintf)( 31604 // translators: 1: The side of the block being modified (top, bottom, left etc.). 2. Type of spacing being modified (padding, margin, etc). 31605 (0,external_wp_i18n_namespaceObject._x)('%1$s %2$s', 'spacing'), labelProp, sideLabel).trim(); 31606 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 31607 className: "spacing-sizes-control", 31608 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 31609 className: "spacing-sizes-control__header", 31610 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 31611 as: "legend", 31612 className: "spacing-sizes-control__label", 31613 children: label 31614 }), !hasOneSide && !hasOnlyAxialSides && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(linked_button_LinkedButton, { 31615 label: labelProp, 31616 onClick: toggleLinked, 31617 isLinked: view === VIEWS.axial 31618 })] 31619 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalVStack, { 31620 spacing: 0.5, 31621 children: renderControls() 31622 })] 31623 }); 31624 } 31625 31626 ;// ./node_modules/@wordpress/block-editor/build-module/components/height-control/index.js 31627 /** 31628 * WordPress dependencies 31629 */ 31630 31631 31632 31633 31634 /** 31635 * Internal dependencies 31636 */ 31637 31638 31639 const RANGE_CONTROL_CUSTOM_SETTINGS = { 31640 px: { 31641 max: 1000, 31642 step: 1 31643 }, 31644 '%': { 31645 max: 100, 31646 step: 1 31647 }, 31648 vw: { 31649 max: 100, 31650 step: 1 31651 }, 31652 vh: { 31653 max: 100, 31654 step: 1 31655 }, 31656 em: { 31657 max: 50, 31658 step: 0.1 31659 }, 31660 rem: { 31661 max: 50, 31662 step: 0.1 31663 }, 31664 svw: { 31665 max: 100, 31666 step: 1 31667 }, 31668 lvw: { 31669 max: 100, 31670 step: 1 31671 }, 31672 dvw: { 31673 max: 100, 31674 step: 1 31675 }, 31676 svh: { 31677 max: 100, 31678 step: 1 31679 }, 31680 lvh: { 31681 max: 100, 31682 step: 1 31683 }, 31684 dvh: { 31685 max: 100, 31686 step: 1 31687 }, 31688 vi: { 31689 max: 100, 31690 step: 1 31691 }, 31692 svi: { 31693 max: 100, 31694 step: 1 31695 }, 31696 lvi: { 31697 max: 100, 31698 step: 1 31699 }, 31700 dvi: { 31701 max: 100, 31702 step: 1 31703 }, 31704 vb: { 31705 max: 100, 31706 step: 1 31707 }, 31708 svb: { 31709 max: 100, 31710 step: 1 31711 }, 31712 lvb: { 31713 max: 100, 31714 step: 1 31715 }, 31716 dvb: { 31717 max: 100, 31718 step: 1 31719 }, 31720 vmin: { 31721 max: 100, 31722 step: 1 31723 }, 31724 svmin: { 31725 max: 100, 31726 step: 1 31727 }, 31728 lvmin: { 31729 max: 100, 31730 step: 1 31731 }, 31732 dvmin: { 31733 max: 100, 31734 step: 1 31735 }, 31736 vmax: { 31737 max: 100, 31738 step: 1 31739 }, 31740 svmax: { 31741 max: 100, 31742 step: 1 31743 }, 31744 lvmax: { 31745 max: 100, 31746 step: 1 31747 }, 31748 dvmax: { 31749 max: 100, 31750 step: 1 31751 } 31752 }; 31753 31754 /** 31755 * HeightControl renders a linked unit control and range control for adjusting the height of a block. 31756 * 31757 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/height-control/README.md 31758 * 31759 * @param {Object} props 31760 * @param {?string} props.label A label for the control. 31761 * @param {( value: string ) => void } props.onChange Called when the height changes. 31762 * @param {string} props.value The current height value. 31763 * 31764 * @return {Component} The component to be rendered. 31765 */ 31766 function HeightControl({ 31767 label = (0,external_wp_i18n_namespaceObject.__)('Height'), 31768 onChange, 31769 value 31770 }) { 31771 var _RANGE_CONTROL_CUSTOM, _RANGE_CONTROL_CUSTOM2; 31772 const customRangeValue = parseFloat(value); 31773 const [availableUnits] = use_settings_useSettings('spacing.units'); 31774 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 31775 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vh', 'vw'] 31776 }); 31777 const selectedUnit = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value), [value])[1] || units[0]?.value || 'px'; 31778 const handleSliderChange = next => { 31779 onChange([next, selectedUnit].join('')); 31780 }; 31781 const handleUnitChange = newUnit => { 31782 // Attempt to smooth over differences between currentUnit and newUnit. 31783 // This should slightly improve the experience of switching between unit types. 31784 const [currentValue, currentUnit] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value); 31785 if (['em', 'rem'].includes(newUnit) && currentUnit === 'px') { 31786 // Convert pixel value to an approximate of the new unit, assuming a root size of 16px. 31787 onChange((currentValue / 16).toFixed(2) + newUnit); 31788 } else if (['em', 'rem'].includes(currentUnit) && newUnit === 'px') { 31789 // Convert to pixel value assuming a root size of 16px. 31790 onChange(Math.round(currentValue * 16) + newUnit); 31791 } 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) { 31792 // When converting to `%` or viewport-relative units, cap the new value at 100. 31793 onChange(100 + newUnit); 31794 } 31795 }; 31796 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 31797 className: "block-editor-height-control", 31798 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl.VisualLabel, { 31799 as: "legend", 31800 children: label 31801 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 31802 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 31803 isBlock: true, 31804 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 31805 value: value, 31806 units: units, 31807 onChange: onChange, 31808 onUnitChange: handleUnitChange, 31809 min: 0, 31810 size: "__unstable-large", 31811 label: label, 31812 hideLabelFromVision: true 31813 }) 31814 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 31815 isBlock: true, 31816 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalSpacer, { 31817 marginX: 2, 31818 marginBottom: 0, 31819 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 31820 __next40pxDefaultSize: true, 31821 value: customRangeValue, 31822 min: 0, 31823 max: (_RANGE_CONTROL_CUSTOM = RANGE_CONTROL_CUSTOM_SETTINGS[selectedUnit]?.max) !== null && _RANGE_CONTROL_CUSTOM !== void 0 ? _RANGE_CONTROL_CUSTOM : 100, 31824 step: (_RANGE_CONTROL_CUSTOM2 = RANGE_CONTROL_CUSTOM_SETTINGS[selectedUnit]?.step) !== null && _RANGE_CONTROL_CUSTOM2 !== void 0 ? _RANGE_CONTROL_CUSTOM2 : 0.1, 31825 withInputField: false, 31826 onChange: handleSliderChange, 31827 __nextHasNoMarginBottom: true, 31828 label: label, 31829 hideLabelFromVision: true 31830 }) 31831 }) 31832 })] 31833 })] 31834 }); 31835 } 31836 31837 ;// ./node_modules/@wordpress/block-editor/build-module/components/grid/use-get-number-of-blocks-before-cell.js 31838 /** 31839 * WordPress dependencies 31840 */ 31841 31842 31843 /** 31844 * Internal dependencies 31845 */ 31846 31847 function useGetNumberOfBlocksBeforeCell(gridClientId, numColumns) { 31848 const { 31849 getBlockOrder, 31850 getBlockAttributes 31851 } = (0,external_wp_data_namespaceObject.useSelect)(store); 31852 const getNumberOfBlocksBeforeCell = (column, row) => { 31853 const targetIndex = (row - 1) * numColumns + column - 1; 31854 let count = 0; 31855 for (const clientId of getBlockOrder(gridClientId)) { 31856 var _getBlockAttributes$s; 31857 const { 31858 columnStart, 31859 rowStart 31860 } = (_getBlockAttributes$s = getBlockAttributes(clientId).style?.layout) !== null && _getBlockAttributes$s !== void 0 ? _getBlockAttributes$s : {}; 31861 const cellIndex = (rowStart - 1) * numColumns + columnStart - 1; 31862 if (cellIndex < targetIndex) { 31863 count++; 31864 } 31865 } 31866 return count; 31867 }; 31868 return getNumberOfBlocksBeforeCell; 31869 } 31870 31871 ;// ./node_modules/@wordpress/block-editor/build-module/components/child-layout-control/index.js 31872 /** 31873 * WordPress dependencies 31874 */ 31875 31876 31877 31878 31879 31880 /** 31881 * Internal dependencies 31882 */ 31883 31884 31885 31886 31887 function helpText(selfStretch, parentLayout) { 31888 const { 31889 orientation = 'horizontal' 31890 } = parentLayout; 31891 if (selfStretch === 'fill') { 31892 return (0,external_wp_i18n_namespaceObject.__)('Stretch to fill available space.'); 31893 } 31894 if (selfStretch === 'fixed' && orientation === 'horizontal') { 31895 return (0,external_wp_i18n_namespaceObject.__)('Specify a fixed width.'); 31896 } else if (selfStretch === 'fixed') { 31897 return (0,external_wp_i18n_namespaceObject.__)('Specify a fixed height.'); 31898 } 31899 return (0,external_wp_i18n_namespaceObject.__)('Fit contents.'); 31900 } 31901 31902 /** 31903 * Form to edit the child layout value. 31904 * 31905 * @param {Object} props Props. 31906 * @param {Object} props.value The child layout value. 31907 * @param {Function} props.onChange Function to update the child layout value. 31908 * @param {Object} props.parentLayout The parent layout value. 31909 * 31910 * @param {boolean} props.isShownByDefault 31911 * @param {string} props.panelId 31912 * @return {Element} child layout edit element. 31913 */ 31914 function ChildLayoutControl({ 31915 value: childLayout = {}, 31916 onChange, 31917 parentLayout, 31918 isShownByDefault, 31919 panelId 31920 }) { 31921 const { 31922 type: parentType, 31923 default: { 31924 type: defaultParentType = 'default' 31925 } = {} 31926 } = parentLayout !== null && parentLayout !== void 0 ? parentLayout : {}; 31927 const parentLayoutType = parentType || defaultParentType; 31928 if (parentLayoutType === 'flex') { 31929 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FlexControls, { 31930 childLayout: childLayout, 31931 onChange: onChange, 31932 parentLayout: parentLayout, 31933 isShownByDefault: isShownByDefault, 31934 panelId: panelId 31935 }); 31936 } else if (parentLayoutType === 'grid') { 31937 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridControls, { 31938 childLayout: childLayout, 31939 onChange: onChange, 31940 parentLayout: parentLayout, 31941 isShownByDefault: isShownByDefault, 31942 panelId: panelId 31943 }); 31944 } 31945 return null; 31946 } 31947 function FlexControls({ 31948 childLayout, 31949 onChange, 31950 parentLayout, 31951 isShownByDefault, 31952 panelId 31953 }) { 31954 const { 31955 selfStretch, 31956 flexSize 31957 } = childLayout; 31958 const { 31959 orientation = 'horizontal' 31960 } = parentLayout !== null && parentLayout !== void 0 ? parentLayout : {}; 31961 const hasFlexValue = () => !!selfStretch; 31962 const flexResetLabel = orientation === 'horizontal' ? (0,external_wp_i18n_namespaceObject.__)('Width') : (0,external_wp_i18n_namespaceObject.__)('Height'); 31963 const [availableUnits] = use_settings_useSettings('spacing.units'); 31964 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 31965 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vh', 'vw'] 31966 }); 31967 const resetFlex = () => { 31968 onChange({ 31969 selfStretch: undefined, 31970 flexSize: undefined 31971 }); 31972 }; 31973 (0,external_wp_element_namespaceObject.useEffect)(() => { 31974 if (selfStretch === 'fixed' && !flexSize) { 31975 onChange({ 31976 ...childLayout, 31977 selfStretch: 'fit' 31978 }); 31979 } 31980 }, []); 31981 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 31982 as: external_wp_components_namespaceObject.__experimentalToolsPanelItem, 31983 spacing: 2, 31984 hasValue: hasFlexValue, 31985 label: flexResetLabel, 31986 onDeselect: resetFlex, 31987 isShownByDefault: isShownByDefault, 31988 panelId: panelId, 31989 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 31990 __nextHasNoMarginBottom: true, 31991 size: "__unstable-large", 31992 label: childLayoutOrientation(parentLayout), 31993 value: selfStretch || 'fit', 31994 help: helpText(selfStretch, parentLayout), 31995 onChange: value => { 31996 const newFlexSize = value !== 'fixed' ? null : flexSize; 31997 onChange({ 31998 selfStretch: value, 31999 flexSize: newFlexSize 32000 }); 32001 }, 32002 isBlock: true, 32003 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 32004 value: "fit", 32005 label: (0,external_wp_i18n_namespaceObject._x)('Fit', 'Intrinsic block width in flex layout') 32006 }, "fit"), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 32007 value: "fill", 32008 label: (0,external_wp_i18n_namespaceObject._x)('Grow', 'Block with expanding width in flex layout') 32009 }, "fill"), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 32010 value: "fixed", 32011 label: (0,external_wp_i18n_namespaceObject._x)('Fixed', 'Block with fixed width in flex layout') 32012 }, "fixed")] 32013 }), selfStretch === 'fixed' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 32014 size: "__unstable-large", 32015 units: units, 32016 onChange: value => { 32017 onChange({ 32018 selfStretch, 32019 flexSize: value 32020 }); 32021 }, 32022 value: flexSize, 32023 label: flexResetLabel, 32024 hideLabelFromVision: true 32025 })] 32026 }); 32027 } 32028 function childLayoutOrientation(parentLayout) { 32029 const { 32030 orientation = 'horizontal' 32031 } = parentLayout; 32032 return orientation === 'horizontal' ? (0,external_wp_i18n_namespaceObject.__)('Width') : (0,external_wp_i18n_namespaceObject.__)('Height'); 32033 } 32034 function GridControls({ 32035 childLayout, 32036 onChange, 32037 parentLayout, 32038 isShownByDefault, 32039 panelId 32040 }) { 32041 const { 32042 columnStart, 32043 rowStart, 32044 columnSpan, 32045 rowSpan 32046 } = childLayout; 32047 const { 32048 columnCount = 3, 32049 rowCount 32050 } = parentLayout !== null && parentLayout !== void 0 ? parentLayout : {}; 32051 const rootClientId = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlockRootClientId(panelId)); 32052 const { 32053 moveBlocksToPosition, 32054 __unstableMarkNextChangeAsNotPersistent 32055 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 32056 const getNumberOfBlocksBeforeCell = useGetNumberOfBlocksBeforeCell(rootClientId, columnCount); 32057 const hasStartValue = () => !!columnStart || !!rowStart; 32058 const hasSpanValue = () => !!columnSpan || !!rowSpan; 32059 const resetGridStarts = () => { 32060 onChange({ 32061 columnStart: undefined, 32062 rowStart: undefined 32063 }); 32064 }; 32065 const resetGridSpans = () => { 32066 onChange({ 32067 columnSpan: undefined, 32068 rowSpan: undefined 32069 }); 32070 }; 32071 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 32072 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 32073 as: external_wp_components_namespaceObject.__experimentalToolsPanelItem, 32074 hasValue: hasSpanValue, 32075 label: (0,external_wp_i18n_namespaceObject.__)('Grid span'), 32076 onDeselect: resetGridSpans, 32077 isShownByDefault: isShownByDefault, 32078 panelId: panelId, 32079 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, { 32080 size: "__unstable-large", 32081 label: (0,external_wp_i18n_namespaceObject.__)('Column span'), 32082 type: "number", 32083 onChange: value => { 32084 // Don't allow unsetting. 32085 const newColumnSpan = value === '' ? 1 : parseInt(value, 10); 32086 onChange({ 32087 columnStart, 32088 rowStart, 32089 rowSpan, 32090 columnSpan: newColumnSpan 32091 }); 32092 }, 32093 value: columnSpan !== null && columnSpan !== void 0 ? columnSpan : 1, 32094 min: 1 32095 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, { 32096 size: "__unstable-large", 32097 label: (0,external_wp_i18n_namespaceObject.__)('Row span'), 32098 type: "number", 32099 onChange: value => { 32100 // Don't allow unsetting. 32101 const newRowSpan = value === '' ? 1 : parseInt(value, 10); 32102 onChange({ 32103 columnStart, 32104 rowStart, 32105 columnSpan, 32106 rowSpan: newRowSpan 32107 }); 32108 }, 32109 value: rowSpan !== null && rowSpan !== void 0 ? rowSpan : 1, 32110 min: 1 32111 })] 32112 }), window.__experimentalEnableGridInteractivity && columnCount && 32113 /*#__PURE__*/ 32114 // Use Flex with an explicit width on the FlexItem instead of HStack to 32115 // work around an issue in webkit where inputs with a max attribute are 32116 // sized incorrectly. 32117 (0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 32118 as: external_wp_components_namespaceObject.__experimentalToolsPanelItem, 32119 hasValue: hasStartValue, 32120 label: (0,external_wp_i18n_namespaceObject.__)('Grid placement'), 32121 onDeselect: resetGridStarts, 32122 isShownByDefault: false, 32123 panelId: panelId, 32124 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 32125 style: { 32126 width: '50%' 32127 }, 32128 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, { 32129 size: "__unstable-large", 32130 label: (0,external_wp_i18n_namespaceObject.__)('Column'), 32131 type: "number", 32132 onChange: value => { 32133 // Don't allow unsetting. 32134 const newColumnStart = value === '' ? 1 : parseInt(value, 10); 32135 onChange({ 32136 columnStart: newColumnStart, 32137 rowStart, 32138 columnSpan, 32139 rowSpan 32140 }); 32141 __unstableMarkNextChangeAsNotPersistent(); 32142 moveBlocksToPosition([panelId], rootClientId, rootClientId, getNumberOfBlocksBeforeCell(newColumnStart, rowStart)); 32143 }, 32144 value: columnStart !== null && columnStart !== void 0 ? columnStart : 1, 32145 min: 1, 32146 max: columnCount ? columnCount - (columnSpan !== null && columnSpan !== void 0 ? columnSpan : 1) + 1 : undefined 32147 }) 32148 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 32149 style: { 32150 width: '50%' 32151 }, 32152 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, { 32153 size: "__unstable-large", 32154 label: (0,external_wp_i18n_namespaceObject.__)('Row'), 32155 type: "number", 32156 onChange: value => { 32157 // Don't allow unsetting. 32158 const newRowStart = value === '' ? 1 : parseInt(value, 10); 32159 onChange({ 32160 columnStart, 32161 rowStart: newRowStart, 32162 columnSpan, 32163 rowSpan 32164 }); 32165 __unstableMarkNextChangeAsNotPersistent(); 32166 moveBlocksToPosition([panelId], rootClientId, rootClientId, getNumberOfBlocksBeforeCell(columnStart, newRowStart)); 32167 }, 32168 value: rowStart !== null && rowStart !== void 0 ? rowStart : 1, 32169 min: 1, 32170 max: rowCount ? rowCount - (rowSpan !== null && rowSpan !== void 0 ? rowSpan : 1) + 1 : undefined 32171 }) 32172 })] 32173 })] 32174 }); 32175 } 32176 32177 ;// ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/aspect-ratio-tool.js 32178 /** 32179 * WordPress dependencies 32180 */ 32181 32182 32183 /** 32184 * Internal dependencies 32185 */ 32186 32187 32188 /** 32189 * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps 32190 */ 32191 32192 /** 32193 * @callback AspectRatioToolPropsOnChange 32194 * @param {string} [value] New aspect ratio value. 32195 * @return {void} No return. 32196 */ 32197 32198 /** 32199 * @typedef {Object} AspectRatioToolProps 32200 * @property {string} [panelId] ID of the panel this tool is associated with. 32201 * @property {string} [value] Current aspect ratio value. 32202 * @property {AspectRatioToolPropsOnChange} [onChange] Callback to update the aspect ratio value. 32203 * @property {SelectControlProps[]} [options] Aspect ratio options. 32204 * @property {string} [defaultValue] Default aspect ratio value. 32205 * @property {boolean} [isShownByDefault] Whether the tool is shown by default. 32206 */ 32207 32208 function AspectRatioTool({ 32209 panelId, 32210 value, 32211 onChange = () => {}, 32212 options, 32213 defaultValue = 'auto', 32214 hasValue, 32215 isShownByDefault = true 32216 }) { 32217 // Match the CSS default so if the value is used directly in CSS it will look correct in the control. 32218 const displayValue = value !== null && value !== void 0 ? value : 'auto'; 32219 const [defaultRatios, themeRatios, showDefaultRatios] = use_settings_useSettings('dimensions.aspectRatios.default', 'dimensions.aspectRatios.theme', 'dimensions.defaultAspectRatios'); 32220 const themeOptions = themeRatios?.map(({ 32221 name, 32222 ratio 32223 }) => ({ 32224 label: name, 32225 value: ratio 32226 })); 32227 const defaultOptions = defaultRatios?.map(({ 32228 name, 32229 ratio 32230 }) => ({ 32231 label: name, 32232 value: ratio 32233 })); 32234 const aspectRatioOptions = [{ 32235 label: (0,external_wp_i18n_namespaceObject._x)('Original', 'Aspect ratio option for dimensions control'), 32236 value: 'auto' 32237 }, ...(showDefaultRatios ? defaultOptions : []), ...(themeOptions ? themeOptions : []), { 32238 label: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Aspect ratio option for dimensions control'), 32239 value: 'custom', 32240 disabled: true, 32241 hidden: true 32242 }]; 32243 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32244 hasValue: hasValue ? hasValue : () => displayValue !== defaultValue, 32245 label: (0,external_wp_i18n_namespaceObject.__)('Aspect ratio'), 32246 onDeselect: () => onChange(undefined), 32247 isShownByDefault: isShownByDefault, 32248 panelId: panelId, 32249 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SelectControl, { 32250 label: (0,external_wp_i18n_namespaceObject.__)('Aspect ratio'), 32251 value: displayValue, 32252 options: options !== null && options !== void 0 ? options : aspectRatioOptions, 32253 onChange: onChange, 32254 size: "__unstable-large", 32255 __nextHasNoMarginBottom: true 32256 }) 32257 }); 32258 } 32259 32260 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/dimensions-panel.js 32261 /** 32262 * External dependencies 32263 */ 32264 32265 32266 /** 32267 * WordPress dependencies 32268 */ 32269 32270 32271 32272 32273 32274 /** 32275 * Internal dependencies 32276 */ 32277 32278 32279 32280 32281 32282 32283 32284 32285 const AXIAL_SIDES = ['horizontal', 'vertical']; 32286 function useHasDimensionsPanel(settings) { 32287 const hasContentSize = useHasContentSize(settings); 32288 const hasWideSize = useHasWideSize(settings); 32289 const hasPadding = useHasPadding(settings); 32290 const hasMargin = useHasMargin(settings); 32291 const hasGap = useHasGap(settings); 32292 const hasMinHeight = useHasMinHeight(settings); 32293 const hasAspectRatio = useHasAspectRatio(settings); 32294 const hasChildLayout = useHasChildLayout(settings); 32295 return external_wp_element_namespaceObject.Platform.OS === 'web' && (hasContentSize || hasWideSize || hasPadding || hasMargin || hasGap || hasMinHeight || hasAspectRatio || hasChildLayout); 32296 } 32297 function useHasContentSize(settings) { 32298 return settings?.layout?.contentSize; 32299 } 32300 function useHasWideSize(settings) { 32301 return settings?.layout?.wideSize; 32302 } 32303 function useHasPadding(settings) { 32304 return settings?.spacing?.padding; 32305 } 32306 function useHasMargin(settings) { 32307 return settings?.spacing?.margin; 32308 } 32309 function useHasGap(settings) { 32310 return settings?.spacing?.blockGap; 32311 } 32312 function useHasMinHeight(settings) { 32313 return settings?.dimensions?.minHeight; 32314 } 32315 function useHasAspectRatio(settings) { 32316 return settings?.dimensions?.aspectRatio; 32317 } 32318 function useHasChildLayout(settings) { 32319 var _settings$parentLayou; 32320 const { 32321 type: parentLayoutType = 'default', 32322 default: { 32323 type: defaultParentLayoutType = 'default' 32324 } = {}, 32325 allowSizingOnChildren = false 32326 } = (_settings$parentLayou = settings?.parentLayout) !== null && _settings$parentLayou !== void 0 ? _settings$parentLayou : {}; 32327 const support = (defaultParentLayoutType === 'flex' || parentLayoutType === 'flex' || defaultParentLayoutType === 'grid' || parentLayoutType === 'grid') && allowSizingOnChildren; 32328 return !!settings?.layout && support; 32329 } 32330 function useHasSpacingPresets(settings) { 32331 const { 32332 defaultSpacingSizes, 32333 spacingSizes 32334 } = settings?.spacing || {}; 32335 return defaultSpacingSizes !== false && spacingSizes?.default?.length > 0 || spacingSizes?.theme?.length > 0 || spacingSizes?.custom?.length > 0; 32336 } 32337 function filterValuesBySides(values, sides) { 32338 // If no custom side configuration, all sides are opted into by default. 32339 // Without any values, we have nothing to filter either. 32340 if (!sides || !values) { 32341 return values; 32342 } 32343 32344 // Only include sides opted into within filtered values. 32345 const filteredValues = {}; 32346 sides.forEach(side => { 32347 if (side === 'vertical') { 32348 filteredValues.top = values.top; 32349 filteredValues.bottom = values.bottom; 32350 } 32351 if (side === 'horizontal') { 32352 filteredValues.left = values.left; 32353 filteredValues.right = values.right; 32354 } 32355 filteredValues[side] = values?.[side]; 32356 }); 32357 return filteredValues; 32358 } 32359 function splitStyleValue(value) { 32360 // Check for shorthand value (a string value). 32361 if (value && typeof value === 'string') { 32362 // Convert to value for individual sides for BoxControl. 32363 return { 32364 top: value, 32365 right: value, 32366 bottom: value, 32367 left: value 32368 }; 32369 } 32370 return value; 32371 } 32372 function splitGapValue(value, isAxialGap) { 32373 if (!value) { 32374 return value; 32375 } 32376 32377 // Check for shorthand value (a string value). 32378 if (typeof value === 'string') { 32379 /* 32380 * Map the string value to appropriate sides for the spacing control depending 32381 * on whether the current block has axial gap support or not. 32382 * 32383 * Note: The axial value pairs must match for the spacing control to display 32384 * the appropriate horizontal/vertical sliders. 32385 */ 32386 return isAxialGap ? { 32387 top: value, 32388 right: value, 32389 bottom: value, 32390 left: value 32391 } : { 32392 top: value 32393 }; 32394 } 32395 return { 32396 ...value, 32397 right: value?.left, 32398 bottom: value?.top 32399 }; 32400 } 32401 function DimensionsToolsPanel({ 32402 resetAllFilter, 32403 onChange, 32404 value, 32405 panelId, 32406 children 32407 }) { 32408 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 32409 const resetAll = () => { 32410 const updatedValue = resetAllFilter(value); 32411 onChange(updatedValue); 32412 }; 32413 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 32414 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions'), 32415 resetAll: resetAll, 32416 panelId: panelId, 32417 dropdownMenuProps: dropdownMenuProps, 32418 children: children 32419 }); 32420 } 32421 const dimensions_panel_DEFAULT_CONTROLS = { 32422 contentSize: true, 32423 wideSize: true, 32424 padding: true, 32425 margin: true, 32426 blockGap: true, 32427 minHeight: true, 32428 aspectRatio: true, 32429 childLayout: true 32430 }; 32431 function DimensionsPanel({ 32432 as: Wrapper = DimensionsToolsPanel, 32433 value, 32434 onChange, 32435 inheritedValue = value, 32436 settings, 32437 panelId, 32438 defaultControls = dimensions_panel_DEFAULT_CONTROLS, 32439 onVisualize = () => {}, 32440 // Special case because the layout controls are not part of the dimensions panel 32441 // in global styles but not in block inspector. 32442 includeLayoutControls = false 32443 }) { 32444 var _defaultControls$cont, _defaultControls$wide, _defaultControls$padd, _defaultControls$marg, _defaultControls$bloc, _defaultControls$chil, _defaultControls$minH, _defaultControls$aspe; 32445 const { 32446 dimensions, 32447 spacing 32448 } = settings; 32449 const decodeValue = rawValue => { 32450 if (rawValue && typeof rawValue === 'object') { 32451 return Object.keys(rawValue).reduce((acc, key) => { 32452 acc[key] = getValueFromVariable({ 32453 settings: { 32454 dimensions, 32455 spacing 32456 } 32457 }, '', rawValue[key]); 32458 return acc; 32459 }, {}); 32460 } 32461 return getValueFromVariable({ 32462 settings: { 32463 dimensions, 32464 spacing 32465 } 32466 }, '', rawValue); 32467 }; 32468 const showSpacingPresetsControl = useHasSpacingPresets(settings); 32469 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 32470 availableUnits: settings?.spacing?.units || ['%', 'px', 'em', 'rem', 'vw'] 32471 }); 32472 32473 //Minimum Margin Value 32474 const minimumMargin = -Infinity; 32475 const [minMarginValue, setMinMarginValue] = (0,external_wp_element_namespaceObject.useState)(minimumMargin); 32476 32477 // Content Width 32478 const showContentSizeControl = useHasContentSize(settings) && includeLayoutControls; 32479 const contentSizeValue = decodeValue(inheritedValue?.layout?.contentSize); 32480 const setContentSizeValue = newValue => { 32481 onChange(setImmutably(value, ['layout', 'contentSize'], newValue || undefined)); 32482 }; 32483 const hasUserSetContentSizeValue = () => !!value?.layout?.contentSize; 32484 const resetContentSizeValue = () => setContentSizeValue(undefined); 32485 32486 // Wide Width 32487 const showWideSizeControl = useHasWideSize(settings) && includeLayoutControls; 32488 const wideSizeValue = decodeValue(inheritedValue?.layout?.wideSize); 32489 const setWideSizeValue = newValue => { 32490 onChange(setImmutably(value, ['layout', 'wideSize'], newValue || undefined)); 32491 }; 32492 const hasUserSetWideSizeValue = () => !!value?.layout?.wideSize; 32493 const resetWideSizeValue = () => setWideSizeValue(undefined); 32494 32495 // Padding 32496 const showPaddingControl = useHasPadding(settings); 32497 const rawPadding = decodeValue(inheritedValue?.spacing?.padding); 32498 const paddingValues = splitStyleValue(rawPadding); 32499 const paddingSides = Array.isArray(settings?.spacing?.padding) ? settings?.spacing?.padding : settings?.spacing?.padding?.sides; 32500 const isAxialPadding = paddingSides && paddingSides.some(side => AXIAL_SIDES.includes(side)); 32501 const setPaddingValues = newPaddingValues => { 32502 const padding = filterValuesBySides(newPaddingValues, paddingSides); 32503 onChange(setImmutably(value, ['spacing', 'padding'], padding)); 32504 }; 32505 const hasPaddingValue = () => !!value?.spacing?.padding && Object.keys(value?.spacing?.padding).length; 32506 const resetPaddingValue = () => setPaddingValues(undefined); 32507 const onMouseOverPadding = () => onVisualize('padding'); 32508 32509 // Margin 32510 const showMarginControl = useHasMargin(settings); 32511 const rawMargin = decodeValue(inheritedValue?.spacing?.margin); 32512 const marginValues = splitStyleValue(rawMargin); 32513 const marginSides = Array.isArray(settings?.spacing?.margin) ? settings?.spacing?.margin : settings?.spacing?.margin?.sides; 32514 const isAxialMargin = marginSides && marginSides.some(side => AXIAL_SIDES.includes(side)); 32515 const setMarginValues = newMarginValues => { 32516 const margin = filterValuesBySides(newMarginValues, marginSides); 32517 onChange(setImmutably(value, ['spacing', 'margin'], margin)); 32518 }; 32519 const hasMarginValue = () => !!value?.spacing?.margin && Object.keys(value?.spacing?.margin).length; 32520 const resetMarginValue = () => setMarginValues(undefined); 32521 const onMouseOverMargin = () => onVisualize('margin'); 32522 32523 // Block Gap 32524 const showGapControl = useHasGap(settings); 32525 const gapSides = Array.isArray(settings?.spacing?.blockGap) ? settings?.spacing?.blockGap : settings?.spacing?.blockGap?.sides; 32526 const isAxialGap = gapSides && gapSides.some(side => AXIAL_SIDES.includes(side)); 32527 const gapValue = decodeValue(inheritedValue?.spacing?.blockGap); 32528 const gapValues = splitGapValue(gapValue, isAxialGap); 32529 const setGapValue = newGapValue => { 32530 onChange(setImmutably(value, ['spacing', 'blockGap'], newGapValue)); 32531 }; 32532 const setGapValues = nextBoxGapValue => { 32533 if (!nextBoxGapValue) { 32534 setGapValue(null); 32535 } 32536 // If axial gap is not enabled, treat the 'top' value as the shorthand gap value. 32537 if (!isAxialGap && nextBoxGapValue?.hasOwnProperty('top')) { 32538 setGapValue(nextBoxGapValue.top); 32539 } else { 32540 setGapValue({ 32541 top: nextBoxGapValue?.top, 32542 left: nextBoxGapValue?.left 32543 }); 32544 } 32545 }; 32546 const resetGapValue = () => setGapValue(undefined); 32547 const hasGapValue = () => !!value?.spacing?.blockGap; 32548 32549 // Min Height 32550 const showMinHeightControl = useHasMinHeight(settings); 32551 const minHeightValue = decodeValue(inheritedValue?.dimensions?.minHeight); 32552 const setMinHeightValue = newValue => { 32553 const tempValue = setImmutably(value, ['dimensions', 'minHeight'], newValue); 32554 // Apply min-height, while removing any applied aspect ratio. 32555 onChange(setImmutably(tempValue, ['dimensions', 'aspectRatio'], undefined)); 32556 }; 32557 const resetMinHeightValue = () => { 32558 setMinHeightValue(undefined); 32559 }; 32560 const hasMinHeightValue = () => !!value?.dimensions?.minHeight; 32561 32562 // Aspect Ratio 32563 const showAspectRatioControl = useHasAspectRatio(settings); 32564 const aspectRatioValue = decodeValue(inheritedValue?.dimensions?.aspectRatio); 32565 const setAspectRatioValue = newValue => { 32566 const tempValue = setImmutably(value, ['dimensions', 'aspectRatio'], newValue); 32567 // Apply aspect-ratio, while removing any applied min-height. 32568 onChange(setImmutably(tempValue, ['dimensions', 'minHeight'], undefined)); 32569 }; 32570 const hasAspectRatioValue = () => !!value?.dimensions?.aspectRatio; 32571 32572 // Child Layout 32573 const showChildLayoutControl = useHasChildLayout(settings); 32574 const childLayout = inheritedValue?.layout; 32575 const setChildLayout = newChildLayout => { 32576 onChange({ 32577 ...value, 32578 layout: { 32579 ...newChildLayout 32580 } 32581 }); 32582 }; 32583 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 32584 return { 32585 ...previousValue, 32586 layout: utils_cleanEmptyObject({ 32587 ...previousValue?.layout, 32588 contentSize: undefined, 32589 wideSize: undefined, 32590 selfStretch: undefined, 32591 flexSize: undefined, 32592 columnStart: undefined, 32593 rowStart: undefined, 32594 columnSpan: undefined, 32595 rowSpan: undefined 32596 }), 32597 spacing: { 32598 ...previousValue?.spacing, 32599 padding: undefined, 32600 margin: undefined, 32601 blockGap: undefined 32602 }, 32603 dimensions: { 32604 ...previousValue?.dimensions, 32605 minHeight: undefined, 32606 aspectRatio: undefined 32607 } 32608 }; 32609 }, []); 32610 const onMouseLeaveControls = () => onVisualize(false); 32611 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Wrapper, { 32612 resetAllFilter: resetAllFilter, 32613 value: value, 32614 onChange: onChange, 32615 panelId: panelId, 32616 children: [(showContentSizeControl || showWideSizeControl) && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 32617 className: "span-columns", 32618 children: (0,external_wp_i18n_namespaceObject.__)('Set the width of the main content area.') 32619 }), showContentSizeControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32620 label: (0,external_wp_i18n_namespaceObject.__)('Content width'), 32621 hasValue: hasUserSetContentSizeValue, 32622 onDeselect: resetContentSizeValue, 32623 isShownByDefault: (_defaultControls$cont = defaultControls.contentSize) !== null && _defaultControls$cont !== void 0 ? _defaultControls$cont : dimensions_panel_DEFAULT_CONTROLS.contentSize, 32624 panelId: panelId, 32625 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 32626 __next40pxDefaultSize: true, 32627 label: (0,external_wp_i18n_namespaceObject.__)('Content width'), 32628 labelPosition: "top", 32629 value: contentSizeValue || '', 32630 onChange: nextContentSize => { 32631 setContentSizeValue(nextContentSize); 32632 }, 32633 units: units, 32634 prefix: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlPrefixWrapper, { 32635 variant: "icon", 32636 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 32637 icon: align_none 32638 }) 32639 }) 32640 }) 32641 }), showWideSizeControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32642 label: (0,external_wp_i18n_namespaceObject.__)('Wide width'), 32643 hasValue: hasUserSetWideSizeValue, 32644 onDeselect: resetWideSizeValue, 32645 isShownByDefault: (_defaultControls$wide = defaultControls.wideSize) !== null && _defaultControls$wide !== void 0 ? _defaultControls$wide : dimensions_panel_DEFAULT_CONTROLS.wideSize, 32646 panelId: panelId, 32647 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 32648 __next40pxDefaultSize: true, 32649 label: (0,external_wp_i18n_namespaceObject.__)('Wide width'), 32650 labelPosition: "top", 32651 value: wideSizeValue || '', 32652 onChange: nextWideSize => { 32653 setWideSizeValue(nextWideSize); 32654 }, 32655 units: units, 32656 prefix: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlPrefixWrapper, { 32657 variant: "icon", 32658 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 32659 icon: stretch_wide 32660 }) 32661 }) 32662 }) 32663 }), showPaddingControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32664 hasValue: hasPaddingValue, 32665 label: (0,external_wp_i18n_namespaceObject.__)('Padding'), 32666 onDeselect: resetPaddingValue, 32667 isShownByDefault: (_defaultControls$padd = defaultControls.padding) !== null && _defaultControls$padd !== void 0 ? _defaultControls$padd : dimensions_panel_DEFAULT_CONTROLS.padding, 32668 className: dist_clsx({ 32669 'tools-panel-item-spacing': showSpacingPresetsControl 32670 }), 32671 panelId: panelId, 32672 children: [!showSpacingPresetsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BoxControl, { 32673 __next40pxDefaultSize: true, 32674 values: paddingValues, 32675 onChange: setPaddingValues, 32676 label: (0,external_wp_i18n_namespaceObject.__)('Padding'), 32677 sides: paddingSides, 32678 units: units, 32679 allowReset: false, 32680 splitOnAxis: isAxialPadding, 32681 inputProps: { 32682 onMouseOver: onMouseOverPadding, 32683 onMouseOut: onMouseLeaveControls 32684 } 32685 }), showSpacingPresetsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingSizesControl, { 32686 values: paddingValues, 32687 onChange: setPaddingValues, 32688 label: (0,external_wp_i18n_namespaceObject.__)('Padding'), 32689 sides: paddingSides, 32690 units: units, 32691 allowReset: false, 32692 onMouseOver: onMouseOverPadding, 32693 onMouseOut: onMouseLeaveControls 32694 })] 32695 }), showMarginControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32696 hasValue: hasMarginValue, 32697 label: (0,external_wp_i18n_namespaceObject.__)('Margin'), 32698 onDeselect: resetMarginValue, 32699 isShownByDefault: (_defaultControls$marg = defaultControls.margin) !== null && _defaultControls$marg !== void 0 ? _defaultControls$marg : dimensions_panel_DEFAULT_CONTROLS.margin, 32700 className: dist_clsx({ 32701 'tools-panel-item-spacing': showSpacingPresetsControl 32702 }), 32703 panelId: panelId, 32704 children: [!showSpacingPresetsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BoxControl, { 32705 __next40pxDefaultSize: true, 32706 values: marginValues, 32707 onChange: setMarginValues, 32708 inputProps: { 32709 min: minMarginValue, 32710 onDragStart: () => { 32711 // Reset to 0 in case the value was negative. 32712 setMinMarginValue(0); 32713 }, 32714 onDragEnd: () => { 32715 setMinMarginValue(minimumMargin); 32716 }, 32717 onMouseOver: onMouseOverMargin, 32718 onMouseOut: onMouseLeaveControls 32719 }, 32720 label: (0,external_wp_i18n_namespaceObject.__)('Margin'), 32721 sides: marginSides, 32722 units: units, 32723 allowReset: false, 32724 splitOnAxis: isAxialMargin 32725 }), showSpacingPresetsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingSizesControl, { 32726 values: marginValues, 32727 onChange: setMarginValues, 32728 minimumCustomValue: -Infinity, 32729 label: (0,external_wp_i18n_namespaceObject.__)('Margin'), 32730 sides: marginSides, 32731 units: units, 32732 allowReset: false, 32733 onMouseOver: onMouseOverMargin, 32734 onMouseOut: onMouseLeaveControls 32735 })] 32736 }), showGapControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32737 hasValue: hasGapValue, 32738 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 32739 onDeselect: resetGapValue, 32740 isShownByDefault: (_defaultControls$bloc = defaultControls.blockGap) !== null && _defaultControls$bloc !== void 0 ? _defaultControls$bloc : dimensions_panel_DEFAULT_CONTROLS.blockGap, 32741 className: dist_clsx({ 32742 'tools-panel-item-spacing': showSpacingPresetsControl, 32743 'single-column': 32744 // If UnitControl is used, should be single-column. 32745 !showSpacingPresetsControl && !isAxialGap 32746 }), 32747 panelId: panelId, 32748 children: [!showSpacingPresetsControl && (isAxialGap ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BoxControl, { 32749 __next40pxDefaultSize: true, 32750 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 32751 min: 0, 32752 onChange: setGapValues, 32753 units: units, 32754 sides: gapSides, 32755 values: gapValues, 32756 allowReset: false, 32757 splitOnAxis: isAxialGap 32758 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 32759 __next40pxDefaultSize: true, 32760 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 32761 min: 0, 32762 onChange: setGapValue, 32763 units: units, 32764 value: gapValue 32765 })), showSpacingPresetsControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingSizesControl, { 32766 label: (0,external_wp_i18n_namespaceObject.__)('Block spacing'), 32767 min: 0, 32768 onChange: setGapValues, 32769 showSideInLabel: false, 32770 sides: isAxialGap ? gapSides : ['top'] // Use 'top' as the shorthand property in non-axial configurations. 32771 , 32772 values: gapValues, 32773 allowReset: false 32774 })] 32775 }), showChildLayoutControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ChildLayoutControl, { 32776 value: childLayout, 32777 onChange: setChildLayout, 32778 parentLayout: settings?.parentLayout, 32779 panelId: panelId, 32780 isShownByDefault: (_defaultControls$chil = defaultControls.childLayout) !== null && _defaultControls$chil !== void 0 ? _defaultControls$chil : dimensions_panel_DEFAULT_CONTROLS.childLayout 32781 }), showMinHeightControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 32782 hasValue: hasMinHeightValue, 32783 label: (0,external_wp_i18n_namespaceObject.__)('Minimum height'), 32784 onDeselect: resetMinHeightValue, 32785 isShownByDefault: (_defaultControls$minH = defaultControls.minHeight) !== null && _defaultControls$minH !== void 0 ? _defaultControls$minH : dimensions_panel_DEFAULT_CONTROLS.minHeight, 32786 panelId: panelId, 32787 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(HeightControl, { 32788 label: (0,external_wp_i18n_namespaceObject.__)('Minimum height'), 32789 value: minHeightValue, 32790 onChange: setMinHeightValue 32791 }) 32792 }), showAspectRatioControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioTool, { 32793 hasValue: hasAspectRatioValue, 32794 value: aspectRatioValue, 32795 onChange: setAspectRatioValue, 32796 panelId: panelId, 32797 isShownByDefault: (_defaultControls$aspe = defaultControls.aspectRatio) !== null && _defaultControls$aspe !== void 0 ? _defaultControls$aspe : dimensions_panel_DEFAULT_CONTROLS.aspectRatio 32798 })] 32799 }); 32800 } 32801 32802 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-popover/use-popover-scroll.js 32803 /** 32804 * WordPress dependencies 32805 */ 32806 32807 32808 const scrollContainerCache = new WeakMap(); 32809 32810 /** 32811 * Allow scrolling "through" popovers over the canvas. This is only called for 32812 * as long as the pointer is over a popover. Do not use React events because it 32813 * will bubble through portals. 32814 * 32815 * @param {Object} contentRef 32816 */ 32817 function usePopoverScroll(contentRef) { 32818 const effect = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 32819 function onWheel(event) { 32820 const { 32821 deltaX, 32822 deltaY 32823 } = event; 32824 const contentEl = contentRef.current; 32825 let scrollContainer = scrollContainerCache.get(contentEl); 32826 if (!scrollContainer) { 32827 scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(contentEl); 32828 scrollContainerCache.set(contentEl, scrollContainer); 32829 } 32830 scrollContainer.scrollBy(deltaX, deltaY); 32831 } 32832 // Tell the browser that we do not call event.preventDefault 32833 // See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners 32834 const options = { 32835 passive: true 32836 }; 32837 node.addEventListener('wheel', onWheel, options); 32838 return () => { 32839 node.removeEventListener('wheel', onWheel, options); 32840 }; 32841 }, [contentRef]); 32842 return contentRef ? effect : null; 32843 } 32844 /* harmony default export */ const use_popover_scroll = (usePopoverScroll); 32845 32846 ;// ./node_modules/@wordpress/block-editor/build-module/utils/dom.js 32847 const BLOCK_SELECTOR = '.block-editor-block-list__block'; 32848 const APPENDER_SELECTOR = '.block-list-appender'; 32849 const BLOCK_APPENDER_CLASS = '.block-editor-button-block-appender'; 32850 32851 /** 32852 * Returns true if two elements are contained within the same block. 32853 * 32854 * @param {Element} a First element. 32855 * @param {Element} b Second element. 32856 * 32857 * @return {boolean} Whether elements are in the same block. 32858 */ 32859 function isInSameBlock(a, b) { 32860 return a.closest(BLOCK_SELECTOR) === b.closest(BLOCK_SELECTOR); 32861 } 32862 32863 /** 32864 * Returns true if an element is considered part of the block and not its inner 32865 * blocks or appender. 32866 * 32867 * @param {Element} blockElement Block container element. 32868 * @param {Element} element Element. 32869 * 32870 * @return {boolean} Whether an element is considered part of the block and not 32871 * its inner blocks or appender. 32872 */ 32873 function isInsideRootBlock(blockElement, element) { 32874 const parentBlock = element.closest([BLOCK_SELECTOR, APPENDER_SELECTOR, BLOCK_APPENDER_CLASS].join(',')); 32875 return parentBlock === blockElement; 32876 } 32877 32878 /** 32879 * Finds the block client ID given any DOM node inside the block. 32880 * 32881 * @param {Node?} node DOM node. 32882 * 32883 * @return {string|undefined} Client ID or undefined if the node is not part of 32884 * a block. 32885 */ 32886 function getBlockClientId(node) { 32887 while (node && node.nodeType !== node.ELEMENT_NODE) { 32888 node = node.parentNode; 32889 } 32890 if (!node) { 32891 return; 32892 } 32893 const elementNode = /** @type {Element} */node; 32894 const blockNode = elementNode.closest(BLOCK_SELECTOR); 32895 if (!blockNode) { 32896 return; 32897 } 32898 return blockNode.id.slice('block-'.length); 32899 } 32900 32901 /** 32902 * Calculates the union of two rectangles. 32903 * 32904 * @param {DOMRect} rect1 First rectangle. 32905 * @param {DOMRect} rect2 Second rectangle. 32906 * @return {DOMRect} Union of the two rectangles. 32907 */ 32908 function rectUnion(rect1, rect2) { 32909 const left = Math.min(rect1.left, rect2.left); 32910 const right = Math.max(rect1.right, rect2.right); 32911 const bottom = Math.max(rect1.bottom, rect2.bottom); 32912 const top = Math.min(rect1.top, rect2.top); 32913 return new window.DOMRectReadOnly(left, top, right - left, bottom - top); 32914 } 32915 32916 /** 32917 * Returns whether an element is visible. 32918 * 32919 * @param {Element} element Element. 32920 * @return {boolean} Whether the element is visible. 32921 */ 32922 function isElementVisible(element) { 32923 const viewport = element.ownerDocument.defaultView; 32924 if (!viewport) { 32925 return false; 32926 } 32927 32928 // Check for <VisuallyHidden> component. 32929 if (element.classList.contains('components-visually-hidden')) { 32930 return false; 32931 } 32932 const bounds = element.getBoundingClientRect(); 32933 if (bounds.width === 0 || bounds.height === 0) { 32934 return false; 32935 } 32936 32937 // Older browsers, e.g. Safari < 17.4 may not support the `checkVisibility` method. 32938 if (element.checkVisibility) { 32939 return element.checkVisibility?.({ 32940 opacityProperty: true, 32941 contentVisibilityAuto: true, 32942 visibilityProperty: true 32943 }); 32944 } 32945 const style = viewport.getComputedStyle(element); 32946 if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') { 32947 return false; 32948 } 32949 return true; 32950 } 32951 32952 /** 32953 * Checks if the element is scrollable. 32954 * 32955 * @param {Element} element Element. 32956 * @return {boolean} True if the element is scrollable. 32957 */ 32958 function isScrollable(element) { 32959 const style = window.getComputedStyle(element); 32960 return style.overflowX === 'auto' || style.overflowX === 'scroll' || style.overflowY === 'auto' || style.overflowY === 'scroll'; 32961 } 32962 const WITH_OVERFLOW_ELEMENT_BLOCKS = ['core/navigation']; 32963 /** 32964 * Returns the bounding rectangle of an element, with special handling for blocks 32965 * that have visible overflowing children (defined in WITH_OVERFLOW_ELEMENT_BLOCKS). 32966 * 32967 * For blocks like Navigation that can have overflowing elements (e.g. submenus), 32968 * this function calculates the combined bounds of both the parent and its visible 32969 * children. The returned rect may extend beyond the viewport. 32970 * The returned rect represents the full extent of the element and its visible 32971 * children, which may extend beyond the viewport. 32972 * 32973 * @param {Element} element Element. 32974 * @return {DOMRect} Bounding client rect of the element and its visible children. 32975 */ 32976 function getElementBounds(element) { 32977 const viewport = element.ownerDocument.defaultView; 32978 if (!viewport) { 32979 return new window.DOMRectReadOnly(); 32980 } 32981 let bounds = element.getBoundingClientRect(); 32982 const dataType = element.getAttribute('data-type'); 32983 32984 /* 32985 * For blocks with overflowing elements (like Navigation), include the bounds 32986 * of visible children that extend beyond the parent container. 32987 */ 32988 if (dataType && WITH_OVERFLOW_ELEMENT_BLOCKS.includes(dataType)) { 32989 const stack = [element]; 32990 let currentElement; 32991 while (currentElement = stack.pop()) { 32992 // Children won’t affect bounds unless the element is not scrollable. 32993 if (!isScrollable(currentElement)) { 32994 for (const child of currentElement.children) { 32995 if (isElementVisible(child)) { 32996 const childBounds = child.getBoundingClientRect(); 32997 bounds = rectUnion(bounds, childBounds); 32998 stack.push(child); 32999 } 33000 } 33001 } 33002 } 33003 } 33004 33005 /* 33006 * Take into account the outer horizontal limits of the container in which 33007 * an element is supposed to be "visible". For example, if an element is 33008 * positioned -10px to the left of the window x value (0), this function 33009 * discounts the negative overhang because it's not visible and therefore 33010 * not to be counted in the visibility calculations. Top and bottom values 33011 * are not accounted for to accommodate vertical scroll. 33012 */ 33013 const left = Math.max(bounds.left, 0); 33014 const right = Math.min(bounds.right, viewport.innerWidth); 33015 bounds = new window.DOMRectReadOnly(left, bounds.top, right - left, bounds.height); 33016 return bounds; 33017 } 33018 33019 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-popover/index.js 33020 /** 33021 * External dependencies 33022 */ 33023 33024 33025 /** 33026 * WordPress dependencies 33027 */ 33028 33029 33030 33031 33032 /** 33033 * Internal dependencies 33034 */ 33035 33036 33037 33038 33039 const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER; 33040 function BlockPopover({ 33041 clientId, 33042 bottomClientId, 33043 children, 33044 __unstablePopoverSlot, 33045 __unstableContentRef, 33046 shift = true, 33047 ...props 33048 }, ref) { 33049 const selectedElement = useBlockElement(clientId); 33050 const lastSelectedElement = useBlockElement(bottomClientId !== null && bottomClientId !== void 0 ? bottomClientId : clientId); 33051 const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, use_popover_scroll(__unstableContentRef)]); 33052 const [popoverDimensionsRecomputeCounter, forceRecomputePopoverDimensions] = (0,external_wp_element_namespaceObject.useReducer)( 33053 // Module is there to make sure that the counter doesn't overflow. 33054 s => (s + 1) % MAX_POPOVER_RECOMPUTE_COUNTER, 0); 33055 33056 // When blocks are moved up/down, they are animated to their new position by 33057 // updating the `transform` property manually (i.e. without using CSS 33058 // transitions or animations). The animation, which can also scroll the block 33059 // editor, can sometimes cause the position of the Popover to get out of sync. 33060 // A MutationObserver is therefore used to make sure that changes to the 33061 // selectedElement's attribute (i.e. `transform`) can be tracked and used to 33062 // trigger the Popover to rerender. 33063 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 33064 if (!selectedElement) { 33065 return; 33066 } 33067 const observer = new window.MutationObserver(forceRecomputePopoverDimensions); 33068 observer.observe(selectedElement, { 33069 attributes: true 33070 }); 33071 return () => { 33072 observer.disconnect(); 33073 }; 33074 }, [selectedElement]); 33075 const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 33076 if ( 33077 // popoverDimensionsRecomputeCounter is by definition always equal or greater 33078 // than 0. This check is only there to satisfy the correctness of the 33079 // exhaustive-deps rule for the `useMemo` hook. 33080 popoverDimensionsRecomputeCounter < 0 || !selectedElement || bottomClientId && !lastSelectedElement) { 33081 return undefined; 33082 } 33083 return { 33084 getBoundingClientRect() { 33085 return lastSelectedElement ? rectUnion(getElementBounds(selectedElement), getElementBounds(lastSelectedElement)) : getElementBounds(selectedElement); 33086 }, 33087 contextElement: selectedElement 33088 }; 33089 }, [popoverDimensionsRecomputeCounter, selectedElement, bottomClientId, lastSelectedElement]); 33090 if (!selectedElement || bottomClientId && !lastSelectedElement) { 33091 return null; 33092 } 33093 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 33094 ref: mergedRefs, 33095 animate: false, 33096 focusOnMount: false, 33097 anchor: popoverAnchor 33098 // Render in the old slot if needed for backward compatibility, 33099 // otherwise render in place (not in the default popover slot). 33100 , 33101 __unstableSlotName: __unstablePopoverSlot, 33102 inline: !__unstablePopoverSlot, 33103 placement: "top-start", 33104 resize: false, 33105 flip: false, 33106 shift: shift, 33107 ...props, 33108 className: dist_clsx('block-editor-block-popover', props.className), 33109 variant: "unstyled", 33110 children: children 33111 }); 33112 } 33113 const PrivateBlockPopover = (0,external_wp_element_namespaceObject.forwardRef)(BlockPopover); 33114 const PublicBlockPopover = ({ 33115 clientId, 33116 bottomClientId, 33117 children, 33118 ...props 33119 }, ref) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockPopover, { 33120 ...props, 33121 bottomClientId: bottomClientId, 33122 clientId: clientId, 33123 __unstableContentRef: undefined, 33124 __unstablePopoverSlot: undefined, 33125 ref: ref, 33126 children: children 33127 }); 33128 33129 /** 33130 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-popover/README.md 33131 */ 33132 /* harmony default export */ const block_popover = ((0,external_wp_element_namespaceObject.forwardRef)(PublicBlockPopover)); 33133 33134 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-popover/cover.js 33135 /** 33136 * WordPress dependencies 33137 */ 33138 33139 33140 /** 33141 * Internal dependencies 33142 */ 33143 33144 33145 33146 function BlockPopoverCover({ 33147 clientId, 33148 bottomClientId, 33149 children, 33150 shift = false, 33151 additionalStyles, 33152 ...props 33153 }, ref) { 33154 var _bottomClientId; 33155 (_bottomClientId = bottomClientId) !== null && _bottomClientId !== void 0 ? _bottomClientId : bottomClientId = clientId; 33156 const selectedElement = useBlockElement(clientId); 33157 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockPopover, { 33158 ref: ref, 33159 clientId: clientId, 33160 bottomClientId: bottomClientId, 33161 shift: shift, 33162 ...props, 33163 children: selectedElement && clientId === bottomClientId ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CoverContainer, { 33164 selectedElement: selectedElement, 33165 additionalStyles: additionalStyles, 33166 children: children 33167 }) : children 33168 }); 33169 } 33170 function CoverContainer({ 33171 selectedElement, 33172 additionalStyles = {}, 33173 children 33174 }) { 33175 const [width, setWidth] = (0,external_wp_element_namespaceObject.useState)(selectedElement.offsetWidth); 33176 const [height, setHeight] = (0,external_wp_element_namespaceObject.useState)(selectedElement.offsetHeight); 33177 (0,external_wp_element_namespaceObject.useEffect)(() => { 33178 const observer = new window.ResizeObserver(() => { 33179 setWidth(selectedElement.offsetWidth); 33180 setHeight(selectedElement.offsetHeight); 33181 }); 33182 observer.observe(selectedElement, { 33183 box: 'border-box' 33184 }); 33185 return () => observer.disconnect(); 33186 }, [selectedElement]); 33187 const style = (0,external_wp_element_namespaceObject.useMemo)(() => { 33188 return { 33189 position: 'absolute', 33190 width, 33191 height, 33192 ...additionalStyles 33193 }; 33194 }, [width, height, additionalStyles]); 33195 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 33196 style: style, 33197 children: children 33198 }); 33199 } 33200 /* harmony default export */ const cover = ((0,external_wp_element_namespaceObject.forwardRef)(BlockPopoverCover)); 33201 33202 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/spacing-visualizer.js 33203 /** 33204 * WordPress dependencies 33205 */ 33206 33207 33208 33209 /** 33210 * Internal dependencies 33211 */ 33212 33213 33214 33215 function SpacingVisualizer({ 33216 clientId, 33217 value, 33218 computeStyle, 33219 forceShow 33220 }) { 33221 const blockElement = useBlockElement(clientId); 33222 const [style, updateStyle] = (0,external_wp_element_namespaceObject.useReducer)(() => computeStyle(blockElement)); 33223 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 33224 if (!blockElement) { 33225 return; 33226 } 33227 // It's not sufficient to read the computed spacing value when value.spacing changes as 33228 // useEffect may run before the browser recomputes CSS. We therefore combine 33229 // useLayoutEffect and two rAF calls to ensure that we read the spacing after the current 33230 // paint but before the next paint. 33231 // See https://github.com/WordPress/gutenberg/pull/59227. 33232 window.requestAnimationFrame(() => window.requestAnimationFrame(updateStyle)); 33233 }, [blockElement, value]); 33234 const previousValueRef = (0,external_wp_element_namespaceObject.useRef)(value); 33235 const [isActive, setIsActive] = (0,external_wp_element_namespaceObject.useState)(false); 33236 (0,external_wp_element_namespaceObject.useEffect)(() => { 33237 if (external_wp_isShallowEqual_default()(value, previousValueRef.current) || forceShow) { 33238 return; 33239 } 33240 setIsActive(true); 33241 previousValueRef.current = value; 33242 const timeout = setTimeout(() => { 33243 setIsActive(false); 33244 }, 400); 33245 return () => { 33246 setIsActive(false); 33247 clearTimeout(timeout); 33248 }; 33249 }, [value, forceShow]); 33250 if (!isActive && !forceShow) { 33251 return null; 33252 } 33253 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(cover, { 33254 clientId: clientId, 33255 __unstablePopoverSlot: "block-toolbar", 33256 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 33257 className: "block-editor__spacing-visualizer", 33258 style: style 33259 }) 33260 }); 33261 } 33262 function getComputedCSS(element, property) { 33263 return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue(property); 33264 } 33265 function MarginVisualizer({ 33266 clientId, 33267 value, 33268 forceShow 33269 }) { 33270 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingVisualizer, { 33271 clientId: clientId, 33272 value: value?.spacing?.margin, 33273 computeStyle: blockElement => { 33274 const top = getComputedCSS(blockElement, 'margin-top'); 33275 const right = getComputedCSS(blockElement, 'margin-right'); 33276 const bottom = getComputedCSS(blockElement, 'margin-bottom'); 33277 const left = getComputedCSS(blockElement, 'margin-left'); 33278 return { 33279 borderTopWidth: top, 33280 borderRightWidth: right, 33281 borderBottomWidth: bottom, 33282 borderLeftWidth: left, 33283 top: top ? `-$top}` : 0, 33284 right: right ? `-$right}` : 0, 33285 bottom: bottom ? `-$bottom}` : 0, 33286 left: left ? `-$left}` : 0 33287 }; 33288 }, 33289 forceShow: forceShow 33290 }); 33291 } 33292 function PaddingVisualizer({ 33293 clientId, 33294 value, 33295 forceShow 33296 }) { 33297 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SpacingVisualizer, { 33298 clientId: clientId, 33299 value: value?.spacing?.padding, 33300 computeStyle: blockElement => ({ 33301 borderTopWidth: getComputedCSS(blockElement, 'padding-top'), 33302 borderRightWidth: getComputedCSS(blockElement, 'padding-right'), 33303 borderBottomWidth: getComputedCSS(blockElement, 'padding-bottom'), 33304 borderLeftWidth: getComputedCSS(blockElement, 'padding-left') 33305 }), 33306 forceShow: forceShow 33307 }); 33308 } 33309 33310 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/dimensions.js 33311 /** 33312 * External dependencies 33313 */ 33314 33315 33316 /** 33317 * WordPress dependencies 33318 */ 33319 33320 33321 33322 33323 33324 /** 33325 * Internal dependencies 33326 */ 33327 33328 33329 33330 33331 33332 33333 33334 const DIMENSIONS_SUPPORT_KEY = 'dimensions'; 33335 const SPACING_SUPPORT_KEY = 'spacing'; 33336 const dimensions_ALL_SIDES = (/* unused pure expression or super */ null && (['top', 'right', 'bottom', 'left'])); 33337 const dimensions_AXIAL_SIDES = (/* unused pure expression or super */ null && (['vertical', 'horizontal'])); 33338 function useVisualizer() { 33339 const [property, setProperty] = (0,external_wp_element_namespaceObject.useState)(false); 33340 const { 33341 hideBlockInterface, 33342 showBlockInterface 33343 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 33344 (0,external_wp_element_namespaceObject.useEffect)(() => { 33345 if (!property) { 33346 showBlockInterface(); 33347 } else { 33348 hideBlockInterface(); 33349 } 33350 }, [property, showBlockInterface, hideBlockInterface]); 33351 return [property, setProperty]; 33352 } 33353 function DimensionsInspectorControl({ 33354 children, 33355 resetAllFilter 33356 }) { 33357 const attributesResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(attributes => { 33358 const existingStyle = attributes.style; 33359 const updatedStyle = resetAllFilter(existingStyle); 33360 return { 33361 ...attributes, 33362 style: updatedStyle 33363 }; 33364 }, [resetAllFilter]); 33365 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 33366 group: "dimensions", 33367 resetAllFilter: attributesResetAllFilter, 33368 children: children 33369 }); 33370 } 33371 function dimensions_DimensionsPanel({ 33372 clientId, 33373 name, 33374 setAttributes, 33375 settings 33376 }) { 33377 const isEnabled = useHasDimensionsPanel(settings); 33378 const value = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlockAttributes(clientId)?.style, [clientId]); 33379 const [visualizedProperty, setVisualizedProperty] = useVisualizer(); 33380 const onChange = newStyle => { 33381 setAttributes({ 33382 style: utils_cleanEmptyObject(newStyle) 33383 }); 33384 }; 33385 if (!isEnabled) { 33386 return null; 33387 } 33388 const defaultDimensionsControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [DIMENSIONS_SUPPORT_KEY, '__experimentalDefaultControls']); 33389 const defaultSpacingControls = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, [SPACING_SUPPORT_KEY, '__experimentalDefaultControls']); 33390 const defaultControls = { 33391 ...defaultDimensionsControls, 33392 ...defaultSpacingControls 33393 }; 33394 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 33395 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DimensionsPanel, { 33396 as: DimensionsInspectorControl, 33397 panelId: clientId, 33398 settings: settings, 33399 value: value, 33400 onChange: onChange, 33401 defaultControls: defaultControls, 33402 onVisualize: setVisualizedProperty 33403 }), !!settings?.spacing?.padding && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PaddingVisualizer, { 33404 forceShow: visualizedProperty === 'padding', 33405 clientId: clientId, 33406 value: value 33407 }), !!settings?.spacing?.margin && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MarginVisualizer, { 33408 forceShow: visualizedProperty === 'margin', 33409 clientId: clientId, 33410 value: value 33411 })] 33412 }); 33413 } 33414 33415 /** 33416 * Determine whether there is block support for dimensions. 33417 * 33418 * @param {string} blockName Block name. 33419 * @param {string} feature Background image feature to check for. 33420 * 33421 * @return {boolean} Whether there is support. 33422 */ 33423 function hasDimensionsSupport(blockName, feature = 'any') { 33424 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 33425 return false; 33426 } 33427 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, DIMENSIONS_SUPPORT_KEY); 33428 if (support === true) { 33429 return true; 33430 } 33431 if (feature === 'any') { 33432 return !!(support?.aspectRatio || !!support?.minHeight); 33433 } 33434 return !!support?.[feature]; 33435 } 33436 /* harmony default export */ const dimensions = ({ 33437 useBlockProps: dimensions_useBlockProps, 33438 attributeKeys: ['minHeight', 'style'], 33439 hasSupport(name) { 33440 return hasDimensionsSupport(name, 'aspectRatio'); 33441 } 33442 }); 33443 function dimensions_useBlockProps({ 33444 name, 33445 minHeight, 33446 style 33447 }) { 33448 if (!hasDimensionsSupport(name, 'aspectRatio') || shouldSkipSerialization(name, DIMENSIONS_SUPPORT_KEY, 'aspectRatio')) { 33449 return {}; 33450 } 33451 const className = dist_clsx({ 33452 'has-aspect-ratio': !!style?.dimensions?.aspectRatio 33453 }); 33454 33455 // Allow dimensions-based inline style overrides to override any global styles rules that 33456 // might be set for the block, and therefore affect the display of the aspect ratio. 33457 const inlineStyleOverrides = {}; 33458 33459 // Apply rules to unset incompatible styles. 33460 // Note that a set `aspectRatio` will win out if both an aspect ratio and a minHeight are set. 33461 // This is because the aspect ratio is a newer block support, so (in theory) any aspect ratio 33462 // that is set should be intentional and should override any existing minHeight. The Cover block 33463 // and dimensions controls have logic that will manually clear the aspect ratio if a minHeight 33464 // is set. 33465 if (style?.dimensions?.aspectRatio) { 33466 // To ensure the aspect ratio does not get overridden by `minHeight` unset any existing rule. 33467 inlineStyleOverrides.minHeight = 'unset'; 33468 } else if (minHeight || style?.dimensions?.minHeight) { 33469 // To ensure the minHeight does not get overridden by `aspectRatio` unset any existing rule. 33470 inlineStyleOverrides.aspectRatio = 'unset'; 33471 } 33472 return { 33473 className, 33474 style: inlineStyleOverrides 33475 }; 33476 } 33477 33478 /** 33479 * @deprecated 33480 */ 33481 function useCustomSides() { 33482 external_wp_deprecated_default()('wp.blockEditor.__experimentalUseCustomSides', { 33483 since: '6.3', 33484 version: '6.4' 33485 }); 33486 } 33487 33488 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/style.js 33489 /** 33490 * WordPress dependencies 33491 */ 33492 33493 33494 33495 33496 33497 33498 /** 33499 * Internal dependencies 33500 */ 33501 33502 33503 33504 33505 33506 33507 33508 33509 33510 const styleSupportKeys = [...TYPOGRAPHY_SUPPORT_KEYS, BORDER_SUPPORT_KEY, COLOR_SUPPORT_KEY, DIMENSIONS_SUPPORT_KEY, BACKGROUND_SUPPORT_KEY, SPACING_SUPPORT_KEY, SHADOW_SUPPORT_KEY]; 33511 const hasStyleSupport = nameOrType => styleSupportKeys.some(key => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, key)); 33512 33513 /** 33514 * Returns the inline styles to add depending on the style object 33515 * 33516 * @param {Object} styles Styles configuration. 33517 * 33518 * @return {Object} Flattened CSS variables declaration. 33519 */ 33520 function getInlineStyles(styles = {}) { 33521 const output = {}; 33522 // The goal is to move everything to server side generated engine styles 33523 // This is temporary as we absorb more and more styles into the engine. 33524 (0,external_wp_styleEngine_namespaceObject.getCSSRules)(styles).forEach(rule => { 33525 output[rule.key] = rule.value; 33526 }); 33527 return output; 33528 } 33529 33530 /** 33531 * Filters registered block settings, extending attributes to include `style` attribute. 33532 * 33533 * @param {Object} settings Original block settings. 33534 * 33535 * @return {Object} Filtered block settings. 33536 */ 33537 function style_addAttribute(settings) { 33538 if (!hasStyleSupport(settings)) { 33539 return settings; 33540 } 33541 33542 // Allow blocks to specify their own attribute definition with default values if needed. 33543 if (!settings.attributes.style) { 33544 Object.assign(settings.attributes, { 33545 style: { 33546 type: 'object' 33547 } 33548 }); 33549 } 33550 return settings; 33551 } 33552 33553 /** 33554 * A dictionary of paths to flag skipping block support serialization as the key, 33555 * with values providing the style paths to be omitted from serialization. 33556 * 33557 * @constant 33558 * @type {Record<string, string[]>} 33559 */ 33560 const skipSerializationPathsEdit = { 33561 [`$BORDER_SUPPORT_KEY}.__experimentalSkipSerialization`]: ['border'], 33562 [`$COLOR_SUPPORT_KEY}.__experimentalSkipSerialization`]: [COLOR_SUPPORT_KEY], 33563 [`$TYPOGRAPHY_SUPPORT_KEY}.__experimentalSkipSerialization`]: [TYPOGRAPHY_SUPPORT_KEY], 33564 [`$DIMENSIONS_SUPPORT_KEY}.__experimentalSkipSerialization`]: [DIMENSIONS_SUPPORT_KEY], 33565 [`$SPACING_SUPPORT_KEY}.__experimentalSkipSerialization`]: [SPACING_SUPPORT_KEY], 33566 [`$SHADOW_SUPPORT_KEY}.__experimentalSkipSerialization`]: [SHADOW_SUPPORT_KEY] 33567 }; 33568 33569 /** 33570 * A dictionary of paths to flag skipping block support serialization as the key, 33571 * with values providing the style paths to be omitted from serialization. 33572 * 33573 * Extends the Edit skip paths to enable skipping additional paths in just 33574 * the Save component. This allows a block support to be serialized within the 33575 * editor, while using an alternate approach, such as server-side rendering, when 33576 * the support is saved. 33577 * 33578 * @constant 33579 * @type {Record<string, string[]>} 33580 */ 33581 const skipSerializationPathsSave = { 33582 ...skipSerializationPathsEdit, 33583 [`$DIMENSIONS_SUPPORT_KEY}.aspectRatio`]: [`$DIMENSIONS_SUPPORT_KEY}.aspectRatio`], 33584 // Skip serialization of aspect ratio in save mode. 33585 [`$BACKGROUND_SUPPORT_KEY}`]: [BACKGROUND_SUPPORT_KEY] // Skip serialization of background support in save mode. 33586 }; 33587 const skipSerializationPathsSaveChecks = { 33588 [`$DIMENSIONS_SUPPORT_KEY}.aspectRatio`]: true, 33589 [`$BACKGROUND_SUPPORT_KEY}`]: true 33590 }; 33591 33592 /** 33593 * A dictionary used to normalize feature names between support flags, style 33594 * object properties and __experimentSkipSerialization configuration arrays. 33595 * 33596 * This allows not having to provide a migration for a support flag and possible 33597 * backwards compatibility bridges, while still achieving consistency between 33598 * the support flag and the skip serialization array. 33599 * 33600 * @constant 33601 * @type {Record<string, string>} 33602 */ 33603 const renamedFeatures = { 33604 gradients: 'gradient' 33605 }; 33606 33607 /** 33608 * A utility function used to remove one or more paths from a style object. 33609 * Works in a way similar to Lodash's `omit()`. See unit tests and examples below. 33610 * 33611 * It supports a single string path: 33612 * 33613 * ``` 33614 * omitStyle( { color: 'red' }, 'color' ); // {} 33615 * ``` 33616 * 33617 * or an array of paths: 33618 * 33619 * ``` 33620 * omitStyle( { color: 'red', background: '#fff' }, [ 'color', 'background' ] ); // {} 33621 * ``` 33622 * 33623 * It also allows you to specify paths at multiple levels in a string. 33624 * 33625 * ``` 33626 * omitStyle( { typography: { textDecoration: 'underline' } }, 'typography.textDecoration' ); // {} 33627 * ``` 33628 * 33629 * You can remove multiple paths at the same time: 33630 * 33631 * ``` 33632 * omitStyle( 33633 * { 33634 * typography: { 33635 * textDecoration: 'underline', 33636 * textTransform: 'uppercase', 33637 * } 33638 * }, 33639 * [ 33640 * 'typography.textDecoration', 33641 * 'typography.textTransform', 33642 * ] 33643 * ); 33644 * // {} 33645 * ``` 33646 * 33647 * You can also specify nested paths as arrays: 33648 * 33649 * ``` 33650 * omitStyle( 33651 * { 33652 * typography: { 33653 * textDecoration: 'underline', 33654 * textTransform: 'uppercase', 33655 * } 33656 * }, 33657 * [ 33658 * [ 'typography', 'textDecoration' ], 33659 * [ 'typography', 'textTransform' ], 33660 * ] 33661 * ); 33662 * // {} 33663 * ``` 33664 * 33665 * With regards to nesting of styles, infinite depth is supported: 33666 * 33667 * ``` 33668 * omitStyle( 33669 * { 33670 * border: { 33671 * radius: { 33672 * topLeft: '10px', 33673 * topRight: '0.5rem', 33674 * } 33675 * } 33676 * }, 33677 * [ 33678 * [ 'border', 'radius', 'topRight' ], 33679 * ] 33680 * ); 33681 * // { border: { radius: { topLeft: '10px' } } } 33682 * ``` 33683 * 33684 * The third argument, `preserveReference`, defines how to treat the input style object. 33685 * It is mostly necessary to properly handle mutation when recursively handling the style object. 33686 * Defaulting to `false`, this will always create a new object, avoiding to mutate `style`. 33687 * However, when recursing, we change that value to `true` in order to work with a single copy 33688 * of the original style object. 33689 * 33690 * @see https://lodash.com/docs/4.17.15#omit 33691 * 33692 * @param {Object} style Styles object. 33693 * @param {Array|string} paths Paths to remove. 33694 * @param {boolean} preserveReference True to mutate the `style` object, false otherwise. 33695 * @return {Object} Styles object with the specified paths removed. 33696 */ 33697 function omitStyle(style, paths, preserveReference = false) { 33698 if (!style) { 33699 return style; 33700 } 33701 let newStyle = style; 33702 if (!preserveReference) { 33703 newStyle = JSON.parse(JSON.stringify(style)); 33704 } 33705 if (!Array.isArray(paths)) { 33706 paths = [paths]; 33707 } 33708 paths.forEach(path => { 33709 if (!Array.isArray(path)) { 33710 path = path.split('.'); 33711 } 33712 if (path.length > 1) { 33713 const [firstSubpath, ...restPath] = path; 33714 omitStyle(newStyle[firstSubpath], [restPath], true); 33715 } else if (path.length === 1) { 33716 delete newStyle[path[0]]; 33717 } 33718 }); 33719 return newStyle; 33720 } 33721 33722 /** 33723 * Override props assigned to save component to inject the CSS variables definition. 33724 * 33725 * @param {Object} props Additional props applied to save element. 33726 * @param {Object|string} blockNameOrType Block type. 33727 * @param {Object} attributes Block attributes. 33728 * @param {?Record<string, string[]>} skipPaths An object of keys and paths to skip serialization. 33729 * 33730 * @return {Object} Filtered props applied to save element. 33731 */ 33732 function style_addSaveProps(props, blockNameOrType, attributes, skipPaths = skipSerializationPathsSave) { 33733 if (!hasStyleSupport(blockNameOrType)) { 33734 return props; 33735 } 33736 let { 33737 style 33738 } = attributes; 33739 Object.entries(skipPaths).forEach(([indicator, path]) => { 33740 const skipSerialization = skipSerializationPathsSaveChecks[indicator] || (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockNameOrType, indicator); 33741 if (skipSerialization === true) { 33742 style = omitStyle(style, path); 33743 } 33744 if (Array.isArray(skipSerialization)) { 33745 skipSerialization.forEach(featureName => { 33746 const feature = renamedFeatures[featureName] || featureName; 33747 style = omitStyle(style, [[...path, feature]]); 33748 }); 33749 } 33750 }); 33751 props.style = { 33752 ...getInlineStyles(style), 33753 ...props.style 33754 }; 33755 return props; 33756 } 33757 function BlockStyleControls({ 33758 clientId, 33759 name, 33760 setAttributes, 33761 __unstableParentLayout 33762 }) { 33763 const settings = useBlockSettings(name, __unstableParentLayout); 33764 const blockEditingMode = useBlockEditingMode(); 33765 const passedProps = { 33766 clientId, 33767 name, 33768 setAttributes, 33769 settings: { 33770 ...settings, 33771 typography: { 33772 ...settings.typography, 33773 // The text alignment UI for individual blocks is rendered in 33774 // the block toolbar, so disable it here. 33775 textAlign: false 33776 } 33777 } 33778 }; 33779 if (blockEditingMode !== 'default') { 33780 return null; 33781 } 33782 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 33783 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorEdit, { 33784 ...passedProps 33785 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(background_BackgroundImagePanel, { 33786 ...passedProps 33787 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(typography_TypographyPanel, { 33788 ...passedProps 33789 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(border_BorderPanel, { 33790 ...passedProps 33791 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(dimensions_DimensionsPanel, { 33792 ...passedProps 33793 })] 33794 }); 33795 } 33796 /* harmony default export */ const style = ({ 33797 edit: BlockStyleControls, 33798 hasSupport: hasStyleSupport, 33799 addSaveProps: style_addSaveProps, 33800 attributeKeys: ['style'], 33801 useBlockProps: style_useBlockProps 33802 }); 33803 33804 // Defines which element types are supported, including their hover styles or 33805 // any other elements that have been included under a single element type 33806 // e.g. heading and h1-h6. 33807 const elementTypes = [{ 33808 elementType: 'button' 33809 }, { 33810 elementType: 'link', 33811 pseudo: [':hover'] 33812 }, { 33813 elementType: 'heading', 33814 elements: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] 33815 }]; 33816 33817 // Used for generating the instance ID 33818 const STYLE_BLOCK_PROPS_REFERENCE = {}; 33819 function style_useBlockProps({ 33820 name, 33821 style 33822 }) { 33823 const blockElementsContainerIdentifier = (0,external_wp_compose_namespaceObject.useInstanceId)(STYLE_BLOCK_PROPS_REFERENCE, 'wp-elements'); 33824 const baseElementSelector = `.$blockElementsContainerIdentifier}`; 33825 const blockElementStyles = style?.elements; 33826 const styles = (0,external_wp_element_namespaceObject.useMemo)(() => { 33827 if (!blockElementStyles) { 33828 return; 33829 } 33830 const elementCSSRules = []; 33831 elementTypes.forEach(({ 33832 elementType, 33833 pseudo, 33834 elements 33835 }) => { 33836 const skipSerialization = shouldSkipSerialization(name, COLOR_SUPPORT_KEY, elementType); 33837 if (skipSerialization) { 33838 return; 33839 } 33840 const elementStyles = blockElementStyles?.[elementType]; 33841 33842 // Process primary element type styles. 33843 if (elementStyles) { 33844 const selector = scopeSelector(baseElementSelector, external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementType]); 33845 elementCSSRules.push((0,external_wp_styleEngine_namespaceObject.compileCSS)(elementStyles, { 33846 selector 33847 })); 33848 33849 // Process any interactive states for the element type. 33850 if (pseudo) { 33851 pseudo.forEach(pseudoSelector => { 33852 if (elementStyles[pseudoSelector]) { 33853 elementCSSRules.push((0,external_wp_styleEngine_namespaceObject.compileCSS)(elementStyles[pseudoSelector], { 33854 selector: scopeSelector(baseElementSelector, `$external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementType]}$pseudoSelector}`) 33855 })); 33856 } 33857 }); 33858 } 33859 } 33860 33861 // Process related elements e.g. h1-h6 for headings 33862 if (elements) { 33863 elements.forEach(element => { 33864 if (blockElementStyles[element]) { 33865 elementCSSRules.push((0,external_wp_styleEngine_namespaceObject.compileCSS)(blockElementStyles[element], { 33866 selector: scopeSelector(baseElementSelector, external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[element]) 33867 })); 33868 } 33869 }); 33870 } 33871 }); 33872 return elementCSSRules.length > 0 ? elementCSSRules.join('') : undefined; 33873 }, [baseElementSelector, blockElementStyles, name]); 33874 useStyleOverride({ 33875 css: styles 33876 }); 33877 return style_addSaveProps({ 33878 className: blockElementsContainerIdentifier 33879 }, name, { 33880 style 33881 }, skipSerializationPathsEdit); 33882 } 33883 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/style/addAttribute', style_addAttribute); 33884 33885 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/settings.js 33886 /** 33887 * WordPress dependencies 33888 */ 33889 33890 33891 const hasSettingsSupport = blockType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, '__experimentalSettings', false); 33892 function settings_addAttribute(settings) { 33893 if (!hasSettingsSupport(settings)) { 33894 return settings; 33895 } 33896 33897 // Allow blocks to specify their own attribute definition with default values if needed. 33898 if (!settings?.attributes?.settings) { 33899 settings.attributes = { 33900 ...settings.attributes, 33901 settings: { 33902 type: 'object' 33903 } 33904 }; 33905 } 33906 return settings; 33907 } 33908 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/settings/addAttribute', settings_addAttribute); 33909 33910 ;// ./node_modules/@wordpress/icons/build-module/library/filter.js 33911 /** 33912 * WordPress dependencies 33913 */ 33914 33915 33916 const filter = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 33917 xmlns: "http://www.w3.org/2000/svg", 33918 viewBox: "0 0 24 24", 33919 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 33920 d: "M12 4 4 19h16L12 4zm0 3.2 5.5 10.3H12V7.2z" 33921 }) 33922 }); 33923 /* harmony default export */ const library_filter = (filter); 33924 33925 ;// ./node_modules/@wordpress/block-editor/build-module/components/duotone-control/index.js 33926 /** 33927 * WordPress dependencies 33928 */ 33929 33930 33931 33932 33933 33934 33935 function DuotoneControl({ 33936 id: idProp, 33937 colorPalette, 33938 duotonePalette, 33939 disableCustomColors, 33940 disableCustomDuotone, 33941 value, 33942 onChange 33943 }) { 33944 let toolbarIcon; 33945 if (value === 'unset') { 33946 toolbarIcon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ColorIndicator, { 33947 className: "block-editor-duotone-control__unset-indicator" 33948 }); 33949 } else if (value) { 33950 toolbarIcon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DuotoneSwatch, { 33951 values: value 33952 }); 33953 } else { 33954 toolbarIcon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 33955 icon: library_filter 33956 }); 33957 } 33958 const actionLabel = (0,external_wp_i18n_namespaceObject.__)('Apply duotone filter'); 33959 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(DuotoneControl, 'duotone-control', idProp); 33960 const descriptionId = `$id}__description`; 33961 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 33962 popoverProps: { 33963 className: 'block-editor-duotone-control__popover', 33964 headerTitle: (0,external_wp_i18n_namespaceObject.__)('Duotone') 33965 }, 33966 renderToggle: ({ 33967 isOpen, 33968 onToggle 33969 }) => { 33970 const openOnArrowDown = event => { 33971 if (!isOpen && event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 33972 event.preventDefault(); 33973 onToggle(); 33974 } 33975 }; 33976 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 33977 showTooltip: true, 33978 onClick: onToggle, 33979 "aria-haspopup": "true", 33980 "aria-expanded": isOpen, 33981 onKeyDown: openOnArrowDown, 33982 label: actionLabel, 33983 icon: toolbarIcon 33984 }); 33985 }, 33986 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 33987 label: (0,external_wp_i18n_namespaceObject.__)('Duotone'), 33988 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 33989 children: (0,external_wp_i18n_namespaceObject.__)('Create a two-tone color effect without losing your original image.') 33990 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DuotonePicker, { 33991 "aria-label": actionLabel, 33992 "aria-describedby": descriptionId, 33993 colorPalette: colorPalette, 33994 duotonePalette: duotonePalette, 33995 disableCustomColors: disableCustomColors, 33996 disableCustomDuotone: disableCustomDuotone, 33997 value: value, 33998 onChange: onChange 33999 })] 34000 }) 34001 }); 34002 } 34003 /* harmony default export */ const duotone_control = (DuotoneControl); 34004 34005 ;// ./node_modules/@wordpress/block-editor/build-module/components/duotone/utils.js 34006 /** 34007 * External dependencies 34008 */ 34009 34010 34011 /** 34012 * Convert a list of colors to an object of R, G, and B values. 34013 * 34014 * @param {string[]} colors Array of RBG color strings. 34015 * 34016 * @return {Object} R, G, and B values. 34017 */ 34018 function getValuesFromColors(colors = []) { 34019 const values = { 34020 r: [], 34021 g: [], 34022 b: [], 34023 a: [] 34024 }; 34025 colors.forEach(color => { 34026 const rgbColor = w(color).toRgb(); 34027 values.r.push(rgbColor.r / 255); 34028 values.g.push(rgbColor.g / 255); 34029 values.b.push(rgbColor.b / 255); 34030 values.a.push(rgbColor.a); 34031 }); 34032 return values; 34033 } 34034 34035 /** 34036 * Stylesheet for disabling a global styles duotone filter. 34037 * 34038 * @param {string} selector Selector to disable the filter for. 34039 * 34040 * @return {string} Filter none style. 34041 */ 34042 function getDuotoneUnsetStylesheet(selector) { 34043 return `$selector}{filter:none}`; 34044 } 34045 34046 /** 34047 * SVG and stylesheet needed for rendering the duotone filter. 34048 * 34049 * @param {string} selector Selector to apply the filter to. 34050 * @param {string} id Unique id for this duotone filter. 34051 * 34052 * @return {string} Duotone filter style. 34053 */ 34054 function getDuotoneStylesheet(selector, id) { 34055 return `$selector}{filter:url(#$id})}`; 34056 } 34057 34058 /** 34059 * The SVG part of the duotone filter. 34060 * 34061 * @param {string} id Unique id for this duotone filter. 34062 * @param {string[]} colors Color strings from dark to light. 34063 * 34064 * @return {string} Duotone SVG. 34065 */ 34066 function getDuotoneFilter(id, colors) { 34067 const values = getValuesFromColors(colors); 34068 return ` 34069 <svg 34070 xmlns:xlink="http://www.w3.org/1999/xlink" 34071 viewBox="0 0 0 0" 34072 width="0" 34073 height="0" 34074 focusable="false" 34075 role="none" 34076 aria-hidden="true" 34077 style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" 34078 > 34079 <defs> 34080 <filter id="$id}"> 34081 <!-- 34082 Use sRGB instead of linearRGB so transparency looks correct. 34083 Use perceptual brightness to convert to grayscale. 34084 --> 34085 <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> 34086 <!-- Use sRGB instead of linearRGB to be consistent with how CSS gradients work. --> 34087 <feComponentTransfer color-interpolation-filters="sRGB"> 34088 <feFuncR type="table" tableValues="$values.r.join(' ')}"></feFuncR> 34089 <feFuncG type="table" tableValues="$values.g.join(' ')}"></feFuncG> 34090 <feFuncB type="table" tableValues="$values.b.join(' ')}"></feFuncB> 34091 <feFuncA type="table" tableValues="$values.a.join(' ')}"></feFuncA> 34092 </feComponentTransfer> 34093 <!-- Re-mask the image with the original transparency since the feColorMatrix above loses that information. --> 34094 <feComposite in2="SourceGraphic" operator="in"></feComposite> 34095 </filter> 34096 </defs> 34097 </svg>`; 34098 } 34099 34100 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/get-block-css-selector.js 34101 /** 34102 * Internal dependencies 34103 */ 34104 34105 34106 34107 /** 34108 * Determine the CSS selector for the block type and target provided, returning 34109 * it if available. 34110 * 34111 * @param {import('@wordpress/blocks').Block} blockType The block's type. 34112 * @param {string|string[]} target The desired selector's target e.g. `root`, delimited string, or array path. 34113 * @param {Object} options Options object. 34114 * @param {boolean} options.fallback Whether or not to fallback to broader selector. 34115 * 34116 * @return {?string} The CSS selector or `null` if no selector available. 34117 */ 34118 function getBlockCSSSelector(blockType, target = 'root', options = {}) { 34119 if (!target) { 34120 return null; 34121 } 34122 const { 34123 fallback = false 34124 } = options; 34125 const { 34126 name, 34127 selectors, 34128 supports 34129 } = blockType; 34130 const hasSelectors = selectors && Object.keys(selectors).length > 0; 34131 const path = Array.isArray(target) ? target.join('.') : target; 34132 34133 // Root selector. 34134 34135 // Calculated before returning as it can be used as a fallback for feature 34136 // selectors later on. 34137 let rootSelector = null; 34138 if (hasSelectors && selectors.root) { 34139 // Use the selectors API if available. 34140 rootSelector = selectors?.root; 34141 } else if (supports?.__experimentalSelector) { 34142 // Use the old experimental selector supports property if set. 34143 rootSelector = supports.__experimentalSelector; 34144 } else { 34145 // If no root selector found, generate default block class selector. 34146 rootSelector = '.wp-block-' + name.replace('core/', '').replace('/', '-'); 34147 } 34148 34149 // Return selector if it's the root target we are looking for. 34150 if (path === 'root') { 34151 return rootSelector; 34152 } 34153 34154 // If target is not `root` or `duotone` we have a feature or subfeature 34155 // as the target. If the target is a string convert to an array. 34156 const pathArray = Array.isArray(target) ? target : target.split('.'); 34157 34158 // Feature selectors ( may fallback to root selector ); 34159 if (pathArray.length === 1) { 34160 const fallbackSelector = fallback ? rootSelector : null; 34161 34162 // Prefer the selectors API if available. 34163 if (hasSelectors) { 34164 // Get selector from either `feature.root` or shorthand path. 34165 const featureSelector = getValueFromObjectPath(selectors, `$path}.root`, null) || getValueFromObjectPath(selectors, path, null); 34166 34167 // Return feature selector if found or any available fallback. 34168 return featureSelector || fallbackSelector; 34169 } 34170 34171 // Try getting old experimental supports selector value. 34172 const featureSelector = getValueFromObjectPath(supports, `$path}.__experimentalSelector`, null); 34173 34174 // If nothing to work with, provide fallback selector if available. 34175 if (!featureSelector) { 34176 return fallbackSelector; 34177 } 34178 34179 // Scope the feature selector by the block's root selector. 34180 return scopeSelector(rootSelector, featureSelector); 34181 } 34182 34183 // Subfeature selector. 34184 // This may fallback either to parent feature or root selector. 34185 let subfeatureSelector; 34186 34187 // Use selectors API if available. 34188 if (hasSelectors) { 34189 subfeatureSelector = getValueFromObjectPath(selectors, path, null); 34190 } 34191 34192 // Only return if we have a subfeature selector. 34193 if (subfeatureSelector) { 34194 return subfeatureSelector; 34195 } 34196 34197 // To this point we don't have a subfeature selector. If a fallback has been 34198 // requested, remove subfeature from target path and return results of a 34199 // call for the parent feature's selector. 34200 if (fallback) { 34201 return getBlockCSSSelector(blockType, pathArray[0], options); 34202 } 34203 34204 // We tried. 34205 return null; 34206 } 34207 34208 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/filters-panel.js 34209 /** 34210 * External dependencies 34211 */ 34212 34213 34214 /** 34215 * WordPress dependencies 34216 */ 34217 34218 34219 34220 34221 34222 /** 34223 * Internal dependencies 34224 */ 34225 34226 34227 34228 const filters_panel_EMPTY_ARRAY = []; 34229 function useMultiOriginColorPresets(settings, { 34230 presetSetting, 34231 defaultSetting 34232 }) { 34233 const disableDefault = !settings?.color?.[defaultSetting]; 34234 const userPresets = settings?.color?.[presetSetting]?.custom || filters_panel_EMPTY_ARRAY; 34235 const themePresets = settings?.color?.[presetSetting]?.theme || filters_panel_EMPTY_ARRAY; 34236 const defaultPresets = settings?.color?.[presetSetting]?.default || filters_panel_EMPTY_ARRAY; 34237 return (0,external_wp_element_namespaceObject.useMemo)(() => [...userPresets, ...themePresets, ...(disableDefault ? filters_panel_EMPTY_ARRAY : defaultPresets)], [disableDefault, userPresets, themePresets, defaultPresets]); 34238 } 34239 function useHasFiltersPanel(settings) { 34240 return useHasDuotoneControl(settings); 34241 } 34242 function useHasDuotoneControl(settings) { 34243 return settings.color.customDuotone || settings.color.defaultDuotone || settings.color.duotone.length > 0; 34244 } 34245 function FiltersToolsPanel({ 34246 resetAllFilter, 34247 onChange, 34248 value, 34249 panelId, 34250 children 34251 }) { 34252 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 34253 const resetAll = () => { 34254 const updatedValue = resetAllFilter(value); 34255 onChange(updatedValue); 34256 }; 34257 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 34258 label: (0,external_wp_i18n_namespaceObject._x)('Filters', 'Name for applying graphical effects'), 34259 resetAll: resetAll, 34260 panelId: panelId, 34261 dropdownMenuProps: dropdownMenuProps, 34262 children: children 34263 }); 34264 } 34265 const filters_panel_DEFAULT_CONTROLS = { 34266 duotone: true 34267 }; 34268 const filters_panel_popoverProps = { 34269 placement: 'left-start', 34270 offset: 36, 34271 shift: true, 34272 className: 'block-editor-duotone-control__popover', 34273 headerTitle: (0,external_wp_i18n_namespaceObject.__)('Duotone') 34274 }; 34275 const LabeledColorIndicator = ({ 34276 indicator, 34277 label 34278 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 34279 justify: "flex-start", 34280 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalZStack, { 34281 isLayered: false, 34282 offset: -8, 34283 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Flex, { 34284 expanded: false, 34285 children: indicator === 'unset' || !indicator ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ColorIndicator, { 34286 className: "block-editor-duotone-control__unset-indicator" 34287 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DuotoneSwatch, { 34288 values: indicator 34289 }) 34290 }) 34291 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 34292 title: label, 34293 children: label 34294 })] 34295 }); 34296 const renderToggle = (duotone, resetDuotone) => ({ 34297 onToggle, 34298 isOpen 34299 }) => { 34300 const duotoneButtonRef = (0,external_wp_element_namespaceObject.useRef)(undefined); 34301 const toggleProps = { 34302 onClick: onToggle, 34303 className: dist_clsx({ 34304 'is-open': isOpen 34305 }), 34306 'aria-expanded': isOpen, 34307 ref: duotoneButtonRef 34308 }; 34309 const removeButtonProps = { 34310 onClick: () => { 34311 if (isOpen) { 34312 onToggle(); 34313 } 34314 resetDuotone(); 34315 // Return focus to parent button. 34316 duotoneButtonRef.current?.focus(); 34317 }, 34318 className: 'block-editor-panel-duotone-settings__reset', 34319 label: (0,external_wp_i18n_namespaceObject.__)('Reset') 34320 }; 34321 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 34322 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 34323 __next40pxDefaultSize: true, 34324 ...toggleProps, 34325 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LabeledColorIndicator, { 34326 indicator: duotone, 34327 label: (0,external_wp_i18n_namespaceObject.__)('Duotone') 34328 }) 34329 }), duotone && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 34330 size: "small", 34331 icon: library_reset, 34332 ...removeButtonProps 34333 })] 34334 }); 34335 }; 34336 function FiltersPanel({ 34337 as: Wrapper = FiltersToolsPanel, 34338 value, 34339 onChange, 34340 inheritedValue = value, 34341 settings, 34342 panelId, 34343 defaultControls = filters_panel_DEFAULT_CONTROLS 34344 }) { 34345 const decodeValue = rawValue => getValueFromVariable({ 34346 settings 34347 }, '', rawValue); 34348 34349 // Duotone 34350 const hasDuotoneEnabled = useHasDuotoneControl(settings); 34351 const duotonePalette = useMultiOriginColorPresets(settings, { 34352 presetSetting: 'duotone', 34353 defaultSetting: 'defaultDuotone' 34354 }); 34355 const colorPalette = useMultiOriginColorPresets(settings, { 34356 presetSetting: 'palette', 34357 defaultSetting: 'defaultPalette' 34358 }); 34359 const duotone = decodeValue(inheritedValue?.filter?.duotone); 34360 const setDuotone = newValue => { 34361 const duotonePreset = duotonePalette.find(({ 34362 colors 34363 }) => { 34364 return colors === newValue; 34365 }); 34366 const duotoneValue = duotonePreset ? `var:preset|duotone|$duotonePreset.slug}` : newValue; 34367 onChange(setImmutably(value, ['filter', 'duotone'], duotoneValue)); 34368 }; 34369 const hasDuotone = () => !!value?.filter?.duotone; 34370 const resetDuotone = () => setDuotone(undefined); 34371 const resetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(previousValue => { 34372 return { 34373 ...previousValue, 34374 filter: { 34375 ...previousValue.filter, 34376 duotone: undefined 34377 } 34378 }; 34379 }, []); 34380 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Wrapper, { 34381 resetAllFilter: resetAllFilter, 34382 value: value, 34383 onChange: onChange, 34384 panelId: panelId, 34385 children: hasDuotoneEnabled && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 34386 label: (0,external_wp_i18n_namespaceObject.__)('Duotone'), 34387 hasValue: hasDuotone, 34388 onDeselect: resetDuotone, 34389 isShownByDefault: defaultControls.duotone, 34390 panelId: panelId, 34391 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 34392 popoverProps: filters_panel_popoverProps, 34393 className: "block-editor-global-styles-filters-panel__dropdown", 34394 renderToggle: renderToggle(duotone, resetDuotone), 34395 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 34396 paddingSize: "small", 34397 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 34398 label: (0,external_wp_i18n_namespaceObject.__)('Duotone'), 34399 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 34400 children: (0,external_wp_i18n_namespaceObject.__)('Create a two-tone color effect without losing your original image.') 34401 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DuotonePicker, { 34402 colorPalette: colorPalette, 34403 duotonePalette: duotonePalette 34404 // TODO: Re-enable both when custom colors are supported for block-level styles. 34405 , 34406 disableCustomColors: true, 34407 disableCustomDuotone: true, 34408 value: duotone, 34409 onChange: setDuotone 34410 })] 34411 }) 34412 }) 34413 }) 34414 }) 34415 }); 34416 } 34417 34418 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/duotone.js 34419 /** 34420 * External dependencies 34421 */ 34422 34423 34424 34425 /** 34426 * WordPress dependencies 34427 */ 34428 34429 34430 34431 34432 34433 /** 34434 * Internal dependencies 34435 */ 34436 34437 34438 34439 34440 34441 34442 34443 34444 34445 const duotone_EMPTY_ARRAY = []; 34446 34447 // Safari does not always update the duotone filter when the duotone colors 34448 // are changed. This browser check is later used to force a re-render of the block 34449 // element to ensure the duotone filter is updated. The check is included at the 34450 // root of this file as it only needs to be run once per page load. 34451 const isSafari = window?.navigator.userAgent && window.navigator.userAgent.includes('Safari') && !window.navigator.userAgent.includes('Chrome') && !window.navigator.userAgent.includes('Chromium'); 34452 k([names]); 34453 function useMultiOriginPresets({ 34454 presetSetting, 34455 defaultSetting 34456 }) { 34457 const [enableDefault, userPresets, themePresets, defaultPresets] = use_settings_useSettings(defaultSetting, `$presetSetting}.custom`, `$presetSetting}.theme`, `$presetSetting}.default`); 34458 return (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPresets || duotone_EMPTY_ARRAY), ...(themePresets || duotone_EMPTY_ARRAY), ...(enableDefault && defaultPresets || duotone_EMPTY_ARRAY)], [enableDefault, userPresets, themePresets, defaultPresets]); 34459 } 34460 function getColorsFromDuotonePreset(duotone, duotonePalette) { 34461 if (!duotone) { 34462 return; 34463 } 34464 const preset = duotonePalette?.find(({ 34465 slug 34466 }) => { 34467 return duotone === `var:preset|duotone|$slug}`; 34468 }); 34469 return preset ? preset.colors : undefined; 34470 } 34471 function getDuotonePresetFromColors(colors, duotonePalette) { 34472 if (!colors || !Array.isArray(colors)) { 34473 return; 34474 } 34475 const preset = duotonePalette?.find(duotonePreset => { 34476 return duotonePreset?.colors?.every((val, index) => val === colors[index]); 34477 }); 34478 return preset ? `var:preset|duotone|$preset.slug}` : undefined; 34479 } 34480 function DuotonePanelPure({ 34481 style, 34482 setAttributes, 34483 name 34484 }) { 34485 const duotoneStyle = style?.color?.duotone; 34486 const settings = useBlockSettings(name); 34487 const blockEditingMode = useBlockEditingMode(); 34488 const duotonePalette = useMultiOriginPresets({ 34489 presetSetting: 'color.duotone', 34490 defaultSetting: 'color.defaultDuotone' 34491 }); 34492 const colorPalette = useMultiOriginPresets({ 34493 presetSetting: 'color.palette', 34494 defaultSetting: 'color.defaultPalette' 34495 }); 34496 const [enableCustomColors, enableCustomDuotone] = use_settings_useSettings('color.custom', 'color.customDuotone'); 34497 const disableCustomColors = !enableCustomColors; 34498 const disableCustomDuotone = !enableCustomDuotone || colorPalette?.length === 0 && disableCustomColors; 34499 if (duotonePalette?.length === 0 && disableCustomDuotone) { 34500 return null; 34501 } 34502 if (blockEditingMode !== 'default') { 34503 return null; 34504 } 34505 const duotonePresetOrColors = !Array.isArray(duotoneStyle) ? getColorsFromDuotonePreset(duotoneStyle, duotonePalette) : duotoneStyle; 34506 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 34507 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 34508 group: "filter", 34509 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FiltersPanel, { 34510 value: { 34511 filter: { 34512 duotone: duotonePresetOrColors 34513 } 34514 }, 34515 onChange: newDuotone => { 34516 const newStyle = { 34517 ...style, 34518 color: { 34519 ...newDuotone?.filter 34520 } 34521 }; 34522 setAttributes({ 34523 style: newStyle 34524 }); 34525 }, 34526 settings: settings 34527 }) 34528 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 34529 group: "block", 34530 __experimentalShareWithChildBlocks: true, 34531 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(duotone_control, { 34532 duotonePalette: duotonePalette, 34533 colorPalette: colorPalette, 34534 disableCustomDuotone: disableCustomDuotone, 34535 disableCustomColors: disableCustomColors, 34536 value: duotonePresetOrColors, 34537 onChange: newDuotone => { 34538 const maybePreset = getDuotonePresetFromColors(newDuotone, duotonePalette); 34539 const newStyle = { 34540 ...style, 34541 color: { 34542 ...style?.color, 34543 duotone: maybePreset !== null && maybePreset !== void 0 ? maybePreset : newDuotone // use preset or fallback to custom colors. 34544 } 34545 }; 34546 setAttributes({ 34547 style: newStyle 34548 }); 34549 }, 34550 settings: settings 34551 }) 34552 })] 34553 }); 34554 } 34555 /* harmony default export */ const duotone = ({ 34556 shareWithChildBlocks: true, 34557 edit: DuotonePanelPure, 34558 useBlockProps: duotone_useBlockProps, 34559 attributeKeys: ['style'], 34560 hasSupport(name) { 34561 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'filter.duotone'); 34562 } 34563 }); 34564 34565 /** 34566 * Filters registered block settings, extending attributes to include 34567 * the `duotone` attribute. 34568 * 34569 * @param {Object} settings Original block settings. 34570 * 34571 * @return {Object} Filtered block settings. 34572 */ 34573 function addDuotoneAttributes(settings) { 34574 // Previous `color.__experimentalDuotone` support flag is migrated via 34575 // block_type_metadata_settings filter in `lib/block-supports/duotone.php`. 34576 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'filter.duotone')) { 34577 return settings; 34578 } 34579 34580 // Allow blocks to specify their own attribute definition with default 34581 // values if needed. 34582 if (!settings.attributes.style) { 34583 Object.assign(settings.attributes, { 34584 style: { 34585 type: 'object' 34586 } 34587 }); 34588 } 34589 return settings; 34590 } 34591 function useDuotoneStyles({ 34592 clientId, 34593 id: filterId, 34594 selector: duotoneSelector, 34595 attribute: duotoneAttr 34596 }) { 34597 const duotonePalette = useMultiOriginPresets({ 34598 presetSetting: 'color.duotone', 34599 defaultSetting: 'color.defaultDuotone' 34600 }); 34601 34602 // Possible values for duotone attribute: 34603 // 1. Array of colors - e.g. ['#000000', '#ffffff']. 34604 // 2. Variable for an existing Duotone preset - e.g. 'var:preset|duotone|green-blue' or 'var(--wp--preset--duotone--green-blue)'' 34605 // 3. A CSS string - e.g. 'unset' to remove globally applied duotone. 34606 const isCustom = Array.isArray(duotoneAttr); 34607 const duotonePreset = isCustom ? undefined : getColorsFromDuotonePreset(duotoneAttr, duotonePalette); 34608 const isPreset = typeof duotoneAttr === 'string' && duotonePreset; 34609 const isCSS = typeof duotoneAttr === 'string' && !isPreset; 34610 34611 // Match the structure of WP_Duotone_Gutenberg::render_duotone_support() in PHP. 34612 let colors = null; 34613 if (isPreset) { 34614 // Array of colors. 34615 colors = duotonePreset; 34616 } else if (isCSS) { 34617 // CSS filter property string (e.g. 'unset'). 34618 colors = duotoneAttr; 34619 } else if (isCustom) { 34620 // Array of colors. 34621 colors = duotoneAttr; 34622 } 34623 34624 // Build the CSS selectors to which the filter will be applied. 34625 const selectors = duotoneSelector.split(','); 34626 const selectorsScoped = selectors.map(selectorPart => { 34627 // Assuming the selector part is a subclass selector (not a tag name) 34628 // so we can prepend the filter id class. If we want to support elements 34629 // such as `img` or namespaces, we'll need to add a case for that here. 34630 return `.$filterId}$selectorPart.trim()}`; 34631 }); 34632 const selector = selectorsScoped.join(', '); 34633 const isValidFilter = Array.isArray(colors) || colors === 'unset'; 34634 usePrivateStyleOverride(isValidFilter ? { 34635 css: colors !== 'unset' ? getDuotoneStylesheet(selector, filterId) : getDuotoneUnsetStylesheet(selector), 34636 __unstableType: 'presets' 34637 } : undefined); 34638 usePrivateStyleOverride(isValidFilter ? { 34639 assets: colors !== 'unset' ? getDuotoneFilter(filterId, colors) : '', 34640 __unstableType: 'svgs' 34641 } : undefined); 34642 const blockElement = useBlockElement(clientId); 34643 (0,external_wp_element_namespaceObject.useEffect)(() => { 34644 if (!isValidFilter) { 34645 return; 34646 } 34647 34648 // Safari does not always update the duotone filter when the duotone 34649 // colors are changed. When using Safari, force the block element to be 34650 // repainted by the browser to ensure any changes are reflected 34651 // visually. This logic matches that used on the site frontend in 34652 // `block-supports/duotone.php`. 34653 if (blockElement && isSafari) { 34654 const display = blockElement.style.display; 34655 // Switch to `inline-block` to force a repaint. In the editor, 34656 // `inline-block` is used instead of `none` to ensure that scroll 34657 // position is not affected, as `none` results in the editor 34658 // scrolling to the top of the block. 34659 blockElement.style.setProperty('display', 'inline-block'); 34660 // Simply accessing el.offsetHeight flushes layout and style changes 34661 // in WebKit without having to wait for setTimeout. 34662 // eslint-disable-next-line no-unused-expressions 34663 blockElement.offsetHeight; 34664 blockElement.style.setProperty('display', display); 34665 } 34666 // `colors` must be a dependency so this effect runs when the colors 34667 // change in Safari. 34668 }, [isValidFilter, blockElement, colors]); 34669 } 34670 34671 // Used for generating the instance ID 34672 const DUOTONE_BLOCK_PROPS_REFERENCE = {}; 34673 function duotone_useBlockProps({ 34674 clientId, 34675 name, 34676 style 34677 }) { 34678 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(DUOTONE_BLOCK_PROPS_REFERENCE); 34679 const selector = (0,external_wp_element_namespaceObject.useMemo)(() => { 34680 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 34681 if (blockType) { 34682 // Backwards compatibility for `supports.color.__experimentalDuotone` 34683 // is provided via the `block_type_metadata_settings` filter. If 34684 // `supports.filter.duotone` has not been set and the 34685 // experimental property has been, the experimental property 34686 // value is copied into `supports.filter.duotone`. 34687 const duotoneSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'filter.duotone', false); 34688 if (!duotoneSupport) { 34689 return null; 34690 } 34691 34692 // If the experimental duotone support was set, that value is 34693 // to be treated as a selector and requires scoping. 34694 const experimentalDuotone = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'color.__experimentalDuotone', false); 34695 if (experimentalDuotone) { 34696 const rootSelector = getBlockCSSSelector(blockType); 34697 return typeof experimentalDuotone === 'string' ? scopeSelector(rootSelector, experimentalDuotone) : rootSelector; 34698 } 34699 34700 // Regular filter.duotone support uses filter.duotone selectors with fallbacks. 34701 return getBlockCSSSelector(blockType, 'filter.duotone', { 34702 fallback: true 34703 }); 34704 } 34705 }, [name]); 34706 const attribute = style?.color?.duotone; 34707 const filterClass = `wp-duotone-$id}`; 34708 const shouldRender = selector && attribute; 34709 useDuotoneStyles({ 34710 clientId, 34711 id: filterClass, 34712 selector, 34713 attribute 34714 }); 34715 return { 34716 className: shouldRender ? filterClass : '' 34717 }; 34718 } 34719 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/editor/duotone/add-attributes', addDuotoneAttributes); 34720 34721 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-block-display-information/index.js 34722 /** 34723 * WordPress dependencies 34724 */ 34725 34726 34727 34728 34729 /** 34730 * Internal dependencies 34731 */ 34732 34733 34734 /** @typedef {import('@wordpress/blocks').WPIcon} WPIcon */ 34735 34736 /** 34737 * Contains basic block's information for display reasons. 34738 * 34739 * @typedef {Object} WPBlockDisplayInformation 34740 * 34741 * @property {boolean} isSynced True if is a reusable block or template part 34742 * @property {string} title Human-readable block type label. 34743 * @property {WPIcon} icon Block type icon. 34744 * @property {string} description A detailed block type description. 34745 * @property {string} anchor HTML anchor. 34746 * @property {name} name A custom, human readable name for the block. 34747 */ 34748 34749 /** 34750 * Get the display label for a block's position type. 34751 * 34752 * @param {Object} attributes Block attributes. 34753 * @return {string} The position type label. 34754 */ 34755 function getPositionTypeLabel(attributes) { 34756 const positionType = attributes?.style?.position?.type; 34757 if (positionType === 'sticky') { 34758 return (0,external_wp_i18n_namespaceObject.__)('Sticky'); 34759 } 34760 if (positionType === 'fixed') { 34761 return (0,external_wp_i18n_namespaceObject.__)('Fixed'); 34762 } 34763 return null; 34764 } 34765 34766 /** 34767 * Hook used to try to find a matching block variation and return 34768 * the appropriate information for display reasons. In order to 34769 * to try to find a match we need to things: 34770 * 1. Block's client id to extract it's current attributes. 34771 * 2. A block variation should have set `isActive` prop to a proper function. 34772 * 34773 * If for any reason a block variation match cannot be found, 34774 * the returned information come from the Block Type. 34775 * If no blockType is found with the provided clientId, returns null. 34776 * 34777 * @param {string} clientId Block's client id. 34778 * @return {?WPBlockDisplayInformation} Block's display information, or `null` when the block or its type not found. 34779 */ 34780 34781 function useBlockDisplayInformation(clientId) { 34782 return (0,external_wp_data_namespaceObject.useSelect)(select => { 34783 if (!clientId) { 34784 return null; 34785 } 34786 const { 34787 getBlockName, 34788 getBlockAttributes 34789 } = select(store); 34790 const { 34791 getBlockType, 34792 getActiveBlockVariation 34793 } = select(external_wp_blocks_namespaceObject.store); 34794 const blockName = getBlockName(clientId); 34795 const blockType = getBlockType(blockName); 34796 if (!blockType) { 34797 return null; 34798 } 34799 const attributes = getBlockAttributes(clientId); 34800 const match = getActiveBlockVariation(blockName, attributes); 34801 const isSynced = (0,external_wp_blocks_namespaceObject.isReusableBlock)(blockType) || (0,external_wp_blocks_namespaceObject.isTemplatePart)(blockType); 34802 const syncedTitle = isSynced ? (0,external_wp_blocks_namespaceObject.__experimentalGetBlockLabel)(blockType, attributes) : undefined; 34803 const title = syncedTitle || blockType.title; 34804 const positionLabel = getPositionTypeLabel(attributes); 34805 const blockTypeInfo = { 34806 isSynced, 34807 title, 34808 icon: blockType.icon, 34809 description: blockType.description, 34810 anchor: attributes?.anchor, 34811 positionLabel, 34812 positionType: attributes?.style?.position?.type, 34813 name: attributes?.metadata?.name 34814 }; 34815 if (!match) { 34816 return blockTypeInfo; 34817 } 34818 return { 34819 isSynced, 34820 title: match.title || blockType.title, 34821 icon: match.icon || blockType.icon, 34822 description: match.description || blockType.description, 34823 anchor: attributes?.anchor, 34824 positionLabel, 34825 positionType: attributes?.style?.position?.type, 34826 name: attributes?.metadata?.name 34827 }; 34828 }, [clientId]); 34829 } 34830 34831 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/position.js 34832 /** 34833 * External dependencies 34834 */ 34835 34836 34837 /** 34838 * WordPress dependencies 34839 */ 34840 34841 34842 34843 34844 34845 34846 34847 /** 34848 * Internal dependencies 34849 */ 34850 34851 34852 34853 34854 34855 34856 const POSITION_SUPPORT_KEY = 'position'; 34857 const DEFAULT_OPTION = { 34858 key: 'default', 34859 value: '', 34860 name: (0,external_wp_i18n_namespaceObject.__)('Default') 34861 }; 34862 const STICKY_OPTION = { 34863 key: 'sticky', 34864 value: 'sticky', 34865 name: (0,external_wp_i18n_namespaceObject._x)('Sticky', 'Name for the value of the CSS position property'), 34866 hint: (0,external_wp_i18n_namespaceObject.__)('The block will stick to the top of the window instead of scrolling.') 34867 }; 34868 const FIXED_OPTION = { 34869 key: 'fixed', 34870 value: 'fixed', 34871 name: (0,external_wp_i18n_namespaceObject._x)('Fixed', 'Name for the value of the CSS position property'), 34872 hint: (0,external_wp_i18n_namespaceObject.__)('The block will not move when the page is scrolled.') 34873 }; 34874 const POSITION_SIDES = ['top', 'right', 'bottom', 'left']; 34875 const VALID_POSITION_TYPES = ['sticky', 'fixed']; 34876 34877 /** 34878 * Get calculated position CSS. 34879 * 34880 * @param {Object} props Component props. 34881 * @param {string} props.selector Selector to use. 34882 * @param {Object} props.style Style object. 34883 * @return {string} The generated CSS rules. 34884 */ 34885 function getPositionCSS({ 34886 selector, 34887 style 34888 }) { 34889 let output = ''; 34890 const { 34891 type: positionType 34892 } = style?.position || {}; 34893 if (!VALID_POSITION_TYPES.includes(positionType)) { 34894 return output; 34895 } 34896 output += `$selector} {`; 34897 output += `position: $positionType};`; 34898 POSITION_SIDES.forEach(side => { 34899 if (style?.position?.[side] !== undefined) { 34900 output += `$side}: $style.position[side]};`; 34901 } 34902 }); 34903 if (positionType === 'sticky' || positionType === 'fixed') { 34904 // TODO: Replace hard-coded z-index value with a z-index preset approach in theme.json. 34905 output += `z-index: 10`; 34906 } 34907 output += `}`; 34908 return output; 34909 } 34910 34911 /** 34912 * Determines if there is sticky position support. 34913 * 34914 * @param {string|Object} blockType Block name or Block Type object. 34915 * 34916 * @return {boolean} Whether there is support. 34917 */ 34918 function hasStickyPositionSupport(blockType) { 34919 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, POSITION_SUPPORT_KEY); 34920 return !!(true === support || support?.sticky); 34921 } 34922 34923 /** 34924 * Determines if there is fixed position support. 34925 * 34926 * @param {string|Object} blockType Block name or Block Type object. 34927 * 34928 * @return {boolean} Whether there is support. 34929 */ 34930 function hasFixedPositionSupport(blockType) { 34931 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, POSITION_SUPPORT_KEY); 34932 return !!(true === support || support?.fixed); 34933 } 34934 34935 /** 34936 * Determines if there is position support. 34937 * 34938 * @param {string|Object} blockType Block name or Block Type object. 34939 * 34940 * @return {boolean} Whether there is support. 34941 */ 34942 function hasPositionSupport(blockType) { 34943 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, POSITION_SUPPORT_KEY); 34944 return !!support; 34945 } 34946 34947 /** 34948 * Checks if there is a current value in the position block support attributes. 34949 * 34950 * @param {Object} props Block props. 34951 * @return {boolean} Whether or not the block has a position value set. 34952 */ 34953 function hasPositionValue(props) { 34954 return props.attributes.style?.position?.type !== undefined; 34955 } 34956 34957 /** 34958 * Checks if the block is currently set to a sticky or fixed position. 34959 * This check is helpful for determining how to position block toolbars or other elements. 34960 * 34961 * @param {Object} attributes Block attributes. 34962 * @return {boolean} Whether or not the block is set to a sticky or fixed position. 34963 */ 34964 function hasStickyOrFixedPositionValue(attributes) { 34965 const positionType = attributes?.style?.position?.type; 34966 return positionType === 'sticky' || positionType === 'fixed'; 34967 } 34968 34969 /** 34970 * Resets the position block support attributes. This can be used when disabling 34971 * the position support controls for a block via a `ToolsPanel`. 34972 * 34973 * @param {Object} props Block props. 34974 * @param {Object} props.attributes Block's attributes. 34975 * @param {Object} props.setAttributes Function to set block's attributes. 34976 */ 34977 function resetPosition({ 34978 attributes = {}, 34979 setAttributes 34980 }) { 34981 const { 34982 style = {} 34983 } = attributes; 34984 setAttributes({ 34985 style: cleanEmptyObject({ 34986 ...style, 34987 position: { 34988 ...style?.position, 34989 type: undefined, 34990 top: undefined, 34991 right: undefined, 34992 bottom: undefined, 34993 left: undefined 34994 } 34995 }) 34996 }); 34997 } 34998 34999 /** 35000 * Custom hook that checks if position settings have been disabled. 35001 * 35002 * @param {string} name The name of the block. 35003 * 35004 * @return {boolean} Whether padding setting is disabled. 35005 */ 35006 function useIsPositionDisabled({ 35007 name: blockName 35008 } = {}) { 35009 const [allowFixed, allowSticky] = use_settings_useSettings('position.fixed', 'position.sticky'); 35010 const isDisabled = !allowFixed && !allowSticky; 35011 return !hasPositionSupport(blockName) || isDisabled; 35012 } 35013 35014 /* 35015 * Position controls rendered in an inspector control panel. 35016 * 35017 * @param {Object} props 35018 * 35019 * @return {Element} Position panel. 35020 */ 35021 function PositionPanelPure({ 35022 style = {}, 35023 clientId, 35024 name: blockName, 35025 setAttributes 35026 }) { 35027 const allowFixed = hasFixedPositionSupport(blockName); 35028 const allowSticky = hasStickyPositionSupport(blockName); 35029 const value = style?.position?.type; 35030 const { 35031 firstParentClientId 35032 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 35033 const { 35034 getBlockParents 35035 } = select(store); 35036 const parents = getBlockParents(clientId); 35037 return { 35038 firstParentClientId: parents[parents.length - 1] 35039 }; 35040 }, [clientId]); 35041 const blockInformation = useBlockDisplayInformation(firstParentClientId); 35042 const stickyHelpText = allowSticky && value === STICKY_OPTION.value && blockInformation ? (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: the name of the parent block. */ 35043 (0,external_wp_i18n_namespaceObject.__)('The block will stick to the scrollable area of the parent %s block.'), blockInformation.title) : null; 35044 const options = (0,external_wp_element_namespaceObject.useMemo)(() => { 35045 const availableOptions = [DEFAULT_OPTION]; 35046 // Display options if they are allowed, or if a block already has a valid value set. 35047 // This allows for a block to be switched off from a position type that is not allowed. 35048 if (allowSticky || value === STICKY_OPTION.value) { 35049 availableOptions.push(STICKY_OPTION); 35050 } 35051 if (allowFixed || value === FIXED_OPTION.value) { 35052 availableOptions.push(FIXED_OPTION); 35053 } 35054 return availableOptions; 35055 }, [allowFixed, allowSticky, value]); 35056 const onChangeType = next => { 35057 // For now, use a hard-coded `0px` value for the position. 35058 // `0px` is preferred over `0` as it can be used in `calc()` functions. 35059 // In the future, it could be useful to allow for an offset value. 35060 const placementValue = '0px'; 35061 const newStyle = { 35062 ...style, 35063 position: { 35064 ...style?.position, 35065 type: next, 35066 top: next === 'sticky' || next === 'fixed' ? placementValue : undefined 35067 } 35068 }; 35069 setAttributes({ 35070 style: utils_cleanEmptyObject(newStyle) 35071 }); 35072 }; 35073 const selectedOption = value ? options.find(option => option.value === value) || DEFAULT_OPTION : DEFAULT_OPTION; 35074 35075 // Only display position controls if there is at least one option to choose from. 35076 return external_wp_element_namespaceObject.Platform.select({ 35077 web: options.length > 1 ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 35078 group: "position", 35079 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.BaseControl, { 35080 __nextHasNoMarginBottom: true, 35081 help: stickyHelpText, 35082 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CustomSelectControl, { 35083 __next40pxDefaultSize: true, 35084 label: (0,external_wp_i18n_namespaceObject.__)('Position'), 35085 hideLabelFromVision: true, 35086 describedBy: (0,external_wp_i18n_namespaceObject.sprintf)( 35087 // translators: %s: Currently selected position. 35088 (0,external_wp_i18n_namespaceObject.__)('Currently selected position: %s'), selectedOption.name), 35089 options: options, 35090 value: selectedOption, 35091 onChange: ({ 35092 selectedItem 35093 }) => { 35094 onChangeType(selectedItem.value); 35095 }, 35096 size: "__unstable-large" 35097 }) 35098 }) 35099 }) : null, 35100 native: null 35101 }); 35102 } 35103 /* harmony default export */ const position = ({ 35104 edit: function Edit(props) { 35105 const isPositionDisabled = useIsPositionDisabled(props); 35106 if (isPositionDisabled) { 35107 return null; 35108 } 35109 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PositionPanelPure, { 35110 ...props 35111 }); 35112 }, 35113 useBlockProps: position_useBlockProps, 35114 attributeKeys: ['style'], 35115 hasSupport(name) { 35116 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, POSITION_SUPPORT_KEY); 35117 } 35118 }); 35119 35120 // Used for generating the instance ID 35121 const POSITION_BLOCK_PROPS_REFERENCE = {}; 35122 function position_useBlockProps({ 35123 name, 35124 style 35125 }) { 35126 const hasPositionBlockSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, POSITION_SUPPORT_KEY); 35127 const isPositionDisabled = useIsPositionDisabled({ 35128 name 35129 }); 35130 const allowPositionStyles = hasPositionBlockSupport && !isPositionDisabled; 35131 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(POSITION_BLOCK_PROPS_REFERENCE); 35132 35133 // Higher specificity to override defaults in editor UI. 35134 const positionSelector = `.wp-container-$id}.wp-container-$id}`; 35135 35136 // Get CSS string for the current position values. 35137 let css; 35138 if (allowPositionStyles) { 35139 css = getPositionCSS({ 35140 selector: positionSelector, 35141 style 35142 }) || ''; 35143 } 35144 35145 // Attach a `wp-container-` id-based class name. 35146 const className = dist_clsx({ 35147 [`wp-container-$id}`]: allowPositionStyles && !!css, 35148 // Only attach a container class if there is generated CSS to be attached. 35149 [`is-position-$style?.position?.type}`]: allowPositionStyles && !!css && !!style?.position?.type 35150 }); 35151 useStyleOverride({ 35152 css 35153 }); 35154 return { 35155 className 35156 }; 35157 } 35158 35159 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/use-global-styles-output.js 35160 /** 35161 * WordPress dependencies 35162 */ 35163 35164 35165 35166 35167 35168 35169 /** 35170 * Internal dependencies 35171 */ 35172 35173 35174 35175 35176 35177 35178 35179 35180 35181 35182 35183 35184 35185 // Elements that rely on class names in their selectors. 35186 const ELEMENT_CLASS_NAMES = { 35187 button: 'wp-element-button', 35188 caption: 'wp-element-caption' 35189 }; 35190 35191 // List of block support features that can have their related styles 35192 // generated under their own feature level selector rather than the block's. 35193 const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = { 35194 __experimentalBorder: 'border', 35195 color: 'color', 35196 spacing: 'spacing', 35197 typography: 'typography' 35198 }; 35199 const { 35200 kebabCase: use_global_styles_output_kebabCase 35201 } = unlock(external_wp_components_namespaceObject.privateApis); 35202 35203 /** 35204 * Transform given preset tree into a set of style declarations. 35205 * 35206 * @param {Object} blockPresets 35207 * @param {Object} mergedSettings Merged theme.json settings. 35208 * 35209 * @return {Array<Object>} An array of style declarations. 35210 */ 35211 function getPresetsDeclarations(blockPresets = {}, mergedSettings) { 35212 return PRESET_METADATA.reduce((declarations, { 35213 path, 35214 valueKey, 35215 valueFunc, 35216 cssVarInfix 35217 }) => { 35218 const presetByOrigin = getValueFromObjectPath(blockPresets, path, []); 35219 ['default', 'theme', 'custom'].forEach(origin => { 35220 if (presetByOrigin[origin]) { 35221 presetByOrigin[origin].forEach(value => { 35222 if (valueKey && !valueFunc) { 35223 declarations.push(`--wp--preset--$cssVarInfix}--$use_global_styles_output_kebabCase(value.slug)}: $value[valueKey]}`); 35224 } else if (valueFunc && typeof valueFunc === 'function') { 35225 declarations.push(`--wp--preset--$cssVarInfix}--$use_global_styles_output_kebabCase(value.slug)}: $valueFunc(value, mergedSettings)}`); 35226 } 35227 }); 35228 } 35229 }); 35230 return declarations; 35231 }, []); 35232 } 35233 35234 /** 35235 * Transform given preset tree into a set of preset class declarations. 35236 * 35237 * @param {?string} blockSelector 35238 * @param {Object} blockPresets 35239 * @return {string} CSS declarations for the preset classes. 35240 */ 35241 function getPresetsClasses(blockSelector = '*', blockPresets = {}) { 35242 return PRESET_METADATA.reduce((declarations, { 35243 path, 35244 cssVarInfix, 35245 classes 35246 }) => { 35247 if (!classes) { 35248 return declarations; 35249 } 35250 const presetByOrigin = getValueFromObjectPath(blockPresets, path, []); 35251 ['default', 'theme', 'custom'].forEach(origin => { 35252 if (presetByOrigin[origin]) { 35253 presetByOrigin[origin].forEach(({ 35254 slug 35255 }) => { 35256 classes.forEach(({ 35257 classSuffix, 35258 propertyName 35259 }) => { 35260 const classSelectorToUse = `.has-$use_global_styles_output_kebabCase(slug)}-$classSuffix}`; 35261 const selectorToUse = blockSelector.split(',') // Selector can be "h1, h2, h3" 35262 .map(selector => `$selector}$classSelectorToUse}`).join(','); 35263 const value = `var(--wp--preset--$cssVarInfix}--$use_global_styles_output_kebabCase(slug)})`; 35264 declarations += `$selectorToUse}{$propertyName}: $value} !important;}`; 35265 }); 35266 }); 35267 } 35268 }); 35269 return declarations; 35270 }, ''); 35271 } 35272 function getPresetsSvgFilters(blockPresets = {}) { 35273 return PRESET_METADATA.filter( 35274 // Duotone are the only type of filters for now. 35275 metadata => metadata.path.at(-1) === 'duotone').flatMap(metadata => { 35276 const presetByOrigin = getValueFromObjectPath(blockPresets, metadata.path, {}); 35277 return ['default', 'theme'].filter(origin => presetByOrigin[origin]).flatMap(origin => presetByOrigin[origin].map(preset => getDuotoneFilter(`wp-duotone-$preset.slug}`, preset.colors))).join(''); 35278 }); 35279 } 35280 function flattenTree(input = {}, prefix, token) { 35281 let result = []; 35282 Object.keys(input).forEach(key => { 35283 const newKey = prefix + use_global_styles_output_kebabCase(key.replace('/', '-')); 35284 const newLeaf = input[key]; 35285 if (newLeaf instanceof Object) { 35286 const newPrefix = newKey + token; 35287 result = [...result, ...flattenTree(newLeaf, newPrefix, token)]; 35288 } else { 35289 result.push(`$newKey}: $newLeaf}`); 35290 } 35291 }); 35292 return result; 35293 } 35294 35295 /** 35296 * Gets variation selector string from feature selector. 35297 * 35298 * @param {string} featureSelector The feature selector. 35299 * 35300 * @param {string} styleVariationSelector The style variation selector. 35301 * @return {string} Combined selector string. 35302 */ 35303 function concatFeatureVariationSelectorString(featureSelector, styleVariationSelector) { 35304 const featureSelectors = featureSelector.split(','); 35305 const combinedSelectors = []; 35306 featureSelectors.forEach(selector => { 35307 combinedSelectors.push(`$styleVariationSelector.trim()}$selector.trim()}`); 35308 }); 35309 return combinedSelectors.join(', '); 35310 } 35311 35312 /** 35313 * Generate style declarations for a block's custom feature and subfeature 35314 * selectors. 35315 * 35316 * NOTE: The passed `styles` object will be mutated by this function. 35317 * 35318 * @param {Object} selectors Custom selectors object for a block. 35319 * @param {Object} styles A block's styles object. 35320 * 35321 * @return {Object} Style declarations. 35322 */ 35323 const getFeatureDeclarations = (selectors, styles) => { 35324 const declarations = {}; 35325 Object.entries(selectors).forEach(([feature, selector]) => { 35326 // We're only processing features/subfeatures that have styles. 35327 if (feature === 'root' || !styles?.[feature]) { 35328 return; 35329 } 35330 const isShorthand = typeof selector === 'string'; 35331 35332 // If we have a selector object instead of shorthand process it. 35333 if (!isShorthand) { 35334 Object.entries(selector).forEach(([subfeature, subfeatureSelector]) => { 35335 // Don't process root feature selector yet or any 35336 // subfeature that doesn't have a style. 35337 if (subfeature === 'root' || !styles?.[feature][subfeature]) { 35338 return; 35339 } 35340 35341 // Create a temporary styles object and build 35342 // declarations for subfeature. 35343 const subfeatureStyles = { 35344 [feature]: { 35345 [subfeature]: styles[feature][subfeature] 35346 } 35347 }; 35348 const newDeclarations = getStylesDeclarations(subfeatureStyles); 35349 35350 // Merge new declarations in with any others that 35351 // share the same selector. 35352 declarations[subfeatureSelector] = [...(declarations[subfeatureSelector] || []), ...newDeclarations]; 35353 35354 // Remove the subfeature's style now it will be 35355 // included under its own selector not the block's. 35356 delete styles[feature][subfeature]; 35357 }); 35358 } 35359 35360 // Now subfeatures have been processed and removed, we can 35361 // process root, or shorthand, feature selectors. 35362 if (isShorthand || selector.root) { 35363 const featureSelector = isShorthand ? selector : selector.root; 35364 35365 // Create temporary style object and build declarations for feature. 35366 const featureStyles = { 35367 [feature]: styles[feature] 35368 }; 35369 const newDeclarations = getStylesDeclarations(featureStyles); 35370 35371 // Merge new declarations with any others that share the selector. 35372 declarations[featureSelector] = [...(declarations[featureSelector] || []), ...newDeclarations]; 35373 35374 // Remove the feature from the block's styles now as it will be 35375 // included under its own selector not the block's. 35376 delete styles[feature]; 35377 } 35378 }); 35379 return declarations; 35380 }; 35381 35382 /** 35383 * Transform given style tree into a set of style declarations. 35384 * 35385 * @param {Object} blockStyles Block styles. 35386 * 35387 * @param {string} selector The selector these declarations should attach to. 35388 * 35389 * @param {boolean} useRootPaddingAlign Whether to use CSS custom properties in root selector. 35390 * 35391 * @param {Object} tree A theme.json tree containing layout definitions. 35392 * 35393 * @param {boolean} disableRootPadding Whether to force disable the root padding styles. 35394 * @return {Array} An array of style declarations. 35395 */ 35396 function getStylesDeclarations(blockStyles = {}, selector = '', useRootPaddingAlign, tree = {}, disableRootPadding = false) { 35397 const isRoot = ROOT_BLOCK_SELECTOR === selector; 35398 const output = Object.entries(external_wp_blocks_namespaceObject.__EXPERIMENTAL_STYLE_PROPERTY).reduce((declarations, [key, { 35399 value, 35400 properties, 35401 useEngine, 35402 rootOnly 35403 }]) => { 35404 if (rootOnly && !isRoot) { 35405 return declarations; 35406 } 35407 const pathToValue = value; 35408 if (pathToValue[0] === 'elements' || useEngine) { 35409 return declarations; 35410 } 35411 const styleValue = getValueFromObjectPath(blockStyles, pathToValue); 35412 35413 // Root-level padding styles don't currently support strings with CSS shorthand values. 35414 // This may change: https://github.com/WordPress/gutenberg/issues/40132. 35415 if (key === '--wp--style--root--padding' && (typeof styleValue === 'string' || !useRootPaddingAlign)) { 35416 return declarations; 35417 } 35418 if (properties && typeof styleValue !== 'string') { 35419 Object.entries(properties).forEach(entry => { 35420 const [name, prop] = entry; 35421 if (!getValueFromObjectPath(styleValue, [prop], false)) { 35422 // Do not create a declaration 35423 // for sub-properties that don't have any value. 35424 return; 35425 } 35426 const cssProperty = name.startsWith('--') ? name : use_global_styles_output_kebabCase(name); 35427 declarations.push(`$cssProperty}: ${(0,external_wp_styleEngine_namespaceObject.getCSSValueFromRawStyle)(getValueFromObjectPath(styleValue, [prop]))}`); 35428 }); 35429 } else if (getValueFromObjectPath(blockStyles, pathToValue, false)) { 35430 const cssProperty = key.startsWith('--') ? key : use_global_styles_output_kebabCase(key); 35431 declarations.push(`$cssProperty}: ${(0,external_wp_styleEngine_namespaceObject.getCSSValueFromRawStyle)(getValueFromObjectPath(blockStyles, pathToValue))}`); 35432 } 35433 return declarations; 35434 }, []); 35435 35436 /* 35437 * Preprocess background image values. 35438 * 35439 * Note: As we absorb more and more styles into the engine, we could simplify this function. 35440 * A refactor is for the style engine to handle ref resolution (and possibly defaults) 35441 * via a public util used internally and externally. Theme.json tree and defaults could be passed 35442 * as options. 35443 */ 35444 if (!!blockStyles.background) { 35445 /* 35446 * Resolve dynamic values before they are compiled by the style engine, 35447 * which doesn't (yet) resolve dynamic values. 35448 */ 35449 if (blockStyles.background?.backgroundImage) { 35450 blockStyles.background.backgroundImage = getResolvedValue(blockStyles.background.backgroundImage, tree); 35451 } 35452 35453 /* 35454 * Set default values for block background styles. 35455 * Top-level styles are an exception as they are applied to the body. 35456 */ 35457 if (!isRoot && !!blockStyles.background?.backgroundImage?.id) { 35458 blockStyles = { 35459 ...blockStyles, 35460 background: { 35461 ...blockStyles.background, 35462 ...setBackgroundStyleDefaults(blockStyles.background) 35463 } 35464 }; 35465 } 35466 } 35467 const extraRules = (0,external_wp_styleEngine_namespaceObject.getCSSRules)(blockStyles); 35468 extraRules.forEach(rule => { 35469 // Don't output padding properties if padding variables are set or if we're not editing a full template. 35470 if (isRoot && (useRootPaddingAlign || disableRootPadding) && rule.key.startsWith('padding')) { 35471 return; 35472 } 35473 const cssProperty = rule.key.startsWith('--') ? rule.key : use_global_styles_output_kebabCase(rule.key); 35474 let ruleValue = getResolvedValue(rule.value, tree, null); 35475 35476 // Calculate fluid typography rules where available. 35477 if (cssProperty === 'font-size') { 35478 /* 35479 * getTypographyFontSizeValue() will check 35480 * if fluid typography has been activated and also 35481 * whether the incoming value can be converted to a fluid value. 35482 * Values that already have a "clamp()" function will not pass the test, 35483 * and therefore the original $value will be returned. 35484 */ 35485 ruleValue = getTypographyFontSizeValue({ 35486 size: ruleValue 35487 }, tree?.settings); 35488 } 35489 35490 // For aspect ratio to work, other dimensions rules (and Cover block defaults) must be unset. 35491 // This ensures that a fixed height does not override the aspect ratio. 35492 if (cssProperty === 'aspect-ratio') { 35493 output.push('min-height: unset'); 35494 } 35495 output.push(`$cssProperty}: $ruleValue}`); 35496 }); 35497 return output; 35498 } 35499 35500 /** 35501 * Get generated CSS for layout styles by looking up layout definitions provided 35502 * in theme.json, and outputting common layout styles, and specific blockGap values. 35503 * 35504 * @param {Object} props 35505 * @param {Object} props.layoutDefinitions Layout definitions, keyed by layout type. 35506 * @param {Object} props.style A style object containing spacing values. 35507 * @param {string} props.selector Selector used to group together layout styling rules. 35508 * @param {boolean} props.hasBlockGapSupport Whether or not the theme opts-in to blockGap support. 35509 * @param {boolean} props.hasFallbackGapSupport Whether or not the theme allows fallback gap styles. 35510 * @param {?string} props.fallbackGapValue An optional fallback gap value if no real gap value is available. 35511 * @return {string} Generated CSS rules for the layout styles. 35512 */ 35513 function getLayoutStyles({ 35514 layoutDefinitions = LAYOUT_DEFINITIONS, 35515 style, 35516 selector, 35517 hasBlockGapSupport, 35518 hasFallbackGapSupport, 35519 fallbackGapValue 35520 }) { 35521 let ruleset = ''; 35522 let gapValue = hasBlockGapSupport ? getGapCSSValue(style?.spacing?.blockGap) : ''; 35523 35524 // Ensure a fallback gap value for the root layout definitions, 35525 // and use a fallback value if one is provided for the current block. 35526 if (hasFallbackGapSupport) { 35527 if (selector === ROOT_BLOCK_SELECTOR) { 35528 gapValue = !gapValue ? '0.5em' : gapValue; 35529 } else if (!hasBlockGapSupport && fallbackGapValue) { 35530 gapValue = fallbackGapValue; 35531 } 35532 } 35533 if (gapValue && layoutDefinitions) { 35534 Object.values(layoutDefinitions).forEach(({ 35535 className, 35536 name, 35537 spacingStyles 35538 }) => { 35539 // Allow outputting fallback gap styles for flex layout type when block gap support isn't available. 35540 if (!hasBlockGapSupport && 'flex' !== name && 'grid' !== name) { 35541 return; 35542 } 35543 if (spacingStyles?.length) { 35544 spacingStyles.forEach(spacingStyle => { 35545 const declarations = []; 35546 if (spacingStyle.rules) { 35547 Object.entries(spacingStyle.rules).forEach(([cssProperty, cssValue]) => { 35548 declarations.push(`$cssProperty}: $cssValue ? cssValue : gapValue}`); 35549 }); 35550 } 35551 if (declarations.length) { 35552 let combinedSelector = ''; 35553 if (!hasBlockGapSupport) { 35554 // For fallback gap styles, use lower specificity, to ensure styles do not unintentionally override theme styles. 35555 combinedSelector = selector === ROOT_BLOCK_SELECTOR ? `:where(.$className}$spacingStyle?.selector || ''})` : `:where($selector}.$className}$spacingStyle?.selector || ''})`; 35556 } else { 35557 combinedSelector = selector === ROOT_BLOCK_SELECTOR ? `:root :where(.$className})$spacingStyle?.selector || ''}` : `:root :where($selector}-$className})$spacingStyle?.selector || ''}`; 35558 } 35559 ruleset += `$combinedSelector} { $declarations.join('; ')}; }`; 35560 } 35561 }); 35562 } 35563 }); 35564 // For backwards compatibility, ensure the legacy block gap CSS variable is still available. 35565 if (selector === ROOT_BLOCK_SELECTOR && hasBlockGapSupport) { 35566 ruleset += `$ROOT_CSS_PROPERTIES_SELECTOR} { --wp--style--block-gap: $gapValue}; }`; 35567 } 35568 } 35569 35570 // Output base styles 35571 if (selector === ROOT_BLOCK_SELECTOR && layoutDefinitions) { 35572 const validDisplayModes = ['block', 'flex', 'grid']; 35573 Object.values(layoutDefinitions).forEach(({ 35574 className, 35575 displayMode, 35576 baseStyles 35577 }) => { 35578 if (displayMode && validDisplayModes.includes(displayMode)) { 35579 ruleset += `$selector} .$className} { display:$displayMode}; }`; 35580 } 35581 if (baseStyles?.length) { 35582 baseStyles.forEach(baseStyle => { 35583 const declarations = []; 35584 if (baseStyle.rules) { 35585 Object.entries(baseStyle.rules).forEach(([cssProperty, cssValue]) => { 35586 declarations.push(`$cssProperty}: $cssValue}`); 35587 }); 35588 } 35589 if (declarations.length) { 35590 const combinedSelector = `.$className}$baseStyle?.selector || ''}`; 35591 ruleset += `$combinedSelector} { $declarations.join('; ')}; }`; 35592 } 35593 }); 35594 } 35595 }); 35596 } 35597 return ruleset; 35598 } 35599 const STYLE_KEYS = ['border', 'color', 'dimensions', 'spacing', 'typography', 'filter', 'outline', 'shadow', 'background']; 35600 function pickStyleKeys(treeToPickFrom) { 35601 if (!treeToPickFrom) { 35602 return {}; 35603 } 35604 const entries = Object.entries(treeToPickFrom); 35605 const pickedEntries = entries.filter(([key]) => STYLE_KEYS.includes(key)); 35606 // clone the style objects so that `getFeatureDeclarations` can remove consumed keys from it 35607 const clonedEntries = pickedEntries.map(([key, style]) => [key, JSON.parse(JSON.stringify(style))]); 35608 return Object.fromEntries(clonedEntries); 35609 } 35610 const getNodesWithStyles = (tree, blockSelectors) => { 35611 var _tree$styles$blocks; 35612 const nodes = []; 35613 if (!tree?.styles) { 35614 return nodes; 35615 } 35616 35617 // Top-level. 35618 const styles = pickStyleKeys(tree.styles); 35619 if (styles) { 35620 nodes.push({ 35621 styles, 35622 selector: ROOT_BLOCK_SELECTOR, 35623 // Root selector (body) styles should not be wrapped in `:root where()` to keep 35624 // specificity at (0,0,1) and maintain backwards compatibility. 35625 skipSelectorWrapper: true 35626 }); 35627 } 35628 Object.entries(external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS).forEach(([name, selector]) => { 35629 if (tree.styles?.elements?.[name]) { 35630 nodes.push({ 35631 styles: tree.styles?.elements?.[name], 35632 selector, 35633 // Top level elements that don't use a class name should not receive the 35634 // `:root :where()` wrapper to maintain backwards compatibility. 35635 skipSelectorWrapper: !ELEMENT_CLASS_NAMES[name] 35636 }); 35637 } 35638 }); 35639 35640 // Iterate over blocks: they can have styles & elements. 35641 Object.entries((_tree$styles$blocks = tree.styles?.blocks) !== null && _tree$styles$blocks !== void 0 ? _tree$styles$blocks : {}).forEach(([blockName, node]) => { 35642 var _node$elements; 35643 const blockStyles = pickStyleKeys(node); 35644 if (node?.variations) { 35645 const variations = {}; 35646 Object.entries(node.variations).forEach(([variationName, variation]) => { 35647 var _variation$elements, _variation$blocks; 35648 variations[variationName] = pickStyleKeys(variation); 35649 if (variation?.css) { 35650 variations[variationName].css = variation.css; 35651 } 35652 const variationSelector = blockSelectors[blockName]?.styleVariationSelectors?.[variationName]; 35653 35654 // Process the variation's inner element styles. 35655 // This comes before the inner block styles so the 35656 // element styles within the block type styles take 35657 // precedence over these. 35658 Object.entries((_variation$elements = variation?.elements) !== null && _variation$elements !== void 0 ? _variation$elements : {}).forEach(([element, elementStyles]) => { 35659 if (elementStyles && external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[element]) { 35660 nodes.push({ 35661 styles: elementStyles, 35662 selector: scopeSelector(variationSelector, external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[element]) 35663 }); 35664 } 35665 }); 35666 35667 // Process the variations inner block type styles. 35668 Object.entries((_variation$blocks = variation?.blocks) !== null && _variation$blocks !== void 0 ? _variation$blocks : {}).forEach(([variationBlockName, variationBlockStyles]) => { 35669 var _variationBlockStyles; 35670 const variationBlockSelector = scopeSelector(variationSelector, blockSelectors[variationBlockName]?.selector); 35671 const variationDuotoneSelector = scopeSelector(variationSelector, blockSelectors[variationBlockName]?.duotoneSelector); 35672 const variationFeatureSelectors = scopeFeatureSelectors(variationSelector, blockSelectors[variationBlockName]?.featureSelectors); 35673 const variationBlockStyleNodes = pickStyleKeys(variationBlockStyles); 35674 if (variationBlockStyles?.css) { 35675 variationBlockStyleNodes.css = variationBlockStyles.css; 35676 } 35677 nodes.push({ 35678 selector: variationBlockSelector, 35679 duotoneSelector: variationDuotoneSelector, 35680 featureSelectors: variationFeatureSelectors, 35681 fallbackGapValue: blockSelectors[variationBlockName]?.fallbackGapValue, 35682 hasLayoutSupport: blockSelectors[variationBlockName]?.hasLayoutSupport, 35683 styles: variationBlockStyleNodes 35684 }); 35685 35686 // Process element styles for the inner blocks 35687 // of the variation. 35688 Object.entries((_variationBlockStyles = variationBlockStyles.elements) !== null && _variationBlockStyles !== void 0 ? _variationBlockStyles : {}).forEach(([variationBlockElement, variationBlockElementStyles]) => { 35689 if (variationBlockElementStyles && external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[variationBlockElement]) { 35690 nodes.push({ 35691 styles: variationBlockElementStyles, 35692 selector: scopeSelector(variationBlockSelector, external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[variationBlockElement]) 35693 }); 35694 } 35695 }); 35696 }); 35697 }); 35698 blockStyles.variations = variations; 35699 } 35700 if (blockSelectors?.[blockName]?.selector) { 35701 nodes.push({ 35702 duotoneSelector: blockSelectors[blockName].duotoneSelector, 35703 fallbackGapValue: blockSelectors[blockName].fallbackGapValue, 35704 hasLayoutSupport: blockSelectors[blockName].hasLayoutSupport, 35705 selector: blockSelectors[blockName].selector, 35706 styles: blockStyles, 35707 featureSelectors: blockSelectors[blockName].featureSelectors, 35708 styleVariationSelectors: blockSelectors[blockName].styleVariationSelectors 35709 }); 35710 } 35711 Object.entries((_node$elements = node?.elements) !== null && _node$elements !== void 0 ? _node$elements : {}).forEach(([elementName, value]) => { 35712 if (value && blockSelectors?.[blockName] && external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementName]) { 35713 nodes.push({ 35714 styles: value, 35715 selector: blockSelectors[blockName]?.selector.split(',').map(sel => { 35716 const elementSelectors = external_wp_blocks_namespaceObject.__EXPERIMENTAL_ELEMENTS[elementName].split(','); 35717 return elementSelectors.map(elementSelector => sel + ' ' + elementSelector); 35718 }).join(',') 35719 }); 35720 } 35721 }); 35722 }); 35723 return nodes; 35724 }; 35725 const getNodesWithSettings = (tree, blockSelectors) => { 35726 var _tree$settings$blocks; 35727 const nodes = []; 35728 if (!tree?.settings) { 35729 return nodes; 35730 } 35731 const pickPresets = treeToPickFrom => { 35732 let presets = {}; 35733 PRESET_METADATA.forEach(({ 35734 path 35735 }) => { 35736 const value = getValueFromObjectPath(treeToPickFrom, path, false); 35737 if (value !== false) { 35738 presets = setImmutably(presets, path, value); 35739 } 35740 }); 35741 return presets; 35742 }; 35743 35744 // Top-level. 35745 const presets = pickPresets(tree.settings); 35746 const custom = tree.settings?.custom; 35747 if (Object.keys(presets).length > 0 || custom) { 35748 nodes.push({ 35749 presets, 35750 custom, 35751 selector: ROOT_CSS_PROPERTIES_SELECTOR 35752 }); 35753 } 35754 35755 // Blocks. 35756 Object.entries((_tree$settings$blocks = tree.settings?.blocks) !== null && _tree$settings$blocks !== void 0 ? _tree$settings$blocks : {}).forEach(([blockName, node]) => { 35757 const blockPresets = pickPresets(node); 35758 const blockCustom = node.custom; 35759 if (Object.keys(blockPresets).length > 0 || blockCustom) { 35760 nodes.push({ 35761 presets: blockPresets, 35762 custom: blockCustom, 35763 selector: blockSelectors[blockName]?.selector 35764 }); 35765 } 35766 }); 35767 return nodes; 35768 }; 35769 const toCustomProperties = (tree, blockSelectors) => { 35770 const settings = getNodesWithSettings(tree, blockSelectors); 35771 let ruleset = ''; 35772 settings.forEach(({ 35773 presets, 35774 custom, 35775 selector 35776 }) => { 35777 const declarations = getPresetsDeclarations(presets, tree?.settings); 35778 const customProps = flattenTree(custom, '--wp--custom--', '--'); 35779 if (customProps.length > 0) { 35780 declarations.push(...customProps); 35781 } 35782 if (declarations.length > 0) { 35783 ruleset += `$selector}{$declarations.join(';')};}`; 35784 } 35785 }); 35786 return ruleset; 35787 }; 35788 const toStyles = (tree, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles = false, disableRootPadding = false, styleOptions = undefined) => { 35789 // These allow opting out of certain sets of styles. 35790 const options = { 35791 blockGap: true, 35792 blockStyles: true, 35793 layoutStyles: true, 35794 marginReset: true, 35795 presets: true, 35796 rootPadding: true, 35797 variationStyles: false, 35798 ...styleOptions 35799 }; 35800 const nodesWithStyles = getNodesWithStyles(tree, blockSelectors); 35801 const nodesWithSettings = getNodesWithSettings(tree, blockSelectors); 35802 const useRootPaddingAlign = tree?.settings?.useRootPaddingAwareAlignments; 35803 const { 35804 contentSize, 35805 wideSize 35806 } = tree?.settings?.layout || {}; 35807 const hasBodyStyles = options.marginReset || options.rootPadding || options.layoutStyles; 35808 let ruleset = ''; 35809 if (options.presets && (contentSize || wideSize)) { 35810 ruleset += `$ROOT_CSS_PROPERTIES_SELECTOR} {`; 35811 ruleset = contentSize ? ruleset + ` --wp--style--global--content-size: $contentSize};` : ruleset; 35812 ruleset = wideSize ? ruleset + ` --wp--style--global--wide-size: $wideSize};` : ruleset; 35813 ruleset += '}'; 35814 } 35815 if (hasBodyStyles) { 35816 /* 35817 * Reset default browser margin on the body element. 35818 * This is set on the body selector **before** generating the ruleset 35819 * from the `theme.json`. This is to ensure that if the `theme.json` declares 35820 * `margin` in its `spacing` declaration for the `body` element then these 35821 * user-generated values take precedence in the CSS cascade. 35822 * @link https://github.com/WordPress/gutenberg/issues/36147. 35823 */ 35824 ruleset += ':where(body) {margin: 0;'; 35825 35826 // Root padding styles should be output for full templates, patterns and template parts. 35827 if (options.rootPadding && useRootPaddingAlign) { 35828 /* 35829 * These rules reproduce the ones from https://github.com/WordPress/gutenberg/blob/79103f124925d1f457f627e154f52a56228ed5ad/lib/class-wp-theme-json-gutenberg.php#L2508 35830 * 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. 35831 */ 35832 ruleset += `padding-right: 0; padding-left: 0; padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom) } 35833 .has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); } 35834 .has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); } 35835 .has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) { padding-right: 0; padding-left: 0; } 35836 .has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) > .alignfull { margin-left: 0; margin-right: 0; 35837 `; 35838 } 35839 ruleset += '}'; 35840 } 35841 if (options.blockStyles) { 35842 nodesWithStyles.forEach(({ 35843 selector, 35844 duotoneSelector, 35845 styles, 35846 fallbackGapValue, 35847 hasLayoutSupport, 35848 featureSelectors, 35849 styleVariationSelectors, 35850 skipSelectorWrapper 35851 }) => { 35852 // Process styles for block support features with custom feature level 35853 // CSS selectors set. 35854 if (featureSelectors) { 35855 const featureDeclarations = getFeatureDeclarations(featureSelectors, styles); 35856 Object.entries(featureDeclarations).forEach(([cssSelector, declarations]) => { 35857 if (declarations.length) { 35858 const rules = declarations.join(';'); 35859 ruleset += `:root :where($cssSelector}){$rules};}`; 35860 } 35861 }); 35862 } 35863 35864 // Process duotone styles. 35865 if (duotoneSelector) { 35866 const duotoneStyles = {}; 35867 if (styles?.filter) { 35868 duotoneStyles.filter = styles.filter; 35869 delete styles.filter; 35870 } 35871 const duotoneDeclarations = getStylesDeclarations(duotoneStyles); 35872 if (duotoneDeclarations.length) { 35873 ruleset += `$duotoneSelector}{$duotoneDeclarations.join(';')};}`; 35874 } 35875 } 35876 35877 // Process blockGap and layout styles. 35878 if (!disableLayoutStyles && (ROOT_BLOCK_SELECTOR === selector || hasLayoutSupport)) { 35879 ruleset += getLayoutStyles({ 35880 style: styles, 35881 selector, 35882 hasBlockGapSupport, 35883 hasFallbackGapSupport, 35884 fallbackGapValue 35885 }); 35886 } 35887 35888 // Process the remaining block styles (they use either normal block class or __experimentalSelector). 35889 const styleDeclarations = getStylesDeclarations(styles, selector, useRootPaddingAlign, tree, disableRootPadding); 35890 if (styleDeclarations?.length) { 35891 const generalSelector = skipSelectorWrapper ? selector : `:root :where($selector})`; 35892 ruleset += `$generalSelector}{$styleDeclarations.join(';')};}`; 35893 } 35894 if (styles?.css) { 35895 ruleset += processCSSNesting(styles.css, `:root :where($selector})`); 35896 } 35897 if (options.variationStyles && styleVariationSelectors) { 35898 Object.entries(styleVariationSelectors).forEach(([styleVariationName, styleVariationSelector]) => { 35899 const styleVariations = styles?.variations?.[styleVariationName]; 35900 if (styleVariations) { 35901 // If the block uses any custom selectors for block support, add those first. 35902 if (featureSelectors) { 35903 const featureDeclarations = getFeatureDeclarations(featureSelectors, styleVariations); 35904 Object.entries(featureDeclarations).forEach(([baseSelector, declarations]) => { 35905 if (declarations.length) { 35906 const cssSelector = concatFeatureVariationSelectorString(baseSelector, styleVariationSelector); 35907 const rules = declarations.join(';'); 35908 ruleset += `:root :where($cssSelector}){$rules};}`; 35909 } 35910 }); 35911 } 35912 35913 // Otherwise add regular selectors. 35914 const styleVariationDeclarations = getStylesDeclarations(styleVariations, styleVariationSelector, useRootPaddingAlign, tree); 35915 if (styleVariationDeclarations.length) { 35916 ruleset += `:root :where($styleVariationSelector}){$styleVariationDeclarations.join(';')};}`; 35917 } 35918 if (styleVariations?.css) { 35919 ruleset += processCSSNesting(styleVariations.css, `:root :where($styleVariationSelector})`); 35920 } 35921 } 35922 }); 35923 } 35924 35925 // Check for pseudo selector in `styles` and handle separately. 35926 const pseudoSelectorStyles = Object.entries(styles).filter(([key]) => key.startsWith(':')); 35927 if (pseudoSelectorStyles?.length) { 35928 pseudoSelectorStyles.forEach(([pseudoKey, pseudoStyle]) => { 35929 const pseudoDeclarations = getStylesDeclarations(pseudoStyle); 35930 if (!pseudoDeclarations?.length) { 35931 return; 35932 } 35933 35934 // `selector` may be provided in a form 35935 // where block level selectors have sub element 35936 // selectors appended to them as a comma separated 35937 // string. 35938 // e.g. `h1 a,h2 a,h3 a,h4 a,h5 a,h6 a`; 35939 // Split and append pseudo selector to create 35940 // the proper rules to target the elements. 35941 const _selector = selector.split(',').map(sel => sel + pseudoKey).join(','); 35942 35943 // As pseudo classes such as :hover, :focus etc. have class-level 35944 // specificity, they must use the `:root :where()` wrapper. This. 35945 // caps the specificity at `0-1-0` to allow proper nesting of variations 35946 // and block type element styles. 35947 const pseudoRule = `:root :where($_selector}){$pseudoDeclarations.join(';')};}`; 35948 ruleset += pseudoRule; 35949 }); 35950 } 35951 }); 35952 } 35953 if (options.layoutStyles) { 35954 /* Add alignment / layout styles */ 35955 ruleset = ruleset + '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; 35956 ruleset = ruleset + '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; 35957 ruleset = ruleset + '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 35958 } 35959 if (options.blockGap && hasBlockGapSupport) { 35960 // Use fallback of `0.5em` just in case, however if there is blockGap support, there should nearly always be a real value. 35961 const gapValue = getGapCSSValue(tree?.styles?.spacing?.blockGap) || '0.5em'; 35962 ruleset = ruleset + `:root :where(.wp-site-blocks) > * { margin-block-start: $gapValue}; margin-block-end: 0; }`; 35963 ruleset = ruleset + ':root :where(.wp-site-blocks) > :first-child { margin-block-start: 0; }'; 35964 ruleset = ruleset + ':root :where(.wp-site-blocks) > :last-child { margin-block-end: 0; }'; 35965 } 35966 if (options.presets) { 35967 nodesWithSettings.forEach(({ 35968 selector, 35969 presets 35970 }) => { 35971 if (ROOT_BLOCK_SELECTOR === selector || ROOT_CSS_PROPERTIES_SELECTOR === selector) { 35972 // Do not add extra specificity for top-level classes. 35973 selector = ''; 35974 } 35975 const classes = getPresetsClasses(selector, presets); 35976 if (classes.length > 0) { 35977 ruleset += classes; 35978 } 35979 }); 35980 } 35981 return ruleset; 35982 }; 35983 function toSvgFilters(tree, blockSelectors) { 35984 const nodesWithSettings = getNodesWithSettings(tree, blockSelectors); 35985 return nodesWithSettings.flatMap(({ 35986 presets 35987 }) => { 35988 return getPresetsSvgFilters(presets); 35989 }); 35990 } 35991 const getSelectorsConfig = (blockType, rootSelector) => { 35992 if (blockType?.selectors && Object.keys(blockType.selectors).length > 0) { 35993 return blockType.selectors; 35994 } 35995 const config = { 35996 root: rootSelector 35997 }; 35998 Object.entries(BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS).forEach(([featureKey, featureName]) => { 35999 const featureSelector = getBlockCSSSelector(blockType, featureKey); 36000 if (featureSelector) { 36001 config[featureName] = featureSelector; 36002 } 36003 }); 36004 return config; 36005 }; 36006 const getBlockSelectors = (blockTypes, getBlockStyles, variationInstanceId) => { 36007 const result = {}; 36008 blockTypes.forEach(blockType => { 36009 const name = blockType.name; 36010 const selector = getBlockCSSSelector(blockType); 36011 let duotoneSelector = getBlockCSSSelector(blockType, 'filter.duotone'); 36012 36013 // Keep backwards compatibility for support.color.__experimentalDuotone. 36014 if (!duotoneSelector) { 36015 const rootSelector = getBlockCSSSelector(blockType); 36016 const duotoneSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'color.__experimentalDuotone', false); 36017 duotoneSelector = duotoneSupport && scopeSelector(rootSelector, duotoneSupport); 36018 } 36019 const hasLayoutSupport = !!blockType?.supports?.layout || !!blockType?.supports?.__experimentalLayout; 36020 const fallbackGapValue = blockType?.supports?.spacing?.blockGap?.__experimentalDefault; 36021 const blockStyleVariations = getBlockStyles(name); 36022 const styleVariationSelectors = {}; 36023 blockStyleVariations?.forEach(variation => { 36024 const variationSuffix = variationInstanceId ? `-$variationInstanceId}` : ''; 36025 const variationName = `$variation.name}$variationSuffix}`; 36026 const styleVariationSelector = getBlockStyleVariationSelector(variationName, selector); 36027 styleVariationSelectors[variationName] = styleVariationSelector; 36028 }); 36029 36030 // For each block support feature add any custom selectors. 36031 const featureSelectors = getSelectorsConfig(blockType, selector); 36032 result[name] = { 36033 duotoneSelector, 36034 fallbackGapValue, 36035 featureSelectors: Object.keys(featureSelectors).length ? featureSelectors : undefined, 36036 hasLayoutSupport, 36037 name, 36038 selector, 36039 styleVariationSelectors: blockStyleVariations?.length ? styleVariationSelectors : undefined 36040 }; 36041 }); 36042 return result; 36043 }; 36044 36045 /** 36046 * If there is a separator block whose color is defined in theme.json via background, 36047 * update the separator color to the same value by using border color. 36048 * 36049 * @param {Object} config Theme.json configuration file object. 36050 * @return {Object} configTheme.json configuration file object updated. 36051 */ 36052 function updateConfigWithSeparator(config) { 36053 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; 36054 if (needsSeparatorStyleUpdate) { 36055 return { 36056 ...config, 36057 styles: { 36058 ...config.styles, 36059 blocks: { 36060 ...config.styles.blocks, 36061 'core/separator': { 36062 ...config.styles.blocks['core/separator'], 36063 color: { 36064 ...config.styles.blocks['core/separator'].color, 36065 text: config.styles?.blocks['core/separator'].color.background 36066 } 36067 } 36068 } 36069 } 36070 }; 36071 } 36072 return config; 36073 } 36074 function processCSSNesting(css, blockSelector) { 36075 let processedCSS = ''; 36076 if (!css || css.trim() === '') { 36077 return processedCSS; 36078 } 36079 36080 // Split CSS nested rules. 36081 const parts = css.split('&'); 36082 parts.forEach(part => { 36083 if (!part || part.trim() === '') { 36084 return; 36085 } 36086 const isRootCss = !part.includes('{'); 36087 if (isRootCss) { 36088 // If the part doesn't contain braces, it applies to the root level. 36089 processedCSS += `:root :where($blockSelector}){$part.trim()}}`; 36090 } else { 36091 // If the part contains braces, it's a nested CSS rule. 36092 const splitPart = part.replace('}', '').split('{'); 36093 if (splitPart.length !== 2) { 36094 return; 36095 } 36096 const [nestedSelector, cssValue] = splitPart; 36097 36098 // Handle pseudo elements such as ::before, ::after, etc. Regex will also 36099 // capture any leading combinator such as >, +, or ~, as well as spaces. 36100 // This allows pseudo elements as descendants e.g. `.parent ::before`. 36101 const matches = nestedSelector.match(/([>+~\s]*::[a-zA-Z-]+)/); 36102 const pseudoPart = matches ? matches[1] : ''; 36103 const withoutPseudoElement = matches ? nestedSelector.replace(pseudoPart, '').trim() : nestedSelector.trim(); 36104 let combinedSelector; 36105 if (withoutPseudoElement === '') { 36106 // Only contained a pseudo element to use the block selector to form 36107 // the final `:root :where()` selector. 36108 combinedSelector = blockSelector; 36109 } else { 36110 // If the nested selector is a descendant of the block scope it with the 36111 // block selector. Otherwise append it to the block selector. 36112 combinedSelector = nestedSelector.startsWith(' ') ? scopeSelector(blockSelector, withoutPseudoElement) : appendToSelector(blockSelector, withoutPseudoElement); 36113 } 36114 36115 // Build final rule, re-adding any pseudo element outside the `:where()` 36116 // to maintain valid CSS selector. 36117 processedCSS += `:root :where($combinedSelector})$pseudoPart}{$cssValue.trim()}}`; 36118 } 36119 }); 36120 return processedCSS; 36121 } 36122 36123 /** 36124 * Returns the global styles output using a global styles configuration. 36125 * If wishing to generate global styles and settings based on the 36126 * global styles config loaded in the editor context, use `useGlobalStylesOutput()`. 36127 * The use case for a custom config is to generate bespoke styles 36128 * and settings for previews, or other out-of-editor experiences. 36129 * 36130 * @param {Object} mergedConfig Global styles configuration. 36131 * @param {boolean} disableRootPadding Disable root padding styles. 36132 * 36133 * @return {Array} Array of stylesheets and settings. 36134 */ 36135 function useGlobalStylesOutputWithConfig(mergedConfig = {}, disableRootPadding) { 36136 const [blockGap] = useGlobalSetting('spacing.blockGap'); 36137 const hasBlockGapSupport = blockGap !== null; 36138 const hasFallbackGapSupport = !hasBlockGapSupport; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback styles support. 36139 const disableLayoutStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 36140 const { 36141 getSettings 36142 } = select(store); 36143 return !!getSettings().disableLayoutStyles; 36144 }); 36145 const { 36146 getBlockStyles 36147 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 36148 return (0,external_wp_element_namespaceObject.useMemo)(() => { 36149 var _updatedConfig$styles; 36150 if (!mergedConfig?.styles || !mergedConfig?.settings) { 36151 return []; 36152 } 36153 const updatedConfig = updateConfigWithSeparator(mergedConfig); 36154 const blockSelectors = getBlockSelectors((0,external_wp_blocks_namespaceObject.getBlockTypes)(), getBlockStyles); 36155 const customProperties = toCustomProperties(updatedConfig, blockSelectors); 36156 const globalStyles = toStyles(updatedConfig, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles, disableRootPadding); 36157 const svgs = toSvgFilters(updatedConfig, blockSelectors); 36158 const styles = [{ 36159 css: customProperties, 36160 isGlobalStyles: true 36161 }, { 36162 css: globalStyles, 36163 isGlobalStyles: true 36164 }, 36165 // 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. 36166 { 36167 css: (_updatedConfig$styles = updatedConfig.styles.css) !== null && _updatedConfig$styles !== void 0 ? _updatedConfig$styles : '', 36168 isGlobalStyles: true 36169 }, { 36170 assets: svgs, 36171 __unstableType: 'svg', 36172 isGlobalStyles: true 36173 }]; 36174 36175 // Loop through the blocks to check if there are custom CSS values. 36176 // If there are, get the block selector and push the selector together with 36177 // the CSS value to the 'stylesheets' array. 36178 (0,external_wp_blocks_namespaceObject.getBlockTypes)().forEach(blockType => { 36179 if (updatedConfig.styles.blocks[blockType.name]?.css) { 36180 const selector = blockSelectors[blockType.name].selector; 36181 styles.push({ 36182 css: processCSSNesting(updatedConfig.styles.blocks[blockType.name]?.css, selector), 36183 isGlobalStyles: true 36184 }); 36185 } 36186 }); 36187 return [styles, updatedConfig.settings]; 36188 }, [hasBlockGapSupport, hasFallbackGapSupport, mergedConfig, disableLayoutStyles, disableRootPadding, getBlockStyles]); 36189 } 36190 36191 /** 36192 * Returns the global styles output based on the current state of global styles config loaded in the editor context. 36193 * 36194 * @param {boolean} disableRootPadding Disable root padding styles. 36195 * 36196 * @return {Array} Array of stylesheets and settings. 36197 */ 36198 function useGlobalStylesOutput(disableRootPadding = false) { 36199 const { 36200 merged: mergedConfig 36201 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 36202 return useGlobalStylesOutputWithConfig(mergedConfig, disableRootPadding); 36203 } 36204 36205 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/block-style-variation.js 36206 /** 36207 * WordPress dependencies 36208 */ 36209 36210 36211 36212 36213 /** 36214 * Internal dependencies 36215 */ 36216 36217 36218 36219 36220 36221 36222 36223 const VARIATION_PREFIX = 'is-style-'; 36224 function getVariationMatches(className) { 36225 if (!className) { 36226 return []; 36227 } 36228 return className.split(/\s+/).reduce((matches, name) => { 36229 if (name.startsWith(VARIATION_PREFIX)) { 36230 const match = name.slice(VARIATION_PREFIX.length); 36231 if (match !== 'default') { 36232 matches.push(match); 36233 } 36234 } 36235 return matches; 36236 }, []); 36237 } 36238 36239 /** 36240 * Get the first block style variation that has been registered from the class string. 36241 * 36242 * @param {string} className CSS class string for a block. 36243 * @param {Array} registeredStyles Currently registered block styles. 36244 * 36245 * @return {string|null} The name of the first registered variation. 36246 */ 36247 function getVariationNameFromClass(className, registeredStyles = []) { 36248 // The global flag affects how capturing groups work in JS. So the regex 36249 // below will only return full CSS classes not just the variation name. 36250 const matches = getVariationMatches(className); 36251 if (!matches) { 36252 return null; 36253 } 36254 for (const variation of matches) { 36255 if (registeredStyles.some(style => style.name === variation)) { 36256 return variation; 36257 } 36258 } 36259 return null; 36260 } 36261 36262 // A helper component to apply a style override using the useStyleOverride hook. 36263 function OverrideStyles({ 36264 override 36265 }) { 36266 usePrivateStyleOverride(override); 36267 } 36268 36269 /** 36270 * This component is used to generate new block style variation overrides 36271 * based on an incoming theme config. If a matching style is found in the config, 36272 * a new override is created and returned. The overrides can be used in conjunction with 36273 * useStyleOverride to apply the new styles to the editor. Its use is 36274 * subject to change. 36275 * 36276 * @param {Object} props Props. 36277 * @param {Object} props.config A global styles object, containing settings and styles. 36278 * @return {JSX.Element|undefined} An array of new block variation overrides. 36279 */ 36280 function __unstableBlockStyleVariationOverridesWithConfig({ 36281 config 36282 }) { 36283 const { 36284 getBlockStyles, 36285 overrides 36286 } = (0,external_wp_data_namespaceObject.useSelect)(select => ({ 36287 getBlockStyles: select(external_wp_blocks_namespaceObject.store).getBlockStyles, 36288 overrides: unlock(select(store)).getStyleOverrides() 36289 }), []); 36290 const { 36291 getBlockName 36292 } = (0,external_wp_data_namespaceObject.useSelect)(store); 36293 const overridesWithConfig = (0,external_wp_element_namespaceObject.useMemo)(() => { 36294 if (!overrides?.length) { 36295 return; 36296 } 36297 const newOverrides = []; 36298 const overriddenClientIds = []; 36299 for (const [, override] of overrides) { 36300 if (override?.variation && override?.clientId && 36301 /* 36302 * Because this component overwrites existing style overrides, 36303 * filter out any overrides that are already present in the store. 36304 */ 36305 !overriddenClientIds.includes(override.clientId)) { 36306 const blockName = getBlockName(override.clientId); 36307 const configStyles = config?.styles?.blocks?.[blockName]?.variations?.[override.variation]; 36308 if (configStyles) { 36309 const variationConfig = { 36310 settings: config?.settings, 36311 // The variation style data is all that is needed to generate 36312 // the styles for the current application to a block. The variation 36313 // name is updated to match the instance specific class name. 36314 styles: { 36315 blocks: { 36316 [blockName]: { 36317 variations: { 36318 [`$override.variation}-$override.clientId}`]: configStyles 36319 } 36320 } 36321 } 36322 } 36323 }; 36324 const blockSelectors = getBlockSelectors((0,external_wp_blocks_namespaceObject.getBlockTypes)(), getBlockStyles, override.clientId); 36325 const hasBlockGapSupport = false; 36326 const hasFallbackGapSupport = true; 36327 const disableLayoutStyles = true; 36328 const disableRootPadding = true; 36329 const variationStyles = toStyles(variationConfig, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles, disableRootPadding, { 36330 blockGap: false, 36331 blockStyles: true, 36332 layoutStyles: false, 36333 marginReset: false, 36334 presets: false, 36335 rootPadding: false, 36336 variationStyles: true 36337 }); 36338 newOverrides.push({ 36339 id: `$override.variation}-$override.clientId}`, 36340 css: variationStyles, 36341 __unstableType: 'variation', 36342 variation: override.variation, 36343 // The clientId will be stored with the override and used to ensure 36344 // the order of overrides matches the order of blocks so that the 36345 // correct CSS cascade is maintained. 36346 clientId: override.clientId 36347 }); 36348 overriddenClientIds.push(override.clientId); 36349 } 36350 } 36351 } 36352 return newOverrides; 36353 }, [config, overrides, getBlockStyles, getBlockName]); 36354 if (!overridesWithConfig || !overridesWithConfig.length) { 36355 return; 36356 } 36357 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 36358 children: overridesWithConfig.map(override => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(OverrideStyles, { 36359 override: override 36360 }, override.id)) 36361 }); 36362 } 36363 36364 /** 36365 * Retrieves any variation styles data and resolves any referenced values. 36366 * 36367 * @param {Object} globalStyles A complete global styles object, containing settings and styles. 36368 * @param {string} name The name of the desired block type. 36369 * @param {variation} variation The of the block style variation to retrieve data for. 36370 * 36371 * @return {Object|undefined} The global styles data for the specified variation. 36372 */ 36373 function getVariationStylesWithRefValues(globalStyles, name, variation) { 36374 if (!globalStyles?.styles?.blocks?.[name]?.variations?.[variation]) { 36375 return; 36376 } 36377 36378 // Helper to recursively look for `ref` values to resolve. 36379 const replaceRefs = variationStyles => { 36380 Object.keys(variationStyles).forEach(key => { 36381 const value = variationStyles[key]; 36382 36383 // Only process objects. 36384 if (typeof value === 'object' && value !== null) { 36385 // Process `ref` value if present. 36386 if (value.ref !== undefined) { 36387 if (typeof value.ref !== 'string' || value.ref.trim() === '') { 36388 // Remove invalid ref. 36389 delete variationStyles[key]; 36390 } else { 36391 // Resolve `ref` value. 36392 const refValue = getValueFromObjectPath(globalStyles, value.ref); 36393 if (refValue) { 36394 variationStyles[key] = refValue; 36395 } else { 36396 delete variationStyles[key]; 36397 } 36398 } 36399 } else { 36400 // Recursively resolve `ref` values in nested objects. 36401 replaceRefs(value); 36402 36403 // After recursion, if value is empty due to explicitly 36404 // `undefined` ref value, remove it. 36405 if (Object.keys(value).length === 0) { 36406 delete variationStyles[key]; 36407 } 36408 } 36409 } 36410 }); 36411 }; 36412 36413 // Deep clone variation node to avoid mutating it within global styles and losing refs. 36414 const styles = JSON.parse(JSON.stringify(globalStyles.styles.blocks[name].variations[variation])); 36415 replaceRefs(styles); 36416 return styles; 36417 } 36418 function useBlockStyleVariation(name, variation, clientId) { 36419 // Prefer global styles data in GlobalStylesContext, which are available 36420 // if in the site editor. Otherwise fall back to whatever is in the 36421 // editor settings and available in the post editor. 36422 const { 36423 merged: mergedConfig 36424 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 36425 const { 36426 globalSettings, 36427 globalStyles 36428 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 36429 const settings = select(store).getSettings(); 36430 return { 36431 globalSettings: settings.__experimentalFeatures, 36432 globalStyles: settings[globalStylesDataKey] 36433 }; 36434 }, []); 36435 return (0,external_wp_element_namespaceObject.useMemo)(() => { 36436 var _mergedConfig$setting, _mergedConfig$styles, _mergedConfig$setting2; 36437 const variationStyles = getVariationStylesWithRefValues({ 36438 settings: (_mergedConfig$setting = mergedConfig?.settings) !== null && _mergedConfig$setting !== void 0 ? _mergedConfig$setting : globalSettings, 36439 styles: (_mergedConfig$styles = mergedConfig?.styles) !== null && _mergedConfig$styles !== void 0 ? _mergedConfig$styles : globalStyles 36440 }, name, variation); 36441 return { 36442 settings: (_mergedConfig$setting2 = mergedConfig?.settings) !== null && _mergedConfig$setting2 !== void 0 ? _mergedConfig$setting2 : globalSettings, 36443 // The variation style data is all that is needed to generate 36444 // the styles for the current application to a block. The variation 36445 // name is updated to match the instance specific class name. 36446 styles: { 36447 blocks: { 36448 [name]: { 36449 variations: { 36450 [`$variation}-$clientId}`]: variationStyles 36451 } 36452 } 36453 } 36454 } 36455 }; 36456 }, [mergedConfig, globalSettings, globalStyles, variation, clientId, name]); 36457 } 36458 36459 // Rather than leveraging `useInstanceId` here, the `clientId` is used. 36460 // This is so that the variation style override's ID is predictable 36461 // when the order of applied style variations changes. 36462 function block_style_variation_useBlockProps({ 36463 name, 36464 className, 36465 clientId 36466 }) { 36467 const { 36468 getBlockStyles 36469 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 36470 const registeredStyles = getBlockStyles(name); 36471 const variation = getVariationNameFromClass(className, registeredStyles); 36472 const variationClass = `$VARIATION_PREFIX}$variation}-$clientId}`; 36473 const { 36474 settings, 36475 styles 36476 } = useBlockStyleVariation(name, variation, clientId); 36477 const variationStyles = (0,external_wp_element_namespaceObject.useMemo)(() => { 36478 if (!variation) { 36479 return; 36480 } 36481 const variationConfig = { 36482 settings, 36483 styles 36484 }; 36485 const blockSelectors = getBlockSelectors((0,external_wp_blocks_namespaceObject.getBlockTypes)(), getBlockStyles, clientId); 36486 const hasBlockGapSupport = false; 36487 const hasFallbackGapSupport = true; 36488 const disableLayoutStyles = true; 36489 const disableRootPadding = true; 36490 return toStyles(variationConfig, blockSelectors, hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles, disableRootPadding, { 36491 blockGap: false, 36492 blockStyles: true, 36493 layoutStyles: false, 36494 marginReset: false, 36495 presets: false, 36496 rootPadding: false, 36497 variationStyles: true 36498 }); 36499 }, [variation, settings, styles, getBlockStyles, clientId]); 36500 usePrivateStyleOverride({ 36501 id: `variation-$clientId}`, 36502 css: variationStyles, 36503 __unstableType: 'variation', 36504 variation, 36505 // The clientId will be stored with the override and used to ensure 36506 // the order of overrides matches the order of blocks so that the 36507 // correct CSS cascade is maintained. 36508 clientId 36509 }); 36510 return variation ? { 36511 className: variationClass 36512 } : {}; 36513 } 36514 /* harmony default export */ const block_style_variation = ({ 36515 hasSupport: () => true, 36516 attributeKeys: ['className'], 36517 isMatch: ({ 36518 className 36519 }) => getVariationMatches(className).length > 0, 36520 useBlockProps: block_style_variation_useBlockProps 36521 }); 36522 36523 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/layout.js 36524 /** 36525 * External dependencies 36526 */ 36527 36528 36529 /** 36530 * WordPress dependencies 36531 */ 36532 36533 36534 36535 36536 36537 36538 36539 /** 36540 * Internal dependencies 36541 */ 36542 36543 36544 36545 36546 36547 36548 36549 36550 36551 const layoutBlockSupportKey = 'layout'; 36552 const { 36553 kebabCase: layout_kebabCase 36554 } = unlock(external_wp_components_namespaceObject.privateApis); 36555 function hasLayoutBlockSupport(blockName) { 36556 return (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'layout') || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, '__experimentalLayout'); 36557 } 36558 36559 /** 36560 * Generates the utility classnames for the given block's layout attributes. 36561 * 36562 * @param { Object } blockAttributes Block attributes. 36563 * @param { string } blockName Block name. 36564 * 36565 * @return { Array } Array of CSS classname strings. 36566 */ 36567 function useLayoutClasses(blockAttributes = {}, blockName = '') { 36568 const { 36569 layout 36570 } = blockAttributes; 36571 const { 36572 default: defaultBlockLayout 36573 } = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, layoutBlockSupportKey) || {}; 36574 const usedLayout = layout?.inherit || layout?.contentSize || layout?.wideSize ? { 36575 ...layout, 36576 type: 'constrained' 36577 } : layout || defaultBlockLayout || {}; 36578 const layoutClassnames = []; 36579 if (LAYOUT_DEFINITIONS[usedLayout?.type || 'default']?.className) { 36580 const baseClassName = LAYOUT_DEFINITIONS[usedLayout?.type || 'default']?.className; 36581 const splitBlockName = blockName.split('/'); 36582 const fullBlockName = splitBlockName[0] === 'core' ? splitBlockName.pop() : splitBlockName.join('-'); 36583 const compoundClassName = `wp-block-$fullBlockName}-$baseClassName}`; 36584 layoutClassnames.push(baseClassName, compoundClassName); 36585 } 36586 const hasGlobalPadding = (0,external_wp_data_namespaceObject.useSelect)(select => { 36587 return (usedLayout?.inherit || usedLayout?.contentSize || usedLayout?.type === 'constrained') && select(store).getSettings().__experimentalFeatures?.useRootPaddingAwareAlignments; 36588 }, [usedLayout?.contentSize, usedLayout?.inherit, usedLayout?.type]); 36589 if (hasGlobalPadding) { 36590 layoutClassnames.push('has-global-padding'); 36591 } 36592 if (usedLayout?.orientation) { 36593 layoutClassnames.push(`is-$layout_kebabCase(usedLayout.orientation)}`); 36594 } 36595 if (usedLayout?.justifyContent) { 36596 layoutClassnames.push(`is-content-justification-$layout_kebabCase(usedLayout.justifyContent)}`); 36597 } 36598 if (usedLayout?.flexWrap && usedLayout.flexWrap === 'nowrap') { 36599 layoutClassnames.push('is-nowrap'); 36600 } 36601 return layoutClassnames; 36602 } 36603 36604 /** 36605 * Generates a CSS rule with the given block's layout styles. 36606 * 36607 * @param { Object } blockAttributes Block attributes. 36608 * @param { string } blockName Block name. 36609 * @param { string } selector A selector to use in generating the CSS rule. 36610 * 36611 * @return { string } CSS rule. 36612 */ 36613 function useLayoutStyles(blockAttributes = {}, blockName, selector) { 36614 const { 36615 layout = {}, 36616 style = {} 36617 } = blockAttributes; 36618 // Update type for blocks using legacy layouts. 36619 const usedLayout = layout?.inherit || layout?.contentSize || layout?.wideSize ? { 36620 ...layout, 36621 type: 'constrained' 36622 } : layout || {}; 36623 const fullLayoutType = getLayoutType(usedLayout?.type || 'default'); 36624 const [blockGapSupport] = use_settings_useSettings('spacing.blockGap'); 36625 const hasBlockGapSupport = blockGapSupport !== null; 36626 return fullLayoutType?.getLayoutStyle?.({ 36627 blockName, 36628 selector, 36629 layout, 36630 style, 36631 hasBlockGapSupport 36632 }); 36633 } 36634 function LayoutPanelPure({ 36635 layout, 36636 setAttributes, 36637 name: blockName, 36638 clientId 36639 }) { 36640 const settings = useBlockSettings(blockName); 36641 // Block settings come from theme.json under settings.[blockName]. 36642 const { 36643 layout: layoutSettings 36644 } = settings; 36645 const { 36646 themeSupportsLayout 36647 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 36648 const { 36649 getSettings 36650 } = select(store); 36651 return { 36652 themeSupportsLayout: getSettings().supportsLayout 36653 }; 36654 }, []); 36655 const blockEditingMode = useBlockEditingMode(); 36656 if (blockEditingMode !== 'default') { 36657 return null; 36658 } 36659 36660 // Layout block support comes from the block's block.json. 36661 const layoutBlockSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, layoutBlockSupportKey, {}); 36662 const blockSupportAndThemeSettings = { 36663 ...layoutSettings, 36664 ...layoutBlockSupport 36665 }; 36666 const { 36667 allowSwitching, 36668 allowEditing = true, 36669 allowInheriting = true, 36670 default: defaultBlockLayout 36671 } = blockSupportAndThemeSettings; 36672 if (!allowEditing) { 36673 return null; 36674 } 36675 36676 /* 36677 * Try to find the layout type from either the 36678 * block's layout settings or any saved layout config. 36679 */ 36680 const blockSupportAndLayout = { 36681 ...layoutBlockSupport, 36682 ...layout 36683 }; 36684 const { 36685 type, 36686 default: { 36687 type: defaultType = 'default' 36688 } = {} 36689 } = blockSupportAndLayout; 36690 const blockLayoutType = type || defaultType; 36691 36692 // Only show the inherit toggle if it's supported, 36693 // and either the default / flow or the constrained layout type is in use, as the toggle switches from one to the other. 36694 const showInheritToggle = !!(allowInheriting && (!blockLayoutType || blockLayoutType === 'default' || blockLayoutType === 'constrained' || blockSupportAndLayout.inherit)); 36695 const usedLayout = layout || defaultBlockLayout || {}; 36696 const { 36697 inherit = false, 36698 contentSize = null 36699 } = usedLayout; 36700 /** 36701 * `themeSupportsLayout` is only relevant to the `default/flow` or 36702 * `constrained` layouts and it should not be taken into account when other 36703 * `layout` types are used. 36704 */ 36705 if ((blockLayoutType === 'default' || blockLayoutType === 'constrained') && !themeSupportsLayout) { 36706 return null; 36707 } 36708 const layoutType = getLayoutType(blockLayoutType); 36709 const constrainedType = getLayoutType('constrained'); 36710 const displayControlsForLegacyLayouts = !usedLayout.type && (contentSize || inherit); 36711 const hasContentSizeOrLegacySettings = !!inherit || !!contentSize; 36712 const onChangeType = newType => setAttributes({ 36713 layout: { 36714 type: newType 36715 } 36716 }); 36717 const onChangeLayout = newLayout => setAttributes({ 36718 layout: newLayout 36719 }); 36720 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 36721 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 36722 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.PanelBody, { 36723 title: (0,external_wp_i18n_namespaceObject.__)('Layout'), 36724 children: [showInheritToggle && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 36725 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 36726 __nextHasNoMarginBottom: true, 36727 label: (0,external_wp_i18n_namespaceObject.__)('Inner blocks use content width'), 36728 checked: layoutType?.name === 'constrained' || hasContentSizeOrLegacySettings, 36729 onChange: () => setAttributes({ 36730 layout: { 36731 type: layoutType?.name === 'constrained' || hasContentSizeOrLegacySettings ? 'default' : 'constrained' 36732 } 36733 }), 36734 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.') 36735 }) 36736 }), !inherit && allowSwitching && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LayoutTypeSwitcher, { 36737 type: blockLayoutType, 36738 onChange: onChangeType 36739 }), layoutType && layoutType.name !== 'default' && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(layoutType.inspectorControls, { 36740 layout: usedLayout, 36741 onChange: onChangeLayout, 36742 layoutBlockSupport: blockSupportAndThemeSettings, 36743 name: blockName, 36744 clientId: clientId 36745 }), constrainedType && displayControlsForLegacyLayouts && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(constrainedType.inspectorControls, { 36746 layout: usedLayout, 36747 onChange: onChangeLayout, 36748 layoutBlockSupport: blockSupportAndThemeSettings, 36749 name: blockName, 36750 clientId: clientId 36751 })] 36752 }) 36753 }), !inherit && layoutType && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(layoutType.toolBarControls, { 36754 layout: usedLayout, 36755 onChange: onChangeLayout, 36756 layoutBlockSupport: layoutBlockSupport, 36757 name: blockName, 36758 clientId: clientId 36759 })] 36760 }); 36761 } 36762 /* harmony default export */ const layout = ({ 36763 shareWithChildBlocks: true, 36764 edit: LayoutPanelPure, 36765 attributeKeys: ['layout'], 36766 hasSupport(name) { 36767 return hasLayoutBlockSupport(name); 36768 } 36769 }); 36770 function LayoutTypeSwitcher({ 36771 type, 36772 onChange 36773 }) { 36774 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 36775 __next40pxDefaultSize: true, 36776 isBlock: true, 36777 label: (0,external_wp_i18n_namespaceObject.__)('Layout type'), 36778 __nextHasNoMarginBottom: true, 36779 hideLabelFromVision: true, 36780 isAdaptiveWidth: true, 36781 value: type, 36782 onChange: onChange, 36783 children: getLayoutTypes().map(({ 36784 name, 36785 label 36786 }) => { 36787 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 36788 value: name, 36789 label: label 36790 }, name); 36791 }) 36792 }); 36793 } 36794 36795 /** 36796 * Filters registered block settings, extending attributes to include `layout`. 36797 * 36798 * @param {Object} settings Original block settings. 36799 * 36800 * @return {Object} Filtered block settings. 36801 */ 36802 function layout_addAttribute(settings) { 36803 var _settings$attributes$; 36804 if ('type' in ((_settings$attributes$ = settings.attributes?.layout) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) { 36805 return settings; 36806 } 36807 if (hasLayoutBlockSupport(settings)) { 36808 settings.attributes = { 36809 ...settings.attributes, 36810 layout: { 36811 type: 'object' 36812 } 36813 }; 36814 } 36815 return settings; 36816 } 36817 function BlockWithLayoutStyles({ 36818 block: BlockListBlock, 36819 props, 36820 blockGapSupport, 36821 layoutClasses 36822 }) { 36823 const { 36824 name, 36825 attributes 36826 } = props; 36827 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockListBlock); 36828 const { 36829 layout 36830 } = attributes; 36831 const { 36832 default: defaultBlockLayout 36833 } = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, layoutBlockSupportKey) || {}; 36834 const usedLayout = layout?.inherit || layout?.contentSize || layout?.wideSize ? { 36835 ...layout, 36836 type: 'constrained' 36837 } : layout || defaultBlockLayout || {}; 36838 const selectorPrefix = `wp-container-$layout_kebabCase(name)}-is-layout-`; 36839 // Higher specificity to override defaults from theme.json. 36840 const selector = `.$selectorPrefix}$id}`; 36841 const hasBlockGapSupport = blockGapSupport !== null; 36842 36843 // Get CSS string for the current layout type. 36844 // The CSS and `style` element is only output if it is not empty. 36845 const fullLayoutType = getLayoutType(usedLayout?.type || 'default'); 36846 const css = fullLayoutType?.getLayoutStyle?.({ 36847 blockName: name, 36848 selector, 36849 layout: usedLayout, 36850 style: attributes?.style, 36851 hasBlockGapSupport 36852 }); 36853 36854 // Attach a `wp-container-` id-based class name as well as a layout class name such as `is-layout-flex`. 36855 const layoutClassNames = dist_clsx({ 36856 [`$selectorPrefix}$id}`]: !!css // Only attach a container class if there is generated CSS to be attached. 36857 }, layoutClasses); 36858 useStyleOverride({ 36859 css 36860 }); 36861 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListBlock, { 36862 ...props, 36863 __unstableLayoutClassNames: layoutClassNames 36864 }); 36865 } 36866 36867 /** 36868 * Override the default block element to add the layout styles. 36869 * 36870 * @param {Function} BlockListBlock Original component. 36871 * 36872 * @return {Function} Wrapped component. 36873 */ 36874 const withLayoutStyles = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockListBlock => props => { 36875 const { 36876 clientId, 36877 name, 36878 attributes 36879 } = props; 36880 const blockSupportsLayout = hasLayoutBlockSupport(name); 36881 const layoutClasses = useLayoutClasses(attributes, name); 36882 const extraProps = (0,external_wp_data_namespaceObject.useSelect)(select => { 36883 // The callback returns early to avoid block editor subscription. 36884 if (!blockSupportsLayout) { 36885 return; 36886 } 36887 const { 36888 getSettings, 36889 getBlockSettings 36890 } = unlock(select(store)); 36891 const { 36892 disableLayoutStyles 36893 } = getSettings(); 36894 if (disableLayoutStyles) { 36895 return; 36896 } 36897 const [blockGapSupport] = getBlockSettings(clientId, 'spacing.blockGap'); 36898 return { 36899 blockGapSupport 36900 }; 36901 }, [blockSupportsLayout, clientId]); 36902 if (!extraProps) { 36903 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListBlock, { 36904 ...props, 36905 __unstableLayoutClassNames: blockSupportsLayout ? layoutClasses : undefined 36906 }); 36907 } 36908 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockWithLayoutStyles, { 36909 block: BlockListBlock, 36910 props: props, 36911 layoutClasses: layoutClasses, 36912 ...extraProps 36913 }); 36914 }, 'withLayoutStyles'); 36915 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/layout/addAttribute', layout_addAttribute); 36916 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockListBlock', 'core/editor/layout/with-layout-styles', withLayoutStyles); 36917 36918 ;// ./node_modules/@wordpress/block-editor/build-module/components/grid/utils.js 36919 function range(start, length) { 36920 return Array.from({ 36921 length 36922 }, (_, i) => start + i); 36923 } 36924 class GridRect { 36925 constructor({ 36926 columnStart, 36927 rowStart, 36928 columnEnd, 36929 rowEnd, 36930 columnSpan, 36931 rowSpan 36932 } = {}) { 36933 this.columnStart = columnStart !== null && columnStart !== void 0 ? columnStart : 1; 36934 this.rowStart = rowStart !== null && rowStart !== void 0 ? rowStart : 1; 36935 if (columnSpan !== undefined) { 36936 this.columnEnd = this.columnStart + columnSpan - 1; 36937 } else { 36938 this.columnEnd = columnEnd !== null && columnEnd !== void 0 ? columnEnd : this.columnStart; 36939 } 36940 if (rowSpan !== undefined) { 36941 this.rowEnd = this.rowStart + rowSpan - 1; 36942 } else { 36943 this.rowEnd = rowEnd !== null && rowEnd !== void 0 ? rowEnd : this.rowStart; 36944 } 36945 } 36946 get columnSpan() { 36947 return this.columnEnd - this.columnStart + 1; 36948 } 36949 get rowSpan() { 36950 return this.rowEnd - this.rowStart + 1; 36951 } 36952 contains(column, row) { 36953 return column >= this.columnStart && column <= this.columnEnd && row >= this.rowStart && row <= this.rowEnd; 36954 } 36955 containsRect(rect) { 36956 return this.contains(rect.columnStart, rect.rowStart) && this.contains(rect.columnEnd, rect.rowEnd); 36957 } 36958 intersectsRect(rect) { 36959 return this.columnStart <= rect.columnEnd && this.columnEnd >= rect.columnStart && this.rowStart <= rect.rowEnd && this.rowEnd >= rect.rowStart; 36960 } 36961 } 36962 function utils_getComputedCSS(element, property) { 36963 return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue(property); 36964 } 36965 36966 /** 36967 * Given a grid-template-columns or grid-template-rows CSS property value, gets the start and end 36968 * position in pixels of each grid track. 36969 * 36970 * https://css-tricks.com/snippets/css/complete-guide-grid/#aa-grid-track 36971 * 36972 * @param {string} template The grid-template-columns or grid-template-rows CSS property value. 36973 * Only supports fixed sizes in pixels. 36974 * @param {number} gap The gap between grid tracks in pixels. 36975 * 36976 * @return {Array<{start: number, end: number}>} An array of objects with the start and end 36977 * position in pixels of each grid track. 36978 */ 36979 function getGridTracks(template, gap) { 36980 const tracks = []; 36981 for (const size of template.split(' ')) { 36982 const previousTrack = tracks[tracks.length - 1]; 36983 const start = previousTrack ? previousTrack.end + gap : 0; 36984 const end = start + parseFloat(size); 36985 tracks.push({ 36986 start, 36987 end 36988 }); 36989 } 36990 return tracks; 36991 } 36992 36993 /** 36994 * Given an array of grid tracks and a position in pixels, gets the index of the closest track to 36995 * that position. 36996 * 36997 * https://css-tricks.com/snippets/css/complete-guide-grid/#aa-grid-track 36998 * 36999 * @param {Array<{start: number, end: number}>} tracks An array of objects with the start and end 37000 * position in pixels of each grid track. 37001 * @param {number} position The position in pixels. 37002 * @param {string} edge The edge of the track to compare the 37003 * position to. Either 'start' or 'end'. 37004 * 37005 * @return {number} The index of the closest track to the position. 0-based, unlike CSS grid which 37006 * is 1-based. 37007 */ 37008 function getClosestTrack(tracks, position, edge = 'start') { 37009 return tracks.reduce((closest, track, index) => Math.abs(track[edge] - position) < Math.abs(tracks[closest][edge] - position) ? index : closest, 0); 37010 } 37011 function getGridRect(gridElement, rect) { 37012 const columnGap = parseFloat(utils_getComputedCSS(gridElement, 'column-gap')); 37013 const rowGap = parseFloat(utils_getComputedCSS(gridElement, 'row-gap')); 37014 const gridColumnTracks = getGridTracks(utils_getComputedCSS(gridElement, 'grid-template-columns'), columnGap); 37015 const gridRowTracks = getGridTracks(utils_getComputedCSS(gridElement, 'grid-template-rows'), rowGap); 37016 const columnStart = getClosestTrack(gridColumnTracks, rect.left) + 1; 37017 const rowStart = getClosestTrack(gridRowTracks, rect.top) + 1; 37018 const columnEnd = getClosestTrack(gridColumnTracks, rect.right, 'end') + 1; 37019 const rowEnd = getClosestTrack(gridRowTracks, rect.bottom, 'end') + 1; 37020 return new GridRect({ 37021 columnStart, 37022 columnEnd, 37023 rowStart, 37024 rowEnd 37025 }); 37026 } 37027 function getGridItemRect(gridItemElement) { 37028 return getGridRect(gridItemElement.parentElement, new window.DOMRect(gridItemElement.offsetLeft, gridItemElement.offsetTop, gridItemElement.offsetWidth, gridItemElement.offsetHeight)); 37029 } 37030 function getGridInfo(gridElement) { 37031 const gridTemplateColumns = utils_getComputedCSS(gridElement, 'grid-template-columns'); 37032 const gridTemplateRows = utils_getComputedCSS(gridElement, 'grid-template-rows'); 37033 const borderTopWidth = utils_getComputedCSS(gridElement, 'border-top-width'); 37034 const borderRightWidth = utils_getComputedCSS(gridElement, 'border-right-width'); 37035 const borderBottomWidth = utils_getComputedCSS(gridElement, 'border-bottom-width'); 37036 const borderLeftWidth = utils_getComputedCSS(gridElement, 'border-left-width'); 37037 const paddingTop = utils_getComputedCSS(gridElement, 'padding-top'); 37038 const paddingRight = utils_getComputedCSS(gridElement, 'padding-right'); 37039 const paddingBottom = utils_getComputedCSS(gridElement, 'padding-bottom'); 37040 const paddingLeft = utils_getComputedCSS(gridElement, 'padding-left'); 37041 const numColumns = gridTemplateColumns.split(' ').length; 37042 const numRows = gridTemplateRows.split(' ').length; 37043 const numItems = numColumns * numRows; 37044 return { 37045 numColumns, 37046 numRows, 37047 numItems, 37048 currentColor: utils_getComputedCSS(gridElement, 'color'), 37049 style: { 37050 gridTemplateColumns, 37051 gridTemplateRows, 37052 gap: utils_getComputedCSS(gridElement, 'gap'), 37053 inset: ` 37054 calc($paddingTop} + $borderTopWidth}) 37055 calc($paddingRight} + $borderRightWidth}) 37056 calc($paddingBottom} + $borderBottomWidth}) 37057 calc($paddingLeft} + $borderLeftWidth}) 37058 ` 37059 } 37060 }; 37061 } 37062 37063 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/tips.js 37064 /** 37065 * WordPress dependencies 37066 */ 37067 37068 37069 37070 37071 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.'), { 37072 kbd: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("kbd", {}) 37073 }), (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.'), { 37074 kbd: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("kbd", {}) 37075 }), (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.'), { 37076 kbd: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("kbd", {}) 37077 }), (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.")]; 37078 function Tips() { 37079 const [randomIndex] = (0,external_wp_element_namespaceObject.useState)( 37080 // Disable Reason: I'm not generating an HTML id. 37081 // eslint-disable-next-line no-restricted-syntax 37082 Math.floor(Math.random() * globalTips.length)); 37083 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tip, { 37084 children: globalTips[randomIndex] 37085 }); 37086 } 37087 /* harmony default export */ const tips = (Tips); 37088 37089 ;// ./node_modules/@wordpress/icons/build-module/library/chevron-right.js 37090 /** 37091 * WordPress dependencies 37092 */ 37093 37094 37095 const chevronRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 37096 xmlns: "http://www.w3.org/2000/svg", 37097 viewBox: "0 0 24 24", 37098 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 37099 d: "M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z" 37100 }) 37101 }); 37102 /* harmony default export */ const chevron_right = (chevronRight); 37103 37104 ;// ./node_modules/@wordpress/icons/build-module/library/chevron-left.js 37105 /** 37106 * WordPress dependencies 37107 */ 37108 37109 37110 const chevronLeft = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 37111 xmlns: "http://www.w3.org/2000/svg", 37112 viewBox: "0 0 24 24", 37113 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 37114 d: "M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z" 37115 }) 37116 }); 37117 /* harmony default export */ const chevron_left = (chevronLeft); 37118 37119 ;// ./node_modules/@wordpress/icons/build-module/library/block-default.js 37120 /** 37121 * WordPress dependencies 37122 */ 37123 37124 37125 const blockDefault = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 37126 xmlns: "http://www.w3.org/2000/svg", 37127 viewBox: "0 0 24 24", 37128 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 37129 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" 37130 }) 37131 }); 37132 /* harmony default export */ const block_default = (blockDefault); 37133 37134 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-icon/index.js 37135 /** 37136 * External dependencies 37137 */ 37138 37139 37140 /** 37141 * WordPress dependencies 37142 */ 37143 37144 37145 37146 37147 function BlockIcon({ 37148 icon, 37149 showColors = false, 37150 className, 37151 context 37152 }) { 37153 if (icon?.src === 'block-default') { 37154 icon = { 37155 src: block_default 37156 }; 37157 } 37158 const renderedIcon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 37159 icon: icon && icon.src ? icon.src : icon, 37160 context: context 37161 }); 37162 const style = showColors ? { 37163 backgroundColor: icon && icon.background, 37164 color: icon && icon.foreground 37165 } : {}; 37166 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 37167 style: style, 37168 className: dist_clsx('block-editor-block-icon', className, { 37169 'has-colors': showColors 37170 }), 37171 children: renderedIcon 37172 }); 37173 } 37174 37175 /** 37176 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-icon/README.md 37177 */ 37178 /* harmony default export */ const block_icon = ((0,external_wp_element_namespaceObject.memo)(BlockIcon)); 37179 37180 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-card/index.js 37181 /** 37182 * External dependencies 37183 */ 37184 37185 37186 /** 37187 * WordPress dependencies 37188 */ 37189 37190 37191 37192 37193 37194 37195 /** 37196 * Internal dependencies 37197 */ 37198 37199 37200 37201 37202 const { 37203 Badge 37204 } = unlock(external_wp_components_namespaceObject.privateApis); 37205 37206 /** 37207 * A card component that displays block information including title, icon, and description. 37208 * Can be used to show block metadata and navigation controls for parent blocks. 37209 * 37210 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-card/README.md 37211 * 37212 * @example 37213 * ```jsx 37214 * function Example() { 37215 * return ( 37216 * <BlockCard 37217 * title="My Block" 37218 * icon="smiley" 37219 * description="A simple block example" 37220 * name="Custom Block" 37221 * /> 37222 * ); 37223 * } 37224 * ``` 37225 * 37226 * @param {Object} props Component props. 37227 * @param {string} props.title The title of the block. 37228 * @param {string|Object} props.icon The icon of the block. This can be any of [WordPress' Dashicons](https://developer.wordpress.org/resource/dashicons/), or a custom `svg` element. 37229 * @param {string} props.description The description of the block. 37230 * @param {Object} [props.blockType] Deprecated: Object containing block type data. 37231 * @param {string} [props.className] Additional classes to apply to the card. 37232 * @param {string} [props.name] Custom block name to display before the title. 37233 * @return {Element} Block card component. 37234 */ 37235 function BlockCard({ 37236 title, 37237 icon, 37238 description, 37239 blockType, 37240 className, 37241 name 37242 }) { 37243 if (blockType) { 37244 external_wp_deprecated_default()('`blockType` property in `BlockCard component`', { 37245 since: '5.7', 37246 alternative: '`title, icon and description` properties' 37247 }); 37248 ({ 37249 title, 37250 icon, 37251 description 37252 } = blockType); 37253 } 37254 const { 37255 parentNavBlockClientId 37256 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 37257 const { 37258 getSelectedBlockClientId, 37259 getBlockParentsByBlockName 37260 } = select(store); 37261 const _selectedBlockClientId = getSelectedBlockClientId(); 37262 return { 37263 parentNavBlockClientId: getBlockParentsByBlockName(_selectedBlockClientId, 'core/navigation', true)[0] 37264 }; 37265 }, []); 37266 const { 37267 selectBlock 37268 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 37269 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 37270 className: dist_clsx('block-editor-block-card', className), 37271 children: [parentNavBlockClientId && 37272 /*#__PURE__*/ 37273 // This is only used by the Navigation block for now. It's not ideal having Navigation block specific code here. 37274 (0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 37275 onClick: () => selectBlock(parentNavBlockClientId), 37276 label: (0,external_wp_i18n_namespaceObject.__)('Go to parent Navigation block'), 37277 style: 37278 // TODO: This style override is also used in ToolsPanelHeader. 37279 // It should be supported out-of-the-box by Button. 37280 { 37281 minWidth: 24, 37282 padding: 0 37283 }, 37284 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left, 37285 size: "small" 37286 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 37287 icon: icon, 37288 showColors: true 37289 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 37290 spacing: 1, 37291 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("h2", { 37292 className: "block-editor-block-card__title", 37293 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 37294 className: "block-editor-block-card__name", 37295 children: !!name?.length ? name : title 37296 }), !!name?.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Badge, { 37297 children: title 37298 })] 37299 }), description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 37300 className: "block-editor-block-card__description", 37301 children: description 37302 })] 37303 })] 37304 }); 37305 } 37306 /* harmony default export */ const block_card = (BlockCard); 37307 37308 ;// ./node_modules/@wordpress/upload-media/build-module/store/types.js 37309 let Type = /*#__PURE__*/function (Type) { 37310 Type["Unknown"] = "REDUX_UNKNOWN"; 37311 Type["Add"] = "ADD_ITEM"; 37312 Type["Prepare"] = "PREPARE_ITEM"; 37313 Type["Cancel"] = "CANCEL_ITEM"; 37314 Type["Remove"] = "REMOVE_ITEM"; 37315 Type["PauseItem"] = "PAUSE_ITEM"; 37316 Type["ResumeItem"] = "RESUME_ITEM"; 37317 Type["PauseQueue"] = "PAUSE_QUEUE"; 37318 Type["ResumeQueue"] = "RESUME_QUEUE"; 37319 Type["OperationStart"] = "OPERATION_START"; 37320 Type["OperationFinish"] = "OPERATION_FINISH"; 37321 Type["AddOperations"] = "ADD_OPERATIONS"; 37322 Type["CacheBlobUrl"] = "CACHE_BLOB_URL"; 37323 Type["RevokeBlobUrls"] = "REVOKE_BLOB_URLS"; 37324 Type["UpdateSettings"] = "UPDATE_SETTINGS"; 37325 return Type; 37326 }({}); 37327 37328 // Must match the Attachment type from the media-utils package. 37329 37330 let ItemStatus = /*#__PURE__*/function (ItemStatus) { 37331 ItemStatus["Processing"] = "PROCESSING"; 37332 ItemStatus["Paused"] = "PAUSED"; 37333 return ItemStatus; 37334 }({}); 37335 let OperationType = /*#__PURE__*/function (OperationType) { 37336 OperationType["Prepare"] = "PREPARE"; 37337 OperationType["Upload"] = "UPLOAD"; 37338 return OperationType; 37339 }({}); 37340 37341 ;// ./node_modules/@wordpress/upload-media/build-module/store/reducer.js 37342 /** 37343 * Internal dependencies 37344 */ 37345 37346 const reducer_noop = () => {}; 37347 const DEFAULT_STATE = { 37348 queue: [], 37349 queueStatus: 'active', 37350 blobUrls: {}, 37351 settings: { 37352 mediaUpload: reducer_noop 37353 } 37354 }; 37355 function reducer_reducer(state = DEFAULT_STATE, action = { 37356 type: Type.Unknown 37357 }) { 37358 switch (action.type) { 37359 case Type.PauseQueue: 37360 { 37361 return { 37362 ...state, 37363 queueStatus: 'paused' 37364 }; 37365 } 37366 case Type.ResumeQueue: 37367 { 37368 return { 37369 ...state, 37370 queueStatus: 'active' 37371 }; 37372 } 37373 case Type.Add: 37374 return { 37375 ...state, 37376 queue: [...state.queue, action.item] 37377 }; 37378 case Type.Cancel: 37379 return { 37380 ...state, 37381 queue: state.queue.map(item => item.id === action.id ? { 37382 ...item, 37383 error: action.error 37384 } : item) 37385 }; 37386 case Type.Remove: 37387 return { 37388 ...state, 37389 queue: state.queue.filter(item => item.id !== action.id) 37390 }; 37391 case Type.OperationStart: 37392 { 37393 return { 37394 ...state, 37395 queue: state.queue.map(item => item.id === action.id ? { 37396 ...item, 37397 currentOperation: action.operation 37398 } : item) 37399 }; 37400 } 37401 case Type.AddOperations: 37402 return { 37403 ...state, 37404 queue: state.queue.map(item => { 37405 if (item.id !== action.id) { 37406 return item; 37407 } 37408 return { 37409 ...item, 37410 operations: [...(item.operations || []), ...action.operations] 37411 }; 37412 }) 37413 }; 37414 case Type.OperationFinish: 37415 return { 37416 ...state, 37417 queue: state.queue.map(item => { 37418 if (item.id !== action.id) { 37419 return item; 37420 } 37421 const operations = item.operations ? item.operations.slice(1) : []; 37422 37423 // Prevent an empty object if there's no attachment data. 37424 const attachment = item.attachment || action.item.attachment ? { 37425 ...item.attachment, 37426 ...action.item.attachment 37427 } : undefined; 37428 return { 37429 ...item, 37430 currentOperation: undefined, 37431 operations, 37432 ...action.item, 37433 attachment, 37434 additionalData: { 37435 ...item.additionalData, 37436 ...action.item.additionalData 37437 } 37438 }; 37439 }) 37440 }; 37441 case Type.CacheBlobUrl: 37442 { 37443 const blobUrls = state.blobUrls[action.id] || []; 37444 return { 37445 ...state, 37446 blobUrls: { 37447 ...state.blobUrls, 37448 [action.id]: [...blobUrls, action.blobUrl] 37449 } 37450 }; 37451 } 37452 case Type.RevokeBlobUrls: 37453 { 37454 const newBlobUrls = { 37455 ...state.blobUrls 37456 }; 37457 delete newBlobUrls[action.id]; 37458 return { 37459 ...state, 37460 blobUrls: newBlobUrls 37461 }; 37462 } 37463 case Type.UpdateSettings: 37464 { 37465 return { 37466 ...state, 37467 settings: { 37468 ...state.settings, 37469 ...action.settings 37470 } 37471 }; 37472 } 37473 } 37474 return state; 37475 } 37476 /* harmony default export */ const store_reducer = (reducer_reducer); 37477 37478 ;// ./node_modules/@wordpress/upload-media/build-module/store/selectors.js 37479 /** 37480 * Internal dependencies 37481 */ 37482 37483 /** 37484 * Returns all items currently being uploaded. 37485 * 37486 * @param state Upload state. 37487 * 37488 * @return Queue items. 37489 */ 37490 function getItems(state) { 37491 return state.queue; 37492 } 37493 37494 /** 37495 * Determines whether any upload is currently in progress. 37496 * 37497 * @param state Upload state. 37498 * 37499 * @return Whether any upload is currently in progress. 37500 */ 37501 function isUploading(state) { 37502 return state.queue.length >= 1; 37503 } 37504 37505 /** 37506 * Determines whether an upload is currently in progress given an attachment URL. 37507 * 37508 * @param state Upload state. 37509 * @param url Attachment URL. 37510 * 37511 * @return Whether upload is currently in progress for the given attachment. 37512 */ 37513 function isUploadingByUrl(state, url) { 37514 return state.queue.some(item => item.attachment?.url === url || item.sourceUrl === url); 37515 } 37516 37517 /** 37518 * Determines whether an upload is currently in progress given an attachment ID. 37519 * 37520 * @param state Upload state. 37521 * @param attachmentId Attachment ID. 37522 * 37523 * @return Whether upload is currently in progress for the given attachment. 37524 */ 37525 function isUploadingById(state, attachmentId) { 37526 return state.queue.some(item => item.attachment?.id === attachmentId || item.sourceAttachmentId === attachmentId); 37527 } 37528 37529 /** 37530 * Returns the media upload settings. 37531 * 37532 * @param state Upload state. 37533 * 37534 * @return Settings 37535 */ 37536 function selectors_getSettings(state) { 37537 return state.settings; 37538 } 37539 37540 ;// ./node_modules/@wordpress/upload-media/build-module/store/private-selectors.js 37541 /** 37542 * Internal dependencies 37543 */ 37544 37545 37546 /** 37547 * Returns all items currently being uploaded. 37548 * 37549 * @param state Upload state. 37550 * 37551 * @return Queue items. 37552 */ 37553 function getAllItems(state) { 37554 return state.queue; 37555 } 37556 37557 /** 37558 * Returns a specific item given its unique ID. 37559 * 37560 * @param state Upload state. 37561 * @param id Item ID. 37562 * 37563 * @return Queue item. 37564 */ 37565 function getItem(state, id) { 37566 return state.queue.find(item => item.id === id); 37567 } 37568 37569 /** 37570 * Determines whether a batch has been successfully uploaded, given its unique ID. 37571 * 37572 * @param state Upload state. 37573 * @param batchId Batch ID. 37574 * 37575 * @return Whether a batch has been uploaded. 37576 */ 37577 function isBatchUploaded(state, batchId) { 37578 const batchItems = state.queue.filter(item => batchId === item.batchId); 37579 return batchItems.length === 0; 37580 } 37581 37582 /** 37583 * Determines whether an upload is currently in progress given a post or attachment ID. 37584 * 37585 * @param state Upload state. 37586 * @param postOrAttachmentId Post ID or attachment ID. 37587 * 37588 * @return Whether upload is currently in progress for the given post or attachment. 37589 */ 37590 function isUploadingToPost(state, postOrAttachmentId) { 37591 return state.queue.some(item => item.currentOperation === OperationType.Upload && item.additionalData.post === postOrAttachmentId); 37592 } 37593 37594 /** 37595 * Returns the next paused upload for a given post or attachment ID. 37596 * 37597 * @param state Upload state. 37598 * @param postOrAttachmentId Post ID or attachment ID. 37599 * 37600 * @return Paused item. 37601 */ 37602 function getPausedUploadForPost(state, postOrAttachmentId) { 37603 return state.queue.find(item => item.status === ItemStatus.Paused && item.additionalData.post === postOrAttachmentId); 37604 } 37605 37606 /** 37607 * Determines whether uploading is currently paused. 37608 * 37609 * @param state Upload state. 37610 * 37611 * @return Whether uploading is currently paused. 37612 */ 37613 function isPaused(state) { 37614 return state.queueStatus === 'paused'; 37615 } 37616 37617 /** 37618 * Returns all cached blob URLs for a given item ID. 37619 * 37620 * @param state Upload state. 37621 * @param id Item ID 37622 * 37623 * @return List of blob URLs. 37624 */ 37625 function getBlobUrls(state, id) { 37626 return state.blobUrls[id] || []; 37627 } 37628 37629 ;// ./node_modules/@wordpress/upload-media/node_modules/uuid/dist/esm-browser/native.js 37630 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); 37631 /* harmony default export */ const esm_browser_native = ({ 37632 randomUUID 37633 }); 37634 ;// ./node_modules/@wordpress/upload-media/node_modules/uuid/dist/esm-browser/rng.js 37635 // Unique ID creation requires a high quality random # generator. In the browser we therefore 37636 // require the crypto API and do not support built-in fallback to lower quality random number 37637 // generators (like Math.random()). 37638 let getRandomValues; 37639 const rnds8 = new Uint8Array(16); 37640 function rng() { 37641 // lazy load so that environments that need to polyfill have a chance to do so 37642 if (!getRandomValues) { 37643 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. 37644 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); 37645 37646 if (!getRandomValues) { 37647 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 37648 } 37649 } 37650 37651 return getRandomValues(rnds8); 37652 } 37653 ;// ./node_modules/@wordpress/upload-media/node_modules/uuid/dist/esm-browser/stringify.js 37654 37655 /** 37656 * Convert array of 16 byte values to UUID string format of the form: 37657 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 37658 */ 37659 37660 const byteToHex = []; 37661 37662 for (let i = 0; i < 256; ++i) { 37663 byteToHex.push((i + 0x100).toString(16).slice(1)); 37664 } 37665 37666 function unsafeStringify(arr, offset = 0) { 37667 // Note: Be careful editing this code! It's been tuned for performance 37668 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 37669 return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; 37670 } 37671 37672 function stringify(arr, offset = 0) { 37673 const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one 37674 // of the following: 37675 // - One or more input array values don't map to a hex octet (leading to 37676 // "undefined" in the uuid) 37677 // - Invalid input values for the RFC `version` or `variant` fields 37678 37679 if (!validate(uuid)) { 37680 throw TypeError('Stringified UUID is invalid'); 37681 } 37682 37683 return uuid; 37684 } 37685 37686 /* harmony default export */ const esm_browser_stringify = ((/* unused pure expression or super */ null && (stringify))); 37687 ;// ./node_modules/@wordpress/upload-media/node_modules/uuid/dist/esm-browser/v4.js 37688 37689 37690 37691 37692 function v4(options, buf, offset) { 37693 if (esm_browser_native.randomUUID && !buf && !options) { 37694 return esm_browser_native.randomUUID(); 37695 } 37696 37697 options = options || {}; 37698 const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 37699 37700 rnds[6] = rnds[6] & 0x0f | 0x40; 37701 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 37702 37703 if (buf) { 37704 offset = offset || 0; 37705 37706 for (let i = 0; i < 16; ++i) { 37707 buf[offset + i] = rnds[i]; 37708 } 37709 37710 return buf; 37711 } 37712 37713 return unsafeStringify(rnds); 37714 } 37715 37716 /* harmony default export */ const esm_browser_v4 = (v4); 37717 ;// ./node_modules/@wordpress/upload-media/build-module/upload-error.js 37718 /** 37719 * MediaError class. 37720 * 37721 * Small wrapper around the `Error` class 37722 * to hold an error code and a reference to a file object. 37723 */ 37724 class UploadError extends Error { 37725 constructor({ 37726 code, 37727 message, 37728 file, 37729 cause 37730 }) { 37731 super(message, { 37732 cause 37733 }); 37734 Object.setPrototypeOf(this, new.target.prototype); 37735 this.code = code; 37736 this.file = file; 37737 } 37738 } 37739 37740 ;// ./node_modules/@wordpress/upload-media/build-module/validate-mime-type.js 37741 /** 37742 * WordPress dependencies 37743 */ 37744 37745 37746 /** 37747 * Internal dependencies 37748 */ 37749 37750 37751 /** 37752 * Verifies if the caller (e.g. a block) supports this mime type. 37753 * 37754 * @param file File object. 37755 * @param allowedTypes List of allowed mime types. 37756 */ 37757 function validateMimeType(file, allowedTypes) { 37758 if (!allowedTypes) { 37759 return; 37760 } 37761 37762 // Allowed type specified by consumer. 37763 const isAllowedType = allowedTypes.some(allowedType => { 37764 // If a complete mimetype is specified verify if it matches exactly the mime type of the file. 37765 if (allowedType.includes('/')) { 37766 return allowedType === file.type; 37767 } 37768 // Otherwise a general mime type is used, and we should verify if the file mimetype starts with it. 37769 return file.type.startsWith(`$allowedType}/`); 37770 }); 37771 if (file.type && !isAllowedType) { 37772 throw new UploadError({ 37773 code: 'MIME_TYPE_NOT_SUPPORTED', 37774 message: (0,external_wp_i18n_namespaceObject.sprintf)( 37775 // translators: %s: file name. 37776 (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, this file type is not supported here.'), file.name), 37777 file 37778 }); 37779 } 37780 } 37781 37782 ;// ./node_modules/@wordpress/upload-media/build-module/get-mime-types-array.js 37783 /** 37784 * Browsers may use unexpected mime types, and they differ from browser to browser. 37785 * This function computes a flexible array of mime types from the mime type structured provided by the server. 37786 * Converts { jpg|jpeg|jpe: "image/jpeg" } into [ "image/jpeg", "image/jpg", "image/jpeg", "image/jpe" ] 37787 * 37788 * @param {?Object} wpMimeTypesObject Mime type object received from the server. 37789 * Extensions are keys separated by '|' and values are mime types associated with an extension. 37790 * 37791 * @return An array of mime types or null 37792 */ 37793 function getMimeTypesArray(wpMimeTypesObject) { 37794 if (!wpMimeTypesObject) { 37795 return null; 37796 } 37797 return Object.entries(wpMimeTypesObject).flatMap(([extensionsString, mime]) => { 37798 const [type] = mime.split('/'); 37799 const extensions = extensionsString.split('|'); 37800 return [mime, ...extensions.map(extension => `$type}/$extension}`)]; 37801 }); 37802 } 37803 37804 ;// ./node_modules/@wordpress/upload-media/build-module/validate-mime-type-for-user.js 37805 /** 37806 * WordPress dependencies 37807 */ 37808 37809 37810 /** 37811 * Internal dependencies 37812 */ 37813 37814 37815 37816 /** 37817 * Verifies if the user is allowed to upload this mime type. 37818 * 37819 * @param file File object. 37820 * @param wpAllowedMimeTypes List of allowed mime types and file extensions. 37821 */ 37822 function validateMimeTypeForUser(file, wpAllowedMimeTypes) { 37823 // Allowed types for the current WP_User. 37824 const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes); 37825 if (!allowedMimeTypesForUser) { 37826 return; 37827 } 37828 const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(file.type); 37829 if (file.type && !isAllowedMimeTypeForUser) { 37830 throw new UploadError({ 37831 code: 'MIME_TYPE_NOT_ALLOWED_FOR_USER', 37832 message: (0,external_wp_i18n_namespaceObject.sprintf)( 37833 // translators: %s: file name. 37834 (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, you are not allowed to upload this file type.'), file.name), 37835 file 37836 }); 37837 } 37838 } 37839 37840 ;// ./node_modules/@wordpress/upload-media/build-module/validate-file-size.js 37841 /** 37842 * WordPress dependencies 37843 */ 37844 37845 37846 /** 37847 * Internal dependencies 37848 */ 37849 37850 37851 /** 37852 * Verifies whether the file is within the file upload size limits for the site. 37853 * 37854 * @param file File object. 37855 * @param maxUploadFileSize Maximum upload size in bytes allowed for the site. 37856 */ 37857 function validateFileSize(file, maxUploadFileSize) { 37858 // Don't allow empty files to be uploaded. 37859 if (file.size <= 0) { 37860 throw new UploadError({ 37861 code: 'EMPTY_FILE', 37862 message: (0,external_wp_i18n_namespaceObject.sprintf)( 37863 // translators: %s: file name. 37864 (0,external_wp_i18n_namespaceObject.__)('%s: This file is empty.'), file.name), 37865 file 37866 }); 37867 } 37868 if (maxUploadFileSize && file.size > maxUploadFileSize) { 37869 throw new UploadError({ 37870 code: 'SIZE_ABOVE_LIMIT', 37871 message: (0,external_wp_i18n_namespaceObject.sprintf)( 37872 // translators: %s: file name. 37873 (0,external_wp_i18n_namespaceObject.__)('%s: This file exceeds the maximum upload size for this site.'), file.name), 37874 file 37875 }); 37876 } 37877 } 37878 37879 ;// ./node_modules/@wordpress/upload-media/build-module/store/actions.js 37880 /** 37881 * External dependencies 37882 */ 37883 37884 37885 /** 37886 * WordPress dependencies 37887 */ 37888 37889 /** 37890 * Internal dependencies 37891 */ 37892 37893 37894 37895 37896 37897 /** 37898 * Adds a new item to the upload queue. 37899 * 37900 * @param $0 37901 * @param $0.files Files 37902 * @param [$0.onChange] Function called each time a file or a temporary representation of the file is available. 37903 * @param [$0.onSuccess] Function called after the file is uploaded. 37904 * @param [$0.onBatchSuccess] Function called after a batch of files is uploaded. 37905 * @param [$0.onError] Function called when an error happens. 37906 * @param [$0.additionalData] Additional data to include in the request. 37907 * @param [$0.allowedTypes] Array with the types of media that can be uploaded, if unset all types are allowed. 37908 */ 37909 function addItems({ 37910 files, 37911 onChange, 37912 onSuccess, 37913 onError, 37914 onBatchSuccess, 37915 additionalData, 37916 allowedTypes 37917 }) { 37918 return async ({ 37919 select, 37920 dispatch 37921 }) => { 37922 const batchId = esm_browser_v4(); 37923 for (const file of files) { 37924 /* 37925 Check if the caller (e.g. a block) supports this mime type. 37926 Special case for file types such as HEIC which will be converted before upload anyway. 37927 Another check will be done before upload. 37928 */ 37929 try { 37930 validateMimeType(file, allowedTypes); 37931 validateMimeTypeForUser(file, select.getSettings().allowedMimeTypes); 37932 } catch (error) { 37933 onError?.(error); 37934 continue; 37935 } 37936 try { 37937 validateFileSize(file, select.getSettings().maxUploadFileSize); 37938 } catch (error) { 37939 onError?.(error); 37940 continue; 37941 } 37942 dispatch.addItem({ 37943 file, 37944 batchId, 37945 onChange, 37946 onSuccess, 37947 onBatchSuccess, 37948 onError, 37949 additionalData 37950 }); 37951 } 37952 }; 37953 } 37954 37955 /** 37956 * Cancels an item in the queue based on an error. 37957 * 37958 * @param id Item ID. 37959 * @param error Error instance. 37960 * @param silent Whether to cancel the item silently, 37961 * without invoking its `onError` callback. 37962 */ 37963 function cancelItem(id, error, silent = false) { 37964 return async ({ 37965 select, 37966 dispatch 37967 }) => { 37968 const item = select.getItem(id); 37969 if (!item) { 37970 /* 37971 * Do nothing if item has already been removed. 37972 * This can happen if an upload is cancelled manually 37973 * while transcoding with vips is still in progress. 37974 * Then, cancelItem() is once invoked manually and once 37975 * by the error handler in optimizeImageItem(). 37976 */ 37977 return; 37978 } 37979 item.abortController?.abort(); 37980 if (!silent) { 37981 const { 37982 onError 37983 } = item; 37984 onError?.(error !== null && error !== void 0 ? error : new Error('Upload cancelled')); 37985 if (!onError && error) { 37986 // TODO: Find better way to surface errors with sideloads etc. 37987 // eslint-disable-next-line no-console -- Deliberately log errors here. 37988 console.error('Upload cancelled', error); 37989 } 37990 } 37991 dispatch({ 37992 type: Type.Cancel, 37993 id, 37994 error 37995 }); 37996 dispatch.removeItem(id); 37997 dispatch.revokeBlobUrls(id); 37998 37999 // All items of this batch were cancelled or finished. 38000 if (item.batchId && select.isBatchUploaded(item.batchId)) { 38001 item.onBatchSuccess?.(); 38002 } 38003 }; 38004 } 38005 38006 ;// ./node_modules/@wordpress/upload-media/build-module/utils.js 38007 /** 38008 * WordPress dependencies 38009 */ 38010 38011 38012 38013 /** 38014 * Converts a Blob to a File with a default name like "image.png". 38015 * 38016 * If it is already a File object, it is returned unchanged. 38017 * 38018 * @param fileOrBlob Blob object. 38019 * @return File object. 38020 */ 38021 function convertBlobToFile(fileOrBlob) { 38022 if (fileOrBlob instanceof File) { 38023 return fileOrBlob; 38024 } 38025 38026 // Extension is only an approximation. 38027 // The server will override it if incorrect. 38028 const ext = fileOrBlob.type.split('/')[1]; 38029 const mediaType = 'application/pdf' === fileOrBlob.type ? 'document' : fileOrBlob.type.split('/')[0]; 38030 return new File([fileOrBlob], `$mediaType}.$ext}`, { 38031 type: fileOrBlob.type 38032 }); 38033 } 38034 38035 /** 38036 * Renames a given file and returns a new file. 38037 * 38038 * Copies over the last modified time. 38039 * 38040 * @param file File object. 38041 * @param name File name. 38042 * @return Renamed file object. 38043 */ 38044 function renameFile(file, name) { 38045 return new File([file], name, { 38046 type: file.type, 38047 lastModified: file.lastModified 38048 }); 38049 } 38050 38051 /** 38052 * Clones a given file object. 38053 * 38054 * @param file File object. 38055 * @return New file object. 38056 */ 38057 function cloneFile(file) { 38058 return renameFile(file, file.name); 38059 } 38060 38061 /** 38062 * Returns the file extension from a given file name or URL. 38063 * 38064 * @param file File URL. 38065 * @return File extension or null if it does not have one. 38066 */ 38067 function getFileExtension(file) { 38068 return file.includes('.') ? file.split('.').pop() || null : null; 38069 } 38070 38071 /** 38072 * Returns file basename without extension. 38073 * 38074 * For example, turns "my-awesome-file.jpeg" into "my-awesome-file". 38075 * 38076 * @param name File name. 38077 * @return File basename. 38078 */ 38079 function getFileBasename(name) { 38080 return name.includes('.') ? name.split('.').slice(0, -1).join('.') : name; 38081 } 38082 38083 /** 38084 * Returns the file name including extension from a URL. 38085 * 38086 * @param url File URL. 38087 * @return File name. 38088 */ 38089 function getFileNameFromUrl(url) { 38090 return getFilename(url) || _x('unnamed', 'file name'); 38091 } 38092 38093 ;// ./node_modules/@wordpress/upload-media/build-module/stub-file.js 38094 class StubFile extends File { 38095 constructor(fileName = 'stub-file') { 38096 super([], fileName); 38097 } 38098 } 38099 38100 ;// ./node_modules/@wordpress/upload-media/build-module/store/private-actions.js 38101 /** 38102 * External dependencies 38103 */ 38104 38105 38106 /** 38107 * WordPress dependencies 38108 */ 38109 38110 /** 38111 * Internal dependencies 38112 */ 38113 38114 38115 38116 /** 38117 * Adds a new item to the upload queue. 38118 * 38119 * @param $0 38120 * @param $0.file File 38121 * @param [$0.batchId] Batch ID. 38122 * @param [$0.onChange] Function called each time a file or a temporary representation of the file is available. 38123 * @param [$0.onSuccess] Function called after the file is uploaded. 38124 * @param [$0.onBatchSuccess] Function called after a batch of files is uploaded. 38125 * @param [$0.onError] Function called when an error happens. 38126 * @param [$0.additionalData] Additional data to include in the request. 38127 * @param [$0.sourceUrl] Source URL. Used when importing a file from a URL or optimizing an existing file. 38128 * @param [$0.sourceAttachmentId] Source attachment ID. Used when optimizing an existing file for example. 38129 * @param [$0.abortController] Abort controller for upload cancellation. 38130 * @param [$0.operations] List of operations to perform. Defaults to automatically determined list, based on the file. 38131 */ 38132 function addItem({ 38133 file: fileOrBlob, 38134 batchId, 38135 onChange, 38136 onSuccess, 38137 onBatchSuccess, 38138 onError, 38139 additionalData = {}, 38140 sourceUrl, 38141 sourceAttachmentId, 38142 abortController, 38143 operations 38144 }) { 38145 return async ({ 38146 dispatch 38147 }) => { 38148 const itemId = esm_browser_v4(); 38149 38150 // Hardening in case a Blob is passed instead of a File. 38151 // See https://github.com/WordPress/gutenberg/pull/65693 for an example. 38152 const file = convertBlobToFile(fileOrBlob); 38153 let blobUrl; 38154 38155 // StubFile could be coming from addItemFromUrl(). 38156 if (!(file instanceof StubFile)) { 38157 blobUrl = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 38158 dispatch({ 38159 type: Type.CacheBlobUrl, 38160 id: itemId, 38161 blobUrl 38162 }); 38163 } 38164 dispatch({ 38165 type: Type.Add, 38166 item: { 38167 id: itemId, 38168 batchId, 38169 status: ItemStatus.Processing, 38170 sourceFile: cloneFile(file), 38171 file, 38172 attachment: { 38173 url: blobUrl 38174 }, 38175 additionalData: { 38176 convert_format: false, 38177 ...additionalData 38178 }, 38179 onChange, 38180 onSuccess, 38181 onBatchSuccess, 38182 onError, 38183 sourceUrl, 38184 sourceAttachmentId, 38185 abortController: abortController || new AbortController(), 38186 operations: Array.isArray(operations) ? operations : [OperationType.Prepare] 38187 } 38188 }); 38189 dispatch.processItem(itemId); 38190 }; 38191 } 38192 38193 /** 38194 * Processes a single item in the queue. 38195 * 38196 * Runs the next operation in line and invokes any callbacks. 38197 * 38198 * @param id Item ID. 38199 */ 38200 function processItem(id) { 38201 return async ({ 38202 select, 38203 dispatch 38204 }) => { 38205 if (select.isPaused()) { 38206 return; 38207 } 38208 const item = select.getItem(id); 38209 const { 38210 attachment, 38211 onChange, 38212 onSuccess, 38213 onBatchSuccess, 38214 batchId 38215 } = item; 38216 const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0]; 38217 if (attachment) { 38218 onChange?.([attachment]); 38219 } 38220 38221 /* 38222 If there are no more operations, the item can be removed from the queue, 38223 but only if there are no thumbnails still being side-loaded, 38224 or if itself is a side-loaded item. 38225 */ 38226 38227 if (!operation) { 38228 if (attachment) { 38229 onSuccess?.([attachment]); 38230 } 38231 38232 // dispatch.removeItem( id ); 38233 dispatch.revokeBlobUrls(id); 38234 if (batchId && select.isBatchUploaded(batchId)) { 38235 onBatchSuccess?.(); 38236 } 38237 38238 /* 38239 At this point we are dealing with a parent whose children haven't fully uploaded yet. 38240 Do nothing and let the removal happen once the last side-loaded item finishes. 38241 */ 38242 38243 return; 38244 } 38245 if (!operation) { 38246 // This shouldn't really happen. 38247 return; 38248 } 38249 dispatch({ 38250 type: Type.OperationStart, 38251 id, 38252 operation 38253 }); 38254 switch (operation) { 38255 case OperationType.Prepare: 38256 dispatch.prepareItem(item.id); 38257 break; 38258 case OperationType.Upload: 38259 dispatch.uploadItem(id); 38260 break; 38261 } 38262 }; 38263 } 38264 38265 /** 38266 * Returns an action object that pauses all processing in the queue. 38267 * 38268 * Useful for testing purposes. 38269 * 38270 * @return Action object. 38271 */ 38272 function pauseQueue() { 38273 return { 38274 type: Type.PauseQueue 38275 }; 38276 } 38277 38278 /** 38279 * Resumes all processing in the queue. 38280 * 38281 * Dispatches an action object for resuming the queue itself, 38282 * and triggers processing for each remaining item in the queue individually. 38283 */ 38284 function resumeQueue() { 38285 return async ({ 38286 select, 38287 dispatch 38288 }) => { 38289 dispatch({ 38290 type: Type.ResumeQueue 38291 }); 38292 for (const item of select.getAllItems()) { 38293 dispatch.processItem(item.id); 38294 } 38295 }; 38296 } 38297 38298 /** 38299 * Removes a specific item from the queue. 38300 * 38301 * @param id Item ID. 38302 */ 38303 function removeItem(id) { 38304 return async ({ 38305 select, 38306 dispatch 38307 }) => { 38308 const item = select.getItem(id); 38309 if (!item) { 38310 return; 38311 } 38312 dispatch({ 38313 type: Type.Remove, 38314 id 38315 }); 38316 }; 38317 } 38318 38319 /** 38320 * Finishes an operation for a given item ID and immediately triggers processing the next one. 38321 * 38322 * @param id Item ID. 38323 * @param updates Updated item data. 38324 */ 38325 function finishOperation(id, updates) { 38326 return async ({ 38327 dispatch 38328 }) => { 38329 dispatch({ 38330 type: Type.OperationFinish, 38331 id, 38332 item: updates 38333 }); 38334 dispatch.processItem(id); 38335 }; 38336 } 38337 38338 /** 38339 * Prepares an item for initial processing. 38340 * 38341 * Determines the list of operations to perform for a given image, 38342 * depending on its media type. 38343 * 38344 * For example, HEIF images first need to be converted, resized, 38345 * compressed, and then uploaded. 38346 * 38347 * Or videos need to be compressed, and then need poster generation 38348 * before upload. 38349 * 38350 * @param id Item ID. 38351 */ 38352 function prepareItem(id) { 38353 return async ({ 38354 dispatch 38355 }) => { 38356 const operations = [OperationType.Upload]; 38357 dispatch({ 38358 type: Type.AddOperations, 38359 id, 38360 operations 38361 }); 38362 dispatch.finishOperation(id, {}); 38363 }; 38364 } 38365 38366 /** 38367 * Uploads an item to the server. 38368 * 38369 * @param id Item ID. 38370 */ 38371 function uploadItem(id) { 38372 return async ({ 38373 select, 38374 dispatch 38375 }) => { 38376 const item = select.getItem(id); 38377 select.getSettings().mediaUpload({ 38378 filesList: [item.file], 38379 additionalData: item.additionalData, 38380 signal: item.abortController?.signal, 38381 onFileChange: ([attachment]) => { 38382 if (!(0,external_wp_blob_namespaceObject.isBlobURL)(attachment.url)) { 38383 dispatch.finishOperation(id, { 38384 attachment 38385 }); 38386 } 38387 }, 38388 onSuccess: ([attachment]) => { 38389 dispatch.finishOperation(id, { 38390 attachment 38391 }); 38392 }, 38393 onError: error => { 38394 dispatch.cancelItem(id, error); 38395 } 38396 }); 38397 }; 38398 } 38399 38400 /** 38401 * Revokes all blob URLs for a given item, freeing up memory. 38402 * 38403 * @param id Item ID. 38404 */ 38405 function revokeBlobUrls(id) { 38406 return async ({ 38407 select, 38408 dispatch 38409 }) => { 38410 const blobUrls = select.getBlobUrls(id); 38411 for (const blobUrl of blobUrls) { 38412 (0,external_wp_blob_namespaceObject.revokeBlobURL)(blobUrl); 38413 } 38414 dispatch({ 38415 type: Type.RevokeBlobUrls, 38416 id 38417 }); 38418 }; 38419 } 38420 38421 /** 38422 * Returns an action object that pauses all processing in the queue. 38423 * 38424 * Useful for testing purposes. 38425 * 38426 * @param settings 38427 * @return Action object. 38428 */ 38429 function private_actions_updateSettings(settings) { 38430 return { 38431 type: Type.UpdateSettings, 38432 settings 38433 }; 38434 } 38435 38436 ;// ./node_modules/@wordpress/upload-media/build-module/lock-unlock.js 38437 /** 38438 * WordPress dependencies 38439 */ 38440 38441 const { 38442 lock: lock_unlock_lock, 38443 unlock: lock_unlock_unlock 38444 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/upload-media'); 38445 38446 ;// ./node_modules/@wordpress/upload-media/build-module/store/constants.js 38447 const constants_STORE_NAME = 'core/upload-media'; 38448 38449 ;// ./node_modules/@wordpress/upload-media/build-module/store/index.js 38450 /** 38451 * WordPress dependencies 38452 */ 38453 38454 38455 /** 38456 * Internal dependencies 38457 */ 38458 38459 38460 38461 38462 38463 38464 38465 38466 /** 38467 * Media upload data store configuration. 38468 * 38469 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore 38470 */ 38471 const store_storeConfig = { 38472 reducer: store_reducer, 38473 selectors: store_selectors_namespaceObject, 38474 actions: store_actions_namespaceObject 38475 }; 38476 38477 /** 38478 * Store definition for the media upload namespace. 38479 * 38480 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 38481 */ 38482 const store_store = (0,external_wp_data_namespaceObject.createReduxStore)(constants_STORE_NAME, { 38483 reducer: store_reducer, 38484 selectors: store_selectors_namespaceObject, 38485 actions: store_actions_namespaceObject 38486 }); 38487 (0,external_wp_data_namespaceObject.register)(store_store); 38488 // @ts-ignore 38489 lock_unlock_unlock(store_store).registerPrivateActions(store_private_actions_namespaceObject); 38490 // @ts-ignore 38491 lock_unlock_unlock(store_store).registerPrivateSelectors(store_private_selectors_namespaceObject); 38492 38493 ;// ./node_modules/@wordpress/upload-media/build-module/components/provider/with-registry-provider.js 38494 /** 38495 * WordPress dependencies 38496 */ 38497 38498 38499 38500 38501 /** 38502 * Internal dependencies 38503 */ 38504 38505 38506 38507 function getSubRegistry(subRegistries, registry, useSubRegistry) { 38508 if (!useSubRegistry) { 38509 return registry; 38510 } 38511 let subRegistry = subRegistries.get(registry); 38512 if (!subRegistry) { 38513 subRegistry = (0,external_wp_data_namespaceObject.createRegistry)({}, registry); 38514 subRegistry.registerStore(constants_STORE_NAME, store_storeConfig); 38515 subRegistries.set(registry, subRegistry); 38516 } 38517 return subRegistry; 38518 } 38519 const withRegistryProvider = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => ({ 38520 useSubRegistry = true, 38521 ...props 38522 }) => { 38523 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 38524 const [subRegistries] = (0,external_wp_element_namespaceObject.useState)(() => new WeakMap()); 38525 const subRegistry = getSubRegistry(subRegistries, registry, useSubRegistry); 38526 if (subRegistry === registry) { 38527 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 38528 registry: registry, 38529 ...props 38530 }); 38531 } 38532 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_data_namespaceObject.RegistryProvider, { 38533 value: subRegistry, 38534 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 38535 registry: subRegistry, 38536 ...props 38537 }) 38538 }); 38539 }, 'withRegistryProvider'); 38540 /* harmony default export */ const with_registry_provider = (withRegistryProvider); 38541 38542 ;// ./node_modules/@wordpress/upload-media/build-module/components/provider/index.js 38543 /** 38544 * WordPress dependencies 38545 */ 38546 38547 38548 38549 /** 38550 * Internal dependencies 38551 */ 38552 38553 38554 38555 38556 const MediaUploadProvider = with_registry_provider(props => { 38557 const { 38558 children, 38559 settings 38560 } = props; 38561 const { 38562 updateSettings 38563 } = lock_unlock_unlock((0,external_wp_data_namespaceObject.useDispatch)(store_store)); 38564 (0,external_wp_element_namespaceObject.useEffect)(() => { 38565 updateSettings(settings); 38566 }, [settings, updateSettings]); 38567 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 38568 children: children 38569 }); 38570 }); 38571 /* harmony default export */ const provider = (MediaUploadProvider); 38572 38573 ;// ./node_modules/@wordpress/block-editor/build-module/components/provider/with-registry-provider.js 38574 /** 38575 * WordPress dependencies 38576 */ 38577 38578 38579 38580 38581 /** 38582 * Internal dependencies 38583 */ 38584 38585 38586 38587 function with_registry_provider_getSubRegistry(subRegistries, registry, useSubRegistry) { 38588 if (!useSubRegistry) { 38589 return registry; 38590 } 38591 let subRegistry = subRegistries.get(registry); 38592 if (!subRegistry) { 38593 subRegistry = (0,external_wp_data_namespaceObject.createRegistry)({}, registry); 38594 subRegistry.registerStore(STORE_NAME, storeConfig); 38595 subRegistries.set(registry, subRegistry); 38596 } 38597 return subRegistry; 38598 } 38599 const with_registry_provider_withRegistryProvider = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => ({ 38600 useSubRegistry = true, 38601 ...props 38602 }) => { 38603 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 38604 const [subRegistries] = (0,external_wp_element_namespaceObject.useState)(() => new WeakMap()); 38605 const subRegistry = with_registry_provider_getSubRegistry(subRegistries, registry, useSubRegistry); 38606 if (subRegistry === registry) { 38607 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 38608 registry: registry, 38609 ...props 38610 }); 38611 } 38612 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_data_namespaceObject.RegistryProvider, { 38613 value: subRegistry, 38614 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 38615 registry: subRegistry, 38616 ...props 38617 }) 38618 }); 38619 }, 'withRegistryProvider'); 38620 /* harmony default export */ const provider_with_registry_provider = (with_registry_provider_withRegistryProvider); 38621 38622 ;// ./node_modules/@wordpress/block-editor/build-module/components/provider/use-block-sync.js 38623 /** 38624 * WordPress dependencies 38625 */ 38626 38627 38628 38629 38630 /** 38631 * Internal dependencies 38632 */ 38633 38634 const use_block_sync_noop = () => {}; 38635 38636 /** 38637 * A function to call when the block value has been updated in the block-editor 38638 * store. 38639 * 38640 * @callback onBlockUpdate 38641 * @param {Object[]} blocks The updated blocks. 38642 * @param {Object} options The updated block options, such as selectionStart 38643 * and selectionEnd. 38644 */ 38645 38646 /** 38647 * useBlockSync is a side effect which handles bidirectional sync between the 38648 * block-editor store and a controlling data source which provides blocks. This 38649 * is most commonly used by the BlockEditorProvider to synchronize the contents 38650 * of the block-editor store with the root entity, like a post. 38651 * 38652 * Another example would be the template part block, which provides blocks from 38653 * a separate entity data source than a root entity. This hook syncs edits to 38654 * the template part in the block editor back to the entity and vice-versa. 38655 * 38656 * Here are some of its basic functions: 38657 * - Initializes the block-editor store for the given clientID to the blocks 38658 * given via props. 38659 * - Adds incoming changes (like undo) to the block-editor store. 38660 * - Adds outgoing changes (like editing content) to the controlling entity, 38661 * determining if a change should be considered persistent or not. 38662 * - Handles edge cases and race conditions which occur in those operations. 38663 * - Ignores changes which happen to other entities (like nested inner block 38664 * controllers. 38665 * - Passes selection state from the block-editor store to the controlling entity. 38666 * 38667 * @param {Object} props Props for the block sync hook 38668 * @param {string} props.clientId The client ID of the inner block controller. 38669 * If none is passed, then it is assumed to be a 38670 * root controller rather than an inner block 38671 * controller. 38672 * @param {Object[]} props.value The control value for the blocks. This value 38673 * is used to initialize the block-editor store 38674 * and for resetting the blocks to incoming 38675 * changes like undo. 38676 * @param {Object} props.selection The selection state responsible to restore the selection on undo/redo. 38677 * @param {onBlockUpdate} props.onChange Function to call when a persistent 38678 * change has been made in the block-editor blocks 38679 * for the given clientId. For example, after 38680 * this function is called, an entity is marked 38681 * dirty because it has changes to save. 38682 * @param {onBlockUpdate} props.onInput Function to call when a non-persistent 38683 * change has been made in the block-editor blocks 38684 * for the given clientId. When this is called, 38685 * controlling sources do not become dirty. 38686 */ 38687 function useBlockSync({ 38688 clientId = null, 38689 value: controlledBlocks, 38690 selection: controlledSelection, 38691 onChange = use_block_sync_noop, 38692 onInput = use_block_sync_noop 38693 }) { 38694 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 38695 const { 38696 resetBlocks, 38697 resetSelection, 38698 replaceInnerBlocks, 38699 setHasControlledInnerBlocks, 38700 __unstableMarkNextChangeAsNotPersistent 38701 } = registry.dispatch(store); 38702 const { 38703 getBlockName, 38704 getBlocks, 38705 getSelectionStart, 38706 getSelectionEnd 38707 } = registry.select(store); 38708 const isControlled = (0,external_wp_data_namespaceObject.useSelect)(select => { 38709 return !clientId || select(store).areInnerBlocksControlled(clientId); 38710 }, [clientId]); 38711 const pendingChangesRef = (0,external_wp_element_namespaceObject.useRef)({ 38712 incoming: null, 38713 outgoing: [] 38714 }); 38715 const subscribedRef = (0,external_wp_element_namespaceObject.useRef)(false); 38716 const setControlledBlocks = () => { 38717 if (!controlledBlocks) { 38718 return; 38719 } 38720 38721 // We don't need to persist this change because we only replace 38722 // controlled inner blocks when the change was caused by an entity, 38723 // and so it would already be persisted. 38724 __unstableMarkNextChangeAsNotPersistent(); 38725 if (clientId) { 38726 // It is important to batch here because otherwise, 38727 // as soon as `setHasControlledInnerBlocks` is called 38728 // the effect to restore might be triggered 38729 // before the actual blocks get set properly in state. 38730 registry.batch(() => { 38731 setHasControlledInnerBlocks(clientId, true); 38732 const storeBlocks = controlledBlocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 38733 if (subscribedRef.current) { 38734 pendingChangesRef.current.incoming = storeBlocks; 38735 } 38736 __unstableMarkNextChangeAsNotPersistent(); 38737 replaceInnerBlocks(clientId, storeBlocks); 38738 }); 38739 } else { 38740 if (subscribedRef.current) { 38741 pendingChangesRef.current.incoming = controlledBlocks; 38742 } 38743 resetBlocks(controlledBlocks); 38744 } 38745 }; 38746 38747 // Clean up the changes made by setControlledBlocks() when the component 38748 // containing useBlockSync() unmounts. 38749 const unsetControlledBlocks = () => { 38750 __unstableMarkNextChangeAsNotPersistent(); 38751 if (clientId) { 38752 setHasControlledInnerBlocks(clientId, false); 38753 __unstableMarkNextChangeAsNotPersistent(); 38754 replaceInnerBlocks(clientId, []); 38755 } else { 38756 resetBlocks([]); 38757 } 38758 }; 38759 38760 // Add a subscription to the block-editor registry to detect when changes 38761 // have been made. This lets us inform the data source of changes. This 38762 // is an effect so that the subscriber can run synchronously without 38763 // waiting for React renders for changes. 38764 const onInputRef = (0,external_wp_element_namespaceObject.useRef)(onInput); 38765 const onChangeRef = (0,external_wp_element_namespaceObject.useRef)(onChange); 38766 (0,external_wp_element_namespaceObject.useEffect)(() => { 38767 onInputRef.current = onInput; 38768 onChangeRef.current = onChange; 38769 }, [onInput, onChange]); 38770 38771 // Determine if blocks need to be reset when they change. 38772 (0,external_wp_element_namespaceObject.useEffect)(() => { 38773 if (pendingChangesRef.current.outgoing.includes(controlledBlocks)) { 38774 // Skip block reset if the value matches expected outbound sync 38775 // triggered by this component by a preceding change detection. 38776 // Only skip if the value matches expectation, since a reset should 38777 // still occur if the value is modified (not equal by reference), 38778 // to allow that the consumer may apply modifications to reflect 38779 // back on the editor. 38780 if (pendingChangesRef.current.outgoing[pendingChangesRef.current.outgoing.length - 1] === controlledBlocks) { 38781 pendingChangesRef.current.outgoing = []; 38782 } 38783 } else if (getBlocks(clientId) !== controlledBlocks) { 38784 // Reset changing value in all other cases than the sync described 38785 // above. Since this can be reached in an update following an out- 38786 // bound sync, unset the outbound value to avoid considering it in 38787 // subsequent renders. 38788 pendingChangesRef.current.outgoing = []; 38789 setControlledBlocks(); 38790 if (controlledSelection) { 38791 resetSelection(controlledSelection.selectionStart, controlledSelection.selectionEnd, controlledSelection.initialPosition); 38792 } 38793 } 38794 }, [controlledBlocks, clientId]); 38795 const isMountedRef = (0,external_wp_element_namespaceObject.useRef)(false); 38796 (0,external_wp_element_namespaceObject.useEffect)(() => { 38797 // On mount, controlled blocks are already set in the effect above. 38798 if (!isMountedRef.current) { 38799 isMountedRef.current = true; 38800 return; 38801 } 38802 38803 // When the block becomes uncontrolled, it means its inner state has been reset 38804 // we need to take the blocks again from the external value property. 38805 if (!isControlled) { 38806 pendingChangesRef.current.outgoing = []; 38807 setControlledBlocks(); 38808 } 38809 }, [isControlled]); 38810 (0,external_wp_element_namespaceObject.useEffect)(() => { 38811 const { 38812 getSelectedBlocksInitialCaretPosition, 38813 isLastBlockChangePersistent, 38814 __unstableIsLastBlockChangeIgnored, 38815 areInnerBlocksControlled 38816 } = registry.select(store); 38817 let blocks = getBlocks(clientId); 38818 let isPersistent = isLastBlockChangePersistent(); 38819 let previousAreBlocksDifferent = false; 38820 subscribedRef.current = true; 38821 const unsubscribe = registry.subscribe(() => { 38822 // Sometimes, when changing block lists, lingering subscriptions 38823 // might trigger before they are cleaned up. If the block for which 38824 // the subscription runs is no longer in the store, this would clear 38825 // its parent entity's block list. To avoid this, we bail out if 38826 // the subscription is triggering for a block (`clientId !== null`) 38827 // and its block name can't be found because it's not on the list. 38828 // (`getBlockName( clientId ) === null`). 38829 if (clientId !== null && getBlockName(clientId) === null) { 38830 return; 38831 } 38832 38833 // When RESET_BLOCKS on parent blocks get called, the controlled blocks 38834 // can reset to uncontrolled, in these situations, it means we need to populate 38835 // the blocks again from the external blocks (the value property here) 38836 // and we should stop triggering onChange 38837 const isStillControlled = !clientId || areInnerBlocksControlled(clientId); 38838 if (!isStillControlled) { 38839 return; 38840 } 38841 const newIsPersistent = isLastBlockChangePersistent(); 38842 const newBlocks = getBlocks(clientId); 38843 const areBlocksDifferent = newBlocks !== blocks; 38844 blocks = newBlocks; 38845 if (areBlocksDifferent && (pendingChangesRef.current.incoming || __unstableIsLastBlockChangeIgnored())) { 38846 pendingChangesRef.current.incoming = null; 38847 isPersistent = newIsPersistent; 38848 return; 38849 } 38850 38851 // Since we often dispatch an action to mark the previous action as 38852 // persistent, we need to make sure that the blocks changed on the 38853 // previous action before committing the change. 38854 const didPersistenceChange = previousAreBlocksDifferent && !areBlocksDifferent && newIsPersistent && !isPersistent; 38855 if (areBlocksDifferent || didPersistenceChange) { 38856 isPersistent = newIsPersistent; 38857 // We know that onChange/onInput will update controlledBlocks. 38858 // We need to be aware that it was caused by an outgoing change 38859 // so that we do not treat it as an incoming change later on, 38860 // which would cause a block reset. 38861 pendingChangesRef.current.outgoing.push(blocks); 38862 38863 // Inform the controlling entity that changes have been made to 38864 // the block-editor store they should be aware about. 38865 const updateParent = isPersistent ? onChangeRef.current : onInputRef.current; 38866 updateParent(blocks, { 38867 selection: { 38868 selectionStart: getSelectionStart(), 38869 selectionEnd: getSelectionEnd(), 38870 initialPosition: getSelectedBlocksInitialCaretPosition() 38871 } 38872 }); 38873 } 38874 previousAreBlocksDifferent = areBlocksDifferent; 38875 }, store); 38876 return () => { 38877 subscribedRef.current = false; 38878 unsubscribe(); 38879 }; 38880 }, [registry, clientId]); 38881 (0,external_wp_element_namespaceObject.useEffect)(() => { 38882 return () => { 38883 unsetControlledBlocks(); 38884 }; 38885 }, []); 38886 } 38887 38888 ;// external ["wp","keyboardShortcuts"] 38889 const external_wp_keyboardShortcuts_namespaceObject = window["wp"]["keyboardShortcuts"]; 38890 ;// ./node_modules/@wordpress/block-editor/build-module/components/keyboard-shortcuts/index.js 38891 /** 38892 * WordPress dependencies 38893 */ 38894 38895 38896 38897 38898 function KeyboardShortcuts() { 38899 return null; 38900 } 38901 function KeyboardShortcutsRegister() { 38902 // Registering the shortcuts. 38903 const { 38904 registerShortcut 38905 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_keyboardShortcuts_namespaceObject.store); 38906 (0,external_wp_element_namespaceObject.useEffect)(() => { 38907 registerShortcut({ 38908 name: 'core/block-editor/copy', 38909 category: 'block', 38910 description: (0,external_wp_i18n_namespaceObject.__)('Copy the selected block(s).'), 38911 keyCombination: { 38912 modifier: 'primary', 38913 character: 'c' 38914 } 38915 }); 38916 registerShortcut({ 38917 name: 'core/block-editor/cut', 38918 category: 'block', 38919 description: (0,external_wp_i18n_namespaceObject.__)('Cut the selected block(s).'), 38920 keyCombination: { 38921 modifier: 'primary', 38922 character: 'x' 38923 } 38924 }); 38925 registerShortcut({ 38926 name: 'core/block-editor/paste', 38927 category: 'block', 38928 description: (0,external_wp_i18n_namespaceObject.__)('Paste the selected block(s).'), 38929 keyCombination: { 38930 modifier: 'primary', 38931 character: 'v' 38932 } 38933 }); 38934 registerShortcut({ 38935 name: 'core/block-editor/duplicate', 38936 category: 'block', 38937 description: (0,external_wp_i18n_namespaceObject.__)('Duplicate the selected block(s).'), 38938 keyCombination: { 38939 modifier: 'primaryShift', 38940 character: 'd' 38941 } 38942 }); 38943 registerShortcut({ 38944 name: 'core/block-editor/remove', 38945 category: 'block', 38946 description: (0,external_wp_i18n_namespaceObject.__)('Remove the selected block(s).'), 38947 keyCombination: { 38948 modifier: 'primaryShift', 38949 character: 'backspace' 38950 } 38951 }); 38952 registerShortcut({ 38953 name: 'core/block-editor/insert-before', 38954 category: 'block', 38955 description: (0,external_wp_i18n_namespaceObject.__)('Insert a new block before the selected block(s).'), 38956 keyCombination: { 38957 modifier: 'primaryAlt', 38958 character: 't' 38959 } 38960 }); 38961 registerShortcut({ 38962 name: 'core/block-editor/insert-after', 38963 category: 'block', 38964 description: (0,external_wp_i18n_namespaceObject.__)('Insert a new block after the selected block(s).'), 38965 keyCombination: { 38966 modifier: 'primaryAlt', 38967 character: 'y' 38968 } 38969 }); 38970 registerShortcut({ 38971 name: 'core/block-editor/delete-multi-selection', 38972 category: 'block', 38973 description: (0,external_wp_i18n_namespaceObject.__)('Delete selection.'), 38974 keyCombination: { 38975 character: 'del' 38976 }, 38977 aliases: [{ 38978 character: 'backspace' 38979 }] 38980 }); 38981 registerShortcut({ 38982 name: 'core/block-editor/select-all', 38983 category: 'selection', 38984 description: (0,external_wp_i18n_namespaceObject.__)('Select all text when typing. Press again to select all blocks.'), 38985 keyCombination: { 38986 modifier: 'primary', 38987 character: 'a' 38988 } 38989 }); 38990 registerShortcut({ 38991 name: 'core/block-editor/unselect', 38992 category: 'selection', 38993 description: (0,external_wp_i18n_namespaceObject.__)('Clear selection.'), 38994 keyCombination: { 38995 character: 'escape' 38996 } 38997 }); 38998 registerShortcut({ 38999 name: 'core/block-editor/multi-text-selection', 39000 category: 'selection', 39001 description: (0,external_wp_i18n_namespaceObject.__)('Select text across multiple blocks.'), 39002 keyCombination: { 39003 modifier: 'shift', 39004 character: 'arrow' 39005 } 39006 }); 39007 registerShortcut({ 39008 name: 'core/block-editor/focus-toolbar', 39009 category: 'global', 39010 description: (0,external_wp_i18n_namespaceObject.__)('Navigate to the nearest toolbar.'), 39011 keyCombination: { 39012 modifier: 'alt', 39013 character: 'F10' 39014 } 39015 }); 39016 registerShortcut({ 39017 name: 'core/block-editor/move-up', 39018 category: 'block', 39019 description: (0,external_wp_i18n_namespaceObject.__)('Move the selected block(s) up.'), 39020 keyCombination: { 39021 modifier: 'secondary', 39022 character: 't' 39023 } 39024 }); 39025 registerShortcut({ 39026 name: 'core/block-editor/move-down', 39027 category: 'block', 39028 description: (0,external_wp_i18n_namespaceObject.__)('Move the selected block(s) down.'), 39029 keyCombination: { 39030 modifier: 'secondary', 39031 character: 'y' 39032 } 39033 }); 39034 39035 // List view shortcuts. 39036 registerShortcut({ 39037 name: 'core/block-editor/collapse-list-view', 39038 category: 'list-view', 39039 description: (0,external_wp_i18n_namespaceObject.__)('Collapse all other items.'), 39040 keyCombination: { 39041 modifier: 'alt', 39042 character: 'l' 39043 } 39044 }); 39045 registerShortcut({ 39046 name: 'core/block-editor/group', 39047 category: 'block', 39048 description: (0,external_wp_i18n_namespaceObject.__)('Create a group block from the selected multiple blocks.'), 39049 keyCombination: { 39050 modifier: 'primary', 39051 character: 'g' 39052 } 39053 }); 39054 }, [registerShortcut]); 39055 return null; 39056 } 39057 KeyboardShortcuts.Register = KeyboardShortcutsRegister; 39058 /* harmony default export */ const keyboard_shortcuts = (KeyboardShortcuts); 39059 39060 ;// ./node_modules/@wordpress/block-editor/build-module/components/provider/use-media-upload-settings.js 39061 /** 39062 * WordPress dependencies 39063 */ 39064 39065 39066 /** 39067 * React hook used to compute the media upload settings to use in the post editor. 39068 * 39069 * @param {Object} settings Media upload settings prop. 39070 * 39071 * @return {Object} Media upload settings. 39072 */ 39073 function useMediaUploadSettings(settings = {}) { 39074 return (0,external_wp_element_namespaceObject.useMemo)(() => ({ 39075 mediaUpload: settings.mediaUpload, 39076 mediaSideload: settings.mediaSideload, 39077 maxUploadFileSize: settings.maxUploadFileSize, 39078 allowedMimeTypes: settings.allowedMimeTypes 39079 }), [settings]); 39080 } 39081 /* harmony default export */ const use_media_upload_settings = (useMediaUploadSettings); 39082 39083 ;// ./node_modules/@wordpress/block-editor/build-module/components/provider/index.js 39084 /** 39085 * WordPress dependencies 39086 */ 39087 39088 39089 39090 39091 39092 /** 39093 * Internal dependencies 39094 */ 39095 39096 39097 39098 39099 39100 39101 39102 39103 /** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */ 39104 39105 const provider_noop = () => {}; 39106 39107 /** 39108 * Upload a media file when the file upload button is activated 39109 * or when adding a file to the editor via drag & drop. 39110 * 39111 * @param {WPDataRegistry} registry 39112 * @param {Object} $3 Parameters object passed to the function. 39113 * @param {Array} $3.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed. 39114 * @param {Object} $3.additionalData Additional data to include in the request. 39115 * @param {Array<File>} $3.filesList List of files. 39116 * @param {Function} $3.onError Function called when an error happens. 39117 * @param {Function} $3.onFileChange Function called each time a file or a temporary representation of the file is available. 39118 * @param {Function} $3.onSuccess Function called once a file has completely finished uploading, including thumbnails. 39119 * @param {Function} $3.onBatchSuccess Function called once all files in a group have completely finished uploading, including thumbnails. 39120 */ 39121 function mediaUpload(registry, { 39122 allowedTypes, 39123 additionalData = {}, 39124 filesList, 39125 onError = provider_noop, 39126 onFileChange, 39127 onSuccess, 39128 onBatchSuccess 39129 }) { 39130 void registry.dispatch(store_store).addItems({ 39131 files: filesList, 39132 onChange: onFileChange, 39133 onSuccess, 39134 onBatchSuccess, 39135 onError: ({ 39136 message 39137 }) => onError(message), 39138 additionalData, 39139 allowedTypes 39140 }); 39141 } 39142 const ExperimentalBlockEditorProvider = provider_with_registry_provider(props => { 39143 const { 39144 settings: _settings, 39145 registry, 39146 stripExperimentalSettings = false 39147 } = props; 39148 const mediaUploadSettings = use_media_upload_settings(_settings); 39149 let settings = _settings; 39150 if (window.__experimentalMediaProcessing && _settings.mediaUpload) { 39151 // Create a new variable so that the original props.settings.mediaUpload is not modified. 39152 settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 39153 ..._settings, 39154 mediaUpload: mediaUpload.bind(null, registry) 39155 }), [_settings, registry]); 39156 } 39157 const { 39158 __experimentalUpdateSettings 39159 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 39160 (0,external_wp_element_namespaceObject.useEffect)(() => { 39161 __experimentalUpdateSettings({ 39162 ...settings, 39163 __internalIsInitialized: true 39164 }, { 39165 stripExperimentalSettings, 39166 reset: true 39167 }); 39168 }, [settings, stripExperimentalSettings, __experimentalUpdateSettings]); 39169 39170 // Syncs the entity provider with changes in the block-editor store. 39171 useBlockSync(props); 39172 const children = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.SlotFillProvider, { 39173 passthrough: true, 39174 children: [!settings?.isPreviewMode && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(keyboard_shortcuts.Register, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockRefsProvider, { 39175 children: props.children 39176 })] 39177 }); 39178 if (window.__experimentalMediaProcessing) { 39179 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(provider, { 39180 settings: mediaUploadSettings, 39181 useSubRegistry: false, 39182 children: children 39183 }); 39184 } 39185 return children; 39186 }); 39187 const BlockEditorProvider = props => { 39188 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ExperimentalBlockEditorProvider, { 39189 ...props, 39190 stripExperimentalSettings: true, 39191 children: props.children 39192 }); 39193 }; 39194 /* harmony default export */ const components_provider = (BlockEditorProvider); 39195 39196 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-context/index.js 39197 /** 39198 * WordPress dependencies 39199 */ 39200 39201 39202 /** @typedef {import('react').ReactNode} ReactNode */ 39203 39204 /** 39205 * @typedef BlockContextProviderProps 39206 * 39207 * @property {Record<string,*>} value Context value to merge with current 39208 * value. 39209 * @property {ReactNode} children Component children. 39210 */ 39211 39212 /** @type {import('react').Context<Record<string,*>>} */ 39213 39214 const block_context_Context = (0,external_wp_element_namespaceObject.createContext)({}); 39215 39216 /** 39217 * Component which merges passed value with current consumed block context. 39218 * 39219 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-context/README.md 39220 * 39221 * @param {BlockContextProviderProps} props 39222 */ 39223 function BlockContextProvider({ 39224 value, 39225 children 39226 }) { 39227 const context = (0,external_wp_element_namespaceObject.useContext)(block_context_Context); 39228 const nextValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 39229 ...context, 39230 ...value 39231 }), [context, value]); 39232 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_context_Context.Provider, { 39233 value: nextValue, 39234 children: children 39235 }); 39236 } 39237 /* harmony default export */ const block_context = (block_context_Context); 39238 39239 ;// ./node_modules/@wordpress/block-editor/build-module/utils/block-bindings.js 39240 /** 39241 * WordPress dependencies 39242 */ 39243 39244 39245 /** 39246 * Internal dependencies 39247 */ 39248 39249 39250 const DEFAULT_ATTRIBUTE = '__default'; 39251 const PATTERN_OVERRIDES_SOURCE = 'core/pattern-overrides'; 39252 const BLOCK_BINDINGS_ALLOWED_BLOCKS = { 39253 'core/paragraph': ['content'], 39254 'core/heading': ['content'], 39255 'core/image': ['id', 'url', 'title', 'alt'], 39256 'core/button': ['url', 'text', 'linkTarget', 'rel'] 39257 }; 39258 39259 /** 39260 * Checks if the given object is empty. 39261 * 39262 * @param {?Object} object The object to check. 39263 * 39264 * @return {boolean} Whether the object is empty. 39265 */ 39266 function isObjectEmpty(object) { 39267 return !object || Object.keys(object).length === 0; 39268 } 39269 39270 /** 39271 * Based on the given block name, checks if it is possible to bind the block. 39272 * 39273 * @param {string} blockName The name of the block. 39274 * 39275 * @return {boolean} Whether it is possible to bind the block to sources. 39276 */ 39277 function canBindBlock(blockName) { 39278 return blockName in BLOCK_BINDINGS_ALLOWED_BLOCKS; 39279 } 39280 39281 /** 39282 * Based on the given block name and attribute name, checks if it is possible to bind the block attribute. 39283 * 39284 * @param {string} blockName The name of the block. 39285 * @param {string} attributeName The name of attribute. 39286 * 39287 * @return {boolean} Whether it is possible to bind the block attribute. 39288 */ 39289 function canBindAttribute(blockName, attributeName) { 39290 return canBindBlock(blockName) && BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName].includes(attributeName); 39291 } 39292 39293 /** 39294 * Gets the bindable attributes for a given block. 39295 * 39296 * @param {string} blockName The name of the block. 39297 * 39298 * @return {string[]} The bindable attributes for the block. 39299 */ 39300 function getBindableAttributes(blockName) { 39301 return BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName]; 39302 } 39303 39304 /** 39305 * Checks if the block has the `__default` binding for pattern overrides. 39306 * 39307 * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute. 39308 * 39309 * @return {boolean} Whether the block has the `__default` binding for pattern overrides. 39310 */ 39311 function hasPatternOverridesDefaultBinding(bindings) { 39312 return bindings?.[DEFAULT_ATTRIBUTE]?.source === PATTERN_OVERRIDES_SOURCE; 39313 } 39314 39315 /** 39316 * Returns the bindings with the `__default` binding for pattern overrides 39317 * replaced with the full-set of supported attributes. e.g.: 39318 * 39319 * - bindings passed in: `{ __default: { source: 'core/pattern-overrides' } }` 39320 * - bindings returned: `{ content: { source: 'core/pattern-overrides' } }` 39321 * 39322 * @param {string} blockName The block name (e.g. 'core/paragraph'). 39323 * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute. 39324 * 39325 * @return {Object} The bindings with default replaced for pattern overrides. 39326 */ 39327 function replacePatternOverridesDefaultBinding(blockName, bindings) { 39328 // The `__default` binding currently only works for pattern overrides. 39329 if (hasPatternOverridesDefaultBinding(bindings)) { 39330 const supportedAttributes = BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName]; 39331 const bindingsWithDefaults = {}; 39332 for (const attributeName of supportedAttributes) { 39333 // If the block has mixed binding sources, retain any non pattern override bindings. 39334 const bindingSource = bindings[attributeName] ? bindings[attributeName] : { 39335 source: PATTERN_OVERRIDES_SOURCE 39336 }; 39337 bindingsWithDefaults[attributeName] = bindingSource; 39338 } 39339 return bindingsWithDefaults; 39340 } 39341 return bindings; 39342 } 39343 39344 /** 39345 * Contains utils to update the block `bindings` metadata. 39346 * 39347 * @typedef {Object} WPBlockBindingsUtils 39348 * 39349 * @property {Function} updateBlockBindings Updates the value of the bindings connected to block attributes. 39350 * @property {Function} removeAllBlockBindings Removes the bindings property of the `metadata` attribute. 39351 */ 39352 39353 /** 39354 * Retrieves the existing utils needed to update the block `bindings` metadata. 39355 * They can be used to create, modify, or remove connections from the existing block attributes. 39356 * 39357 * It contains the following utils: 39358 * - `updateBlockBindings`: Updates the value of the bindings connected to block attributes. It can be used to remove a specific binding by setting the value to `undefined`. 39359 * - `removeAllBlockBindings`: Removes the bindings property of the `metadata` attribute. 39360 * 39361 * @since 6.7.0 Introduced in WordPress core. 39362 * 39363 * @param {?string} clientId Optional block client ID. If not set, it will use the current block client ID from the context. 39364 * 39365 * @return {?WPBlockBindingsUtils} Object containing the block bindings utils. 39366 * 39367 * @example 39368 * ```js 39369 * import { useBlockBindingsUtils } from '@wordpress/block-editor' 39370 * const { updateBlockBindings, removeAllBlockBindings } = useBlockBindingsUtils(); 39371 * 39372 * // Update url and alt attributes. 39373 * updateBlockBindings( { 39374 * url: { 39375 * source: 'core/post-meta', 39376 * args: { 39377 * key: 'url_custom_field', 39378 * }, 39379 * }, 39380 * alt: { 39381 * source: 'core/post-meta', 39382 * args: { 39383 * key: 'text_custom_field', 39384 * }, 39385 * }, 39386 * } ); 39387 * 39388 * // Remove binding from url attribute. 39389 * updateBlockBindings( { url: undefined } ); 39390 * 39391 * // Remove bindings from all attributes. 39392 * removeAllBlockBindings(); 39393 * ``` 39394 */ 39395 function useBlockBindingsUtils(clientId) { 39396 const { 39397 clientId: contextClientId 39398 } = useBlockEditContext(); 39399 const blockClientId = clientId || contextClientId; 39400 const { 39401 updateBlockAttributes 39402 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39403 const { 39404 getBlockAttributes 39405 } = (0,external_wp_data_namespaceObject.useRegistry)().select(store); 39406 39407 /** 39408 * Updates the value of the bindings connected to block attributes. 39409 * It removes the binding when the new value is `undefined`. 39410 * 39411 * @param {Object} bindings Bindings including the attributes to update and the new object. 39412 * @param {string} bindings.source The source name to connect to. 39413 * @param {Object} [bindings.args] Object containing the arguments needed by the source. 39414 * 39415 * @example 39416 * ```js 39417 * import { useBlockBindingsUtils } from '@wordpress/block-editor' 39418 * 39419 * const { updateBlockBindings } = useBlockBindingsUtils(); 39420 * updateBlockBindings( { 39421 * url: { 39422 * source: 'core/post-meta', 39423 * args: { 39424 * key: 'url_custom_field', 39425 * }, 39426 * }, 39427 * alt: { 39428 * source: 'core/post-meta', 39429 * args: { 39430 * key: 'text_custom_field', 39431 * }, 39432 * } 39433 * } ); 39434 * ``` 39435 */ 39436 const updateBlockBindings = bindings => { 39437 const { 39438 metadata: { 39439 bindings: currentBindings, 39440 ...metadata 39441 } = {} 39442 } = getBlockAttributes(blockClientId); 39443 const newBindings = { 39444 ...currentBindings 39445 }; 39446 Object.entries(bindings).forEach(([attribute, binding]) => { 39447 if (!binding && newBindings[attribute]) { 39448 delete newBindings[attribute]; 39449 return; 39450 } 39451 newBindings[attribute] = binding; 39452 }); 39453 const newMetadata = { 39454 ...metadata, 39455 bindings: newBindings 39456 }; 39457 if (isObjectEmpty(newMetadata.bindings)) { 39458 delete newMetadata.bindings; 39459 } 39460 updateBlockAttributes(blockClientId, { 39461 metadata: isObjectEmpty(newMetadata) ? undefined : newMetadata 39462 }); 39463 }; 39464 39465 /** 39466 * Removes the bindings property of the `metadata` attribute. 39467 * 39468 * @example 39469 * ```js 39470 * import { useBlockBindingsUtils } from '@wordpress/block-editor' 39471 * 39472 * const { removeAllBlockBindings } = useBlockBindingsUtils(); 39473 * removeAllBlockBindings(); 39474 * ``` 39475 */ 39476 const removeAllBlockBindings = () => { 39477 const { 39478 metadata: { 39479 bindings, 39480 ...metadata 39481 } = {} 39482 } = getBlockAttributes(blockClientId); 39483 updateBlockAttributes(blockClientId, { 39484 metadata: isObjectEmpty(metadata) ? undefined : metadata 39485 }); 39486 }; 39487 return { 39488 updateBlockBindings, 39489 removeAllBlockBindings 39490 }; 39491 } 39492 39493 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-edit/edit.js 39494 /** 39495 * External dependencies 39496 */ 39497 39498 39499 /** 39500 * WordPress dependencies 39501 */ 39502 39503 39504 39505 39506 39507 /** 39508 * Internal dependencies 39509 */ 39510 39511 39512 39513 39514 39515 /** 39516 * Default value used for blocks which do not define their own context needs, 39517 * used to guarantee that a block's `context` prop will always be an object. It 39518 * is assigned as a constant since it is always expected to be an empty object, 39519 * and in order to avoid unnecessary React reconciliations of a changing object. 39520 * 39521 * @type {{}} 39522 */ 39523 39524 const DEFAULT_BLOCK_CONTEXT = {}; 39525 const Edit = props => { 39526 const { 39527 name 39528 } = props; 39529 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 39530 if (!blockType) { 39531 return null; 39532 } 39533 39534 // `edit` and `save` are functions or components describing the markup 39535 // with which a block is displayed. If `blockType` is valid, assign 39536 // them preferentially as the render value for the block. 39537 const Component = blockType.edit || blockType.save; 39538 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Component, { 39539 ...props 39540 }); 39541 }; 39542 const EditWithFilters = (0,external_wp_components_namespaceObject.withFilters)('editor.BlockEdit')(Edit); 39543 const EditWithGeneratedProps = props => { 39544 const { 39545 name, 39546 clientId, 39547 attributes, 39548 setAttributes 39549 } = props; 39550 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 39551 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 39552 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 39553 const registeredSources = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(external_wp_blocks_namespaceObject.store)).getAllBlockBindingsSources(), []); 39554 const { 39555 blockBindings, 39556 context, 39557 hasPatternOverrides 39558 } = (0,external_wp_element_namespaceObject.useMemo)(() => { 39559 // Assign context values using the block type's declared context needs. 39560 const computedContext = blockType?.usesContext ? Object.fromEntries(Object.entries(blockContext).filter(([key]) => blockType.usesContext.includes(key))) : DEFAULT_BLOCK_CONTEXT; 39561 // Add context requested by Block Bindings sources. 39562 if (attributes?.metadata?.bindings) { 39563 Object.values(attributes?.metadata?.bindings || {}).forEach(binding => { 39564 registeredSources[binding?.source]?.usesContext?.forEach(key => { 39565 computedContext[key] = blockContext[key]; 39566 }); 39567 }); 39568 } 39569 return { 39570 blockBindings: replacePatternOverridesDefaultBinding(name, attributes?.metadata?.bindings), 39571 context: computedContext, 39572 hasPatternOverrides: hasPatternOverridesDefaultBinding(attributes?.metadata?.bindings) 39573 }; 39574 }, [name, blockType?.usesContext, blockContext, attributes?.metadata?.bindings, registeredSources]); 39575 const computedAttributes = (0,external_wp_data_namespaceObject.useSelect)(select => { 39576 if (!blockBindings) { 39577 return attributes; 39578 } 39579 const attributesFromSources = {}; 39580 const blockBindingsBySource = new Map(); 39581 for (const [attributeName, binding] of Object.entries(blockBindings)) { 39582 const { 39583 source: sourceName, 39584 args: sourceArgs 39585 } = binding; 39586 const source = registeredSources[sourceName]; 39587 if (!source || !canBindAttribute(name, attributeName)) { 39588 continue; 39589 } 39590 blockBindingsBySource.set(source, { 39591 ...blockBindingsBySource.get(source), 39592 [attributeName]: { 39593 args: sourceArgs 39594 } 39595 }); 39596 } 39597 if (blockBindingsBySource.size) { 39598 for (const [source, bindings] of blockBindingsBySource) { 39599 // Get values in batch if the source supports it. 39600 let values = {}; 39601 if (!source.getValues) { 39602 Object.keys(bindings).forEach(attr => { 39603 // Default to the the source label when `getValues` doesn't exist. 39604 values[attr] = source.label; 39605 }); 39606 } else { 39607 values = source.getValues({ 39608 select, 39609 context, 39610 clientId, 39611 bindings 39612 }); 39613 } 39614 for (const [attributeName, value] of Object.entries(values)) { 39615 if (attributeName === 'url' && (!value || !isURLLike(value))) { 39616 // Return null if value is not a valid URL. 39617 attributesFromSources[attributeName] = null; 39618 } else { 39619 attributesFromSources[attributeName] = value; 39620 } 39621 } 39622 } 39623 } 39624 return { 39625 ...attributes, 39626 ...attributesFromSources 39627 }; 39628 }, [attributes, blockBindings, clientId, context, name, registeredSources]); 39629 const setBoundAttributes = (0,external_wp_element_namespaceObject.useCallback)(nextAttributes => { 39630 if (!blockBindings) { 39631 setAttributes(nextAttributes); 39632 return; 39633 } 39634 registry.batch(() => { 39635 const keptAttributes = { 39636 ...nextAttributes 39637 }; 39638 const blockBindingsBySource = new Map(); 39639 39640 // Loop only over the updated attributes to avoid modifying the bound ones that haven't changed. 39641 for (const [attributeName, newValue] of Object.entries(keptAttributes)) { 39642 if (!blockBindings[attributeName] || !canBindAttribute(name, attributeName)) { 39643 continue; 39644 } 39645 const binding = blockBindings[attributeName]; 39646 const source = registeredSources[binding?.source]; 39647 if (!source?.setValues) { 39648 continue; 39649 } 39650 blockBindingsBySource.set(source, { 39651 ...blockBindingsBySource.get(source), 39652 [attributeName]: { 39653 args: binding.args, 39654 newValue 39655 } 39656 }); 39657 delete keptAttributes[attributeName]; 39658 } 39659 if (blockBindingsBySource.size) { 39660 for (const [source, bindings] of blockBindingsBySource) { 39661 source.setValues({ 39662 select: registry.select, 39663 dispatch: registry.dispatch, 39664 context, 39665 clientId, 39666 bindings 39667 }); 39668 } 39669 } 39670 const hasParentPattern = !!context['pattern/overrides']; 39671 if ( 39672 // Don't update non-connected attributes if the block is using pattern overrides 39673 // and the editing is happening while overriding the pattern (not editing the original). 39674 !(hasPatternOverrides && hasParentPattern) && Object.keys(keptAttributes).length) { 39675 // Don't update caption and href until they are supported. 39676 if (hasPatternOverrides) { 39677 delete keptAttributes.caption; 39678 delete keptAttributes.href; 39679 } 39680 setAttributes(keptAttributes); 39681 } 39682 }); 39683 }, [blockBindings, clientId, context, hasPatternOverrides, setAttributes, registeredSources, name, registry]); 39684 if (!blockType) { 39685 return null; 39686 } 39687 if (blockType.apiVersion > 1) { 39688 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EditWithFilters, { 39689 ...props, 39690 attributes: computedAttributes, 39691 context: context, 39692 setAttributes: setBoundAttributes 39693 }); 39694 } 39695 39696 // Generate a class name for the block's editable form. 39697 const generatedClassName = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'className', true) ? (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(name) : null; 39698 const className = dist_clsx(generatedClassName, attributes?.className, props.className); 39699 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EditWithFilters, { 39700 ...props, 39701 attributes: computedAttributes, 39702 className: className, 39703 context: context, 39704 setAttributes: setBoundAttributes 39705 }); 39706 }; 39707 /* harmony default export */ const block_edit_edit = (EditWithGeneratedProps); 39708 39709 ;// ./node_modules/@wordpress/icons/build-module/library/more-vertical.js 39710 /** 39711 * WordPress dependencies 39712 */ 39713 39714 39715 const moreVertical = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 39716 xmlns: "http://www.w3.org/2000/svg", 39717 viewBox: "0 0 24 24", 39718 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 39719 d: "M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z" 39720 }) 39721 }); 39722 /* harmony default export */ const more_vertical = (moreVertical); 39723 39724 ;// ./node_modules/@wordpress/block-editor/build-module/components/warning/index.js 39725 /** 39726 * External dependencies 39727 */ 39728 39729 39730 /** 39731 * WordPress dependencies 39732 */ 39733 39734 39735 39736 39737 function Warning({ 39738 className, 39739 actions, 39740 children, 39741 secondaryActions 39742 }) { 39743 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 39744 style: { 39745 display: 'contents', 39746 all: 'initial' 39747 }, 39748 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 39749 className: dist_clsx(className, 'block-editor-warning'), 39750 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 39751 className: "block-editor-warning__contents", 39752 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 39753 className: "block-editor-warning__message", 39754 children: children 39755 }), (actions?.length > 0 || secondaryActions) && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 39756 className: "block-editor-warning__actions", 39757 children: [actions?.length > 0 && actions.map((action, i) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 39758 className: "block-editor-warning__action", 39759 children: action 39760 }, i)), secondaryActions && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 39761 className: "block-editor-warning__secondary", 39762 icon: more_vertical, 39763 label: (0,external_wp_i18n_namespaceObject.__)('More options'), 39764 popoverProps: { 39765 position: 'bottom left', 39766 className: 'block-editor-warning__dropdown' 39767 }, 39768 noIcons: true, 39769 children: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 39770 children: secondaryActions.map((item, pos) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 39771 onClick: item.onClick, 39772 children: item.title 39773 }, pos)) 39774 }) 39775 })] 39776 })] 39777 }) 39778 }) 39779 }); 39780 } 39781 39782 /** 39783 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/warning/README.md 39784 */ 39785 /* harmony default export */ const warning = (Warning); 39786 39787 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-edit/multiple-usage-warning.js 39788 /** 39789 * WordPress dependencies 39790 */ 39791 39792 39793 39794 39795 39796 /** 39797 * Internal dependencies 39798 */ 39799 39800 39801 39802 function MultipleUsageWarning({ 39803 originalBlockClientId, 39804 name, 39805 onReplace 39806 }) { 39807 const { 39808 selectBlock 39809 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 39810 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 39811 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(warning, { 39812 actions: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 39813 __next40pxDefaultSize: true, 39814 variant: "secondary", 39815 onClick: () => selectBlock(originalBlockClientId), 39816 children: (0,external_wp_i18n_namespaceObject.__)('Find original') 39817 }, "find-original"), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 39818 __next40pxDefaultSize: true, 39819 variant: "secondary", 39820 onClick: () => onReplace([]), 39821 children: (0,external_wp_i18n_namespaceObject.__)('Remove') 39822 }, "remove")], 39823 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("strong", { 39824 children: [blockType?.title, ": "] 39825 }), (0,external_wp_i18n_namespaceObject.__)('This block can only be used once.')] 39826 }); 39827 } 39828 39829 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/private-block-context.js 39830 /** 39831 * WordPress dependencies 39832 */ 39833 39834 const PrivateBlockContext = (0,external_wp_element_namespaceObject.createContext)({}); 39835 39836 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-edit/index.js 39837 /** 39838 * WordPress dependencies 39839 */ 39840 39841 39842 39843 /** 39844 * Internal dependencies 39845 */ 39846 39847 39848 39849 39850 39851 /** 39852 * The `useBlockEditContext` hook provides information about the block this hook is being used in. 39853 * It returns an object with the `name`, `isSelected` state, and the `clientId` of the block. 39854 * It is useful if you want to create custom hooks that need access to the current blocks clientId 39855 * but don't want to rely on the data getting passed in as a parameter. 39856 * 39857 * @return {Object} Block edit context 39858 */ 39859 39860 39861 function BlockEdit({ 39862 mayDisplayControls, 39863 mayDisplayParentControls, 39864 blockEditingMode, 39865 isPreviewMode, 39866 // The remaining props are passed through the BlockEdit filters and are thus 39867 // public API! 39868 ...props 39869 }) { 39870 const { 39871 name, 39872 isSelected, 39873 clientId, 39874 attributes = {}, 39875 __unstableLayoutClassNames 39876 } = props; 39877 const { 39878 layout = null, 39879 metadata = {} 39880 } = attributes; 39881 const { 39882 bindings 39883 } = metadata; 39884 const layoutSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'layout', false) || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, '__experimentalLayout', false); 39885 const { 39886 originalBlockClientId 39887 } = (0,external_wp_element_namespaceObject.useContext)(PrivateBlockContext); 39888 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Provider 39889 // It is important to return the same object if props haven't 39890 // changed to avoid unnecessary rerenders. 39891 // See https://reactjs.org/docs/context.html#caveats. 39892 , { 39893 value: (0,external_wp_element_namespaceObject.useMemo)(() => ({ 39894 name, 39895 isSelected, 39896 clientId, 39897 layout: layoutSupport ? layout : null, 39898 __unstableLayoutClassNames, 39899 // We use symbols in favour of an __unstable prefix to avoid 39900 // usage outside of the package (this context is exposed). 39901 [mayDisplayControlsKey]: mayDisplayControls, 39902 [mayDisplayParentControlsKey]: mayDisplayParentControls, 39903 [blockEditingModeKey]: blockEditingMode, 39904 [blockBindingsKey]: bindings, 39905 [isPreviewModeKey]: isPreviewMode 39906 }), [name, isSelected, clientId, layoutSupport, layout, __unstableLayoutClassNames, mayDisplayControls, mayDisplayParentControls, blockEditingMode, bindings, isPreviewMode]), 39907 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_edit_edit, { 39908 ...props 39909 }), originalBlockClientId && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MultipleUsageWarning, { 39910 originalBlockClientId: originalBlockClientId, 39911 name: name, 39912 onReplace: props.onReplace 39913 })] 39914 }); 39915 } 39916 39917 // EXTERNAL MODULE: ./node_modules/diff/lib/diff/character.js 39918 var character = __webpack_require__(8021); 39919 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-compare/block-view.js 39920 /** 39921 * WordPress dependencies 39922 */ 39923 39924 39925 39926 39927 function BlockView({ 39928 title, 39929 rawContent, 39930 renderedContent, 39931 action, 39932 actionText, 39933 className 39934 }) { 39935 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 39936 className: className, 39937 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 39938 className: "block-editor-block-compare__content", 39939 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("h2", { 39940 className: "block-editor-block-compare__heading", 39941 children: title 39942 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 39943 className: "block-editor-block-compare__html", 39944 children: rawContent 39945 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 39946 className: "block-editor-block-compare__preview edit-post-visual-editor", 39947 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.RawHTML, { 39948 children: (0,external_wp_dom_namespaceObject.safeHTML)(renderedContent) 39949 }) 39950 })] 39951 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 39952 className: "block-editor-block-compare__action", 39953 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 39954 __next40pxDefaultSize: true, 39955 variant: "secondary", 39956 tabIndex: "0", 39957 onClick: action, 39958 children: actionText 39959 }) 39960 })] 39961 }); 39962 } 39963 39964 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-compare/index.js 39965 /** 39966 * External dependencies 39967 */ 39968 39969 // diff doesn't tree-shake correctly, so we import from the individual 39970 // module here, to avoid including too much of the library 39971 39972 39973 /** 39974 * WordPress dependencies 39975 */ 39976 39977 39978 39979 /** 39980 * Internal dependencies 39981 */ 39982 39983 39984 function BlockCompare({ 39985 block, 39986 onKeep, 39987 onConvert, 39988 convertor, 39989 convertButtonText 39990 }) { 39991 function getDifference(originalContent, newContent) { 39992 const difference = (0,character/* diffChars */.JJ)(originalContent, newContent); 39993 return difference.map((item, pos) => { 39994 const classes = dist_clsx({ 39995 'block-editor-block-compare__added': item.added, 39996 'block-editor-block-compare__removed': item.removed 39997 }); 39998 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 39999 className: classes, 40000 children: item.value 40001 }, pos); 40002 }); 40003 } 40004 function getConvertedContent(convertedBlock) { 40005 // The convertor may return an array of items or a single item. 40006 const newBlocks = Array.isArray(convertedBlock) ? convertedBlock : [convertedBlock]; 40007 40008 // Get converted block details. 40009 const newContent = newBlocks.map(item => (0,external_wp_blocks_namespaceObject.getSaveContent)(item.name, item.attributes, item.innerBlocks)); 40010 return newContent.join(''); 40011 } 40012 const converted = getConvertedContent(convertor(block)); 40013 const difference = getDifference(block.originalContent, converted); 40014 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 40015 className: "block-editor-block-compare__wrapper", 40016 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockView, { 40017 title: (0,external_wp_i18n_namespaceObject.__)('Current'), 40018 className: "block-editor-block-compare__current", 40019 action: onKeep, 40020 actionText: (0,external_wp_i18n_namespaceObject.__)('Convert to HTML'), 40021 rawContent: block.originalContent, 40022 renderedContent: block.originalContent 40023 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockView, { 40024 title: (0,external_wp_i18n_namespaceObject.__)('After Conversion'), 40025 className: "block-editor-block-compare__converted", 40026 action: onConvert, 40027 actionText: convertButtonText, 40028 rawContent: difference, 40029 renderedContent: converted 40030 })] 40031 }); 40032 } 40033 /* harmony default export */ const block_compare = (BlockCompare); 40034 40035 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-invalid-warning.js 40036 /** 40037 * WordPress dependencies 40038 */ 40039 40040 40041 40042 40043 40044 40045 /** 40046 * Internal dependencies 40047 */ 40048 40049 40050 40051 40052 const blockToBlocks = block => (0,external_wp_blocks_namespaceObject.rawHandler)({ 40053 HTML: block.originalContent 40054 }); 40055 function BlockInvalidWarning({ 40056 clientId 40057 }) { 40058 const { 40059 block, 40060 canInsertHTMLBlock, 40061 canInsertClassicBlock 40062 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 40063 const { 40064 canInsertBlockType, 40065 getBlock, 40066 getBlockRootClientId 40067 } = select(store); 40068 const rootClientId = getBlockRootClientId(clientId); 40069 return { 40070 block: getBlock(clientId), 40071 canInsertHTMLBlock: canInsertBlockType('core/html', rootClientId), 40072 canInsertClassicBlock: canInsertBlockType('core/freeform', rootClientId) 40073 }; 40074 }, [clientId]); 40075 const { 40076 replaceBlock 40077 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 40078 const [compare, setCompare] = (0,external_wp_element_namespaceObject.useState)(false); 40079 const onCompareClose = (0,external_wp_element_namespaceObject.useCallback)(() => setCompare(false), []); 40080 const convert = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 40081 toClassic() { 40082 const classicBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/freeform', { 40083 content: block.originalContent 40084 }); 40085 return replaceBlock(block.clientId, classicBlock); 40086 }, 40087 toHTML() { 40088 const htmlBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/html', { 40089 content: block.originalContent 40090 }); 40091 return replaceBlock(block.clientId, htmlBlock); 40092 }, 40093 toBlocks() { 40094 const newBlocks = blockToBlocks(block); 40095 return replaceBlock(block.clientId, newBlocks); 40096 }, 40097 toRecoveredBlock() { 40098 const recoveredBlock = (0,external_wp_blocks_namespaceObject.createBlock)(block.name, block.attributes, block.innerBlocks); 40099 return replaceBlock(block.clientId, recoveredBlock); 40100 } 40101 }), [block, replaceBlock]); 40102 const secondaryActions = (0,external_wp_element_namespaceObject.useMemo)(() => [{ 40103 // translators: Button to fix block content 40104 title: (0,external_wp_i18n_namespaceObject._x)('Resolve', 'imperative verb'), 40105 onClick: () => setCompare(true) 40106 }, canInsertHTMLBlock && { 40107 title: (0,external_wp_i18n_namespaceObject.__)('Convert to HTML'), 40108 onClick: convert.toHTML 40109 }, canInsertClassicBlock && { 40110 title: (0,external_wp_i18n_namespaceObject.__)('Convert to Classic Block'), 40111 onClick: convert.toClassic 40112 }].filter(Boolean), [canInsertHTMLBlock, canInsertClassicBlock, convert]); 40113 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 40114 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(warning, { 40115 actions: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 40116 __next40pxDefaultSize: true, 40117 onClick: convert.toRecoveredBlock, 40118 variant: "primary", 40119 children: (0,external_wp_i18n_namespaceObject.__)('Attempt recovery') 40120 }, "recover")], 40121 secondaryActions: secondaryActions, 40122 children: (0,external_wp_i18n_namespaceObject.__)('Block contains unexpected or invalid content.') 40123 }), compare && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Modal, { 40124 title: 40125 // translators: Dialog title to fix block content 40126 (0,external_wp_i18n_namespaceObject.__)('Resolve Block'), 40127 onRequestClose: onCompareClose, 40128 className: "block-editor-block-compare", 40129 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_compare, { 40130 block: block, 40131 onKeep: convert.toHTML, 40132 onConvert: convert.toBlocks, 40133 convertor: blockToBlocks, 40134 convertButtonText: (0,external_wp_i18n_namespaceObject.__)('Convert to Blocks') 40135 }) 40136 })] 40137 }); 40138 } 40139 40140 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-crash-warning.js 40141 /** 40142 * WordPress dependencies 40143 */ 40144 40145 40146 /** 40147 * Internal dependencies 40148 */ 40149 40150 40151 const block_crash_warning_warning = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(warning, { 40152 className: "block-editor-block-list__block-crash-warning", 40153 children: (0,external_wp_i18n_namespaceObject.__)('This block has encountered an error and cannot be previewed.') 40154 }); 40155 /* harmony default export */ const block_crash_warning = (() => block_crash_warning_warning); 40156 40157 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-crash-boundary.js 40158 /** 40159 * WordPress dependencies 40160 */ 40161 40162 class BlockCrashBoundary extends external_wp_element_namespaceObject.Component { 40163 constructor() { 40164 super(...arguments); 40165 this.state = { 40166 hasError: false 40167 }; 40168 } 40169 componentDidCatch() { 40170 this.setState({ 40171 hasError: true 40172 }); 40173 } 40174 render() { 40175 if (this.state.hasError) { 40176 return this.props.fallback; 40177 } 40178 return this.props.children; 40179 } 40180 } 40181 /* harmony default export */ const block_crash_boundary = (BlockCrashBoundary); 40182 40183 // EXTERNAL MODULE: ./node_modules/react-autosize-textarea/lib/index.js 40184 var lib = __webpack_require__(4132); 40185 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-html.js 40186 /** 40187 * External dependencies 40188 */ 40189 40190 40191 /** 40192 * WordPress dependencies 40193 */ 40194 40195 40196 40197 40198 /** 40199 * Internal dependencies 40200 */ 40201 40202 40203 function BlockHTML({ 40204 clientId 40205 }) { 40206 const [html, setHtml] = (0,external_wp_element_namespaceObject.useState)(''); 40207 const block = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlock(clientId), [clientId]); 40208 const { 40209 updateBlock 40210 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 40211 const onChange = () => { 40212 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(block.name); 40213 if (!blockType) { 40214 return; 40215 } 40216 const attributes = (0,external_wp_blocks_namespaceObject.getBlockAttributes)(blockType, html, block.attributes); 40217 40218 // If html is empty we reset the block to the default HTML and mark it as valid to avoid triggering an error 40219 const content = html ? html : (0,external_wp_blocks_namespaceObject.getSaveContent)(blockType, attributes); 40220 const [isValid] = html ? (0,external_wp_blocks_namespaceObject.validateBlock)({ 40221 ...block, 40222 attributes, 40223 originalContent: content 40224 }) : [true]; 40225 updateBlock(clientId, { 40226 attributes, 40227 originalContent: content, 40228 isValid 40229 }); 40230 40231 // Ensure the state is updated if we reset so it displays the default content. 40232 if (!html) { 40233 setHtml(content); 40234 } 40235 }; 40236 (0,external_wp_element_namespaceObject.useEffect)(() => { 40237 setHtml((0,external_wp_blocks_namespaceObject.getBlockContent)(block)); 40238 }, [block]); 40239 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(lib/* default */.A, { 40240 className: "block-editor-block-list__block-html-textarea", 40241 value: html, 40242 onBlur: onChange, 40243 onChange: event => setHtml(event.target.value) 40244 }); 40245 } 40246 /* harmony default export */ const block_html = (BlockHTML); 40247 40248 ;// ./node_modules/@react-spring/rafz/dist/esm/index.js 40249 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}}; 40250 40251 ;// ./node_modules/@react-spring/shared/dist/esm/index.js 40252 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}; 40253 40254 ;// ./node_modules/@react-spring/animated/dist/esm/index.js 40255 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; 40256 40257 ;// ./node_modules/@react-spring/core/dist/esm/index.js 40258 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; 40259 40260 ;// external "ReactDOM" 40261 const external_ReactDOM_namespaceObject = window["ReactDOM"]; 40262 ;// ./node_modules/@react-spring/web/dist/esm/index.js 40263 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; 40264 40265 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-moving-animation/index.js 40266 /** 40267 * External dependencies 40268 */ 40269 40270 40271 /** 40272 * WordPress dependencies 40273 */ 40274 40275 40276 40277 40278 /** 40279 * Internal dependencies 40280 */ 40281 40282 40283 /** 40284 * If the block count exceeds the threshold, we disable the reordering animation 40285 * to avoid laginess. 40286 */ 40287 const BLOCK_ANIMATION_THRESHOLD = 200; 40288 function getAbsolutePosition(element) { 40289 return { 40290 top: element.offsetTop, 40291 left: element.offsetLeft 40292 }; 40293 } 40294 40295 /** 40296 * Hook used to compute the styles required to move a div into a new position. 40297 * 40298 * The way this animation works is the following: 40299 * - It first renders the element as if there was no animation. 40300 * - It takes a snapshot of the position of the block to use it 40301 * as a destination point for the animation. 40302 * - It restores the element to the previous position using a CSS transform 40303 * - It uses the "resetAnimation" flag to reset the animation 40304 * from the beginning in order to animate to the new destination point. 40305 * 40306 * @param {Object} $1 Options 40307 * @param {*} $1.triggerAnimationOnChange Variable used to trigger the animation if it changes. 40308 * @param {string} $1.clientId 40309 */ 40310 function useMovingAnimation({ 40311 triggerAnimationOnChange, 40312 clientId 40313 }) { 40314 const ref = (0,external_wp_element_namespaceObject.useRef)(); 40315 const { 40316 isTyping, 40317 getGlobalBlockCount, 40318 isBlockSelected, 40319 isFirstMultiSelectedBlock, 40320 isBlockMultiSelected, 40321 isAncestorMultiSelected, 40322 isDraggingBlocks 40323 } = (0,external_wp_data_namespaceObject.useSelect)(store); 40324 40325 // Whenever the trigger changes, we need to take a snapshot of the current 40326 // position of the block to use it as a destination point for the animation. 40327 const { 40328 previous, 40329 prevRect 40330 } = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 40331 previous: ref.current && getAbsolutePosition(ref.current), 40332 prevRect: ref.current && ref.current.getBoundingClientRect() 40333 }), [triggerAnimationOnChange]); 40334 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 40335 if (!previous || !ref.current) { 40336 return; 40337 } 40338 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(ref.current); 40339 const isSelected = isBlockSelected(clientId); 40340 const adjustScrolling = isSelected || isFirstMultiSelectedBlock(clientId); 40341 const isDragging = isDraggingBlocks(); 40342 function preserveScrollPosition() { 40343 // The user already scrolled when dragging blocks. 40344 if (isDragging) { 40345 return; 40346 } 40347 if (adjustScrolling && prevRect) { 40348 const blockRect = ref.current.getBoundingClientRect(); 40349 const diff = blockRect.top - prevRect.top; 40350 if (diff) { 40351 scrollContainer.scrollTop += diff; 40352 } 40353 } 40354 } 40355 40356 // We disable the animation if the user has a preference for reduced 40357 // motion, if the user is typing (insertion by Enter), or if the block 40358 // count exceeds the threshold (insertion caused all the blocks that 40359 // follow to animate). 40360 // To do: consider enabling the _moving_ animation even for large 40361 // posts, while only disabling the _insertion_ animation? 40362 const disableAnimation = window.matchMedia('(prefers-reduced-motion: reduce)').matches || isTyping() || getGlobalBlockCount() > BLOCK_ANIMATION_THRESHOLD; 40363 if (disableAnimation) { 40364 // If the animation is disabled and the scroll needs to be adjusted, 40365 // just move directly to the final scroll position. 40366 preserveScrollPosition(); 40367 return; 40368 } 40369 const isPartOfSelection = isSelected || isBlockMultiSelected(clientId) || isAncestorMultiSelected(clientId); 40370 40371 // The user already dragged the blocks to the new position, so don't 40372 // animate the dragged blocks. 40373 if (isPartOfSelection && isDragging) { 40374 return; 40375 } 40376 40377 // Make sure the other blocks move under the selected block(s). 40378 const zIndex = isPartOfSelection ? '1' : ''; 40379 const controller = new esm_le({ 40380 x: 0, 40381 y: 0, 40382 config: { 40383 mass: 5, 40384 tension: 2000, 40385 friction: 200 40386 }, 40387 onChange({ 40388 value 40389 }) { 40390 if (!ref.current) { 40391 return; 40392 } 40393 let { 40394 x, 40395 y 40396 } = value; 40397 x = Math.round(x); 40398 y = Math.round(y); 40399 const finishedMoving = x === 0 && y === 0; 40400 ref.current.style.transformOrigin = 'center center'; 40401 ref.current.style.transform = finishedMoving ? null // Set to `null` to explicitly remove the transform. 40402 : `translate3d($x}px,$y}px,0)`; 40403 ref.current.style.zIndex = zIndex; 40404 preserveScrollPosition(); 40405 } 40406 }); 40407 ref.current.style.transform = undefined; 40408 const destination = getAbsolutePosition(ref.current); 40409 const x = Math.round(previous.left - destination.left); 40410 const y = Math.round(previous.top - destination.top); 40411 controller.start({ 40412 x: 0, 40413 y: 0, 40414 from: { 40415 x, 40416 y 40417 } 40418 }); 40419 return () => { 40420 controller.stop(); 40421 controller.set({ 40422 x: 0, 40423 y: 0 40424 }); 40425 }; 40426 }, [previous, prevRect, clientId, isTyping, getGlobalBlockCount, isBlockSelected, isFirstMultiSelectedBlock, isBlockMultiSelected, isAncestorMultiSelected, isDraggingBlocks]); 40427 return ref; 40428 } 40429 /* harmony default export */ const use_moving_animation = (useMovingAnimation); 40430 40431 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-focus-first-element.js 40432 /** 40433 * WordPress dependencies 40434 */ 40435 40436 40437 40438 40439 /** 40440 * Internal dependencies 40441 */ 40442 40443 40444 40445 40446 /** @typedef {import('@wordpress/element').RefObject} RefObject */ 40447 40448 /** 40449 * Transitions focus to the block or inner tabbable when the block becomes 40450 * selected and an initial position is set. 40451 * 40452 * @param {string} clientId Block client ID. 40453 * 40454 * @return {RefObject} React ref with the block element. 40455 */ 40456 function useFocusFirstElement({ 40457 clientId, 40458 initialPosition 40459 }) { 40460 const ref = (0,external_wp_element_namespaceObject.useRef)(); 40461 const { 40462 isBlockSelected, 40463 isMultiSelecting, 40464 isZoomOut 40465 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 40466 (0,external_wp_element_namespaceObject.useEffect)(() => { 40467 // Check if the block is still selected at the time this effect runs. 40468 if (!isBlockSelected(clientId) || isMultiSelecting() || isZoomOut()) { 40469 return; 40470 } 40471 if (initialPosition === undefined || initialPosition === null) { 40472 return; 40473 } 40474 if (!ref.current) { 40475 return; 40476 } 40477 const { 40478 ownerDocument 40479 } = ref.current; 40480 40481 // Do not focus the block if it already contains the active element. 40482 if (isInsideRootBlock(ref.current, ownerDocument.activeElement)) { 40483 return; 40484 } 40485 40486 // Find all tabbables within node. 40487 const textInputs = external_wp_dom_namespaceObject.focus.tabbable.find(ref.current).filter(node => (0,external_wp_dom_namespaceObject.isTextField)(node)); 40488 40489 // If reversed (e.g. merge via backspace), use the last in the set of 40490 // tabbables. 40491 const isReverse = -1 === initialPosition; 40492 const target = textInputs[isReverse ? textInputs.length - 1 : 0] || ref.current; 40493 if (!isInsideRootBlock(ref.current, target)) { 40494 ref.current.focus(); 40495 return; 40496 } 40497 40498 // Check to see if element is focussable before a generic caret insert. 40499 if (!ref.current.getAttribute('contenteditable')) { 40500 const focusElement = external_wp_dom_namespaceObject.focus.tabbable.findNext(ref.current); 40501 // Make sure focusElement is valid, contained in the same block, and a form field. 40502 if (focusElement && isInsideRootBlock(ref.current, focusElement) && (0,external_wp_dom_namespaceObject.isFormElement)(focusElement)) { 40503 focusElement.focus(); 40504 return; 40505 } 40506 } 40507 (0,external_wp_dom_namespaceObject.placeCaretAtHorizontalEdge)(target, isReverse); 40508 }, [initialPosition, clientId]); 40509 return ref; 40510 } 40511 40512 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-is-hovered.js 40513 /** 40514 * WordPress dependencies 40515 */ 40516 40517 40518 40519 /** 40520 * Internal dependencies 40521 */ 40522 40523 40524 /* 40525 * Adds `is-hovered` class when the block is hovered and in navigation or 40526 * outline mode. 40527 */ 40528 function useIsHovered({ 40529 clientId 40530 }) { 40531 const { 40532 hoverBlock 40533 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 40534 function listener(event) { 40535 if (event.defaultPrevented) { 40536 return; 40537 } 40538 const action = event.type === 'mouseover' ? 'add' : 'remove'; 40539 event.preventDefault(); 40540 event.currentTarget.classList[action]('is-hovered'); 40541 if (action === 'add') { 40542 hoverBlock(clientId); 40543 } else { 40544 hoverBlock(null); 40545 } 40546 } 40547 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40548 node.addEventListener('mouseout', listener); 40549 node.addEventListener('mouseover', listener); 40550 return () => { 40551 node.removeEventListener('mouseout', listener); 40552 node.removeEventListener('mouseover', listener); 40553 40554 // Remove class in case it lingers. 40555 node.classList.remove('is-hovered'); 40556 hoverBlock(null); 40557 }; 40558 }, []); 40559 } 40560 40561 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-focus-handler.js 40562 /** 40563 * WordPress dependencies 40564 */ 40565 40566 40567 40568 /** 40569 * Internal dependencies 40570 */ 40571 40572 40573 40574 /** 40575 * Selects the block if it receives focus. 40576 * 40577 * @param {string} clientId Block client ID. 40578 */ 40579 function useFocusHandler(clientId) { 40580 const { 40581 isBlockSelected 40582 } = (0,external_wp_data_namespaceObject.useSelect)(store); 40583 const { 40584 selectBlock, 40585 selectionChange 40586 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 40587 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40588 /** 40589 * Marks the block as selected when focused and not already 40590 * selected. This specifically handles the case where block does not 40591 * set focus on its own (via `setFocus`), typically if there is no 40592 * focusable input in the block. 40593 * 40594 * @param {FocusEvent} event Focus event. 40595 */ 40596 function onFocus(event) { 40597 // When the whole editor is editable, let writing flow handle 40598 // selection. 40599 if (node.parentElement.closest('[contenteditable="true"]')) { 40600 return; 40601 } 40602 40603 // Check synchronously because a non-selected block might be 40604 // getting data through `useSelect` asynchronously. 40605 if (isBlockSelected(clientId)) { 40606 // Potentially change selection away from rich text. 40607 if (!event.target.isContentEditable) { 40608 selectionChange(clientId); 40609 } 40610 return; 40611 } 40612 40613 // If an inner block is focussed, that block is responsible for 40614 // setting the selected block. 40615 if (!isInsideRootBlock(node, event.target)) { 40616 return; 40617 } 40618 selectBlock(clientId); 40619 } 40620 node.addEventListener('focusin', onFocus); 40621 return () => { 40622 node.removeEventListener('focusin', onFocus); 40623 }; 40624 }, [isBlockSelected, selectBlock]); 40625 } 40626 40627 ;// ./node_modules/@wordpress/icons/build-module/library/drag-handle.js 40628 /** 40629 * WordPress dependencies 40630 */ 40631 40632 40633 const dragHandle = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 40634 width: "24", 40635 height: "24", 40636 xmlns: "http://www.w3.org/2000/svg", 40637 viewBox: "0 0 24 24", 40638 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 40639 d: "M8 7h2V5H8v2zm0 6h2v-2H8v2zm0 6h2v-2H8v2zm6-14v2h2V5h-2zm0 8h2v-2h-2v2zm0 6h2v-2h-2v2z" 40640 }) 40641 }); 40642 /* harmony default export */ const drag_handle = (dragHandle); 40643 40644 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/draggable-chip.js 40645 /** 40646 * WordPress dependencies 40647 */ 40648 40649 40650 40651 40652 /** 40653 * Internal dependencies 40654 */ 40655 40656 40657 function BlockDraggableChip({ 40658 count, 40659 icon, 40660 isPattern, 40661 fadeWhenDisabled 40662 }) { 40663 const patternLabel = isPattern && (0,external_wp_i18n_namespaceObject.__)('Pattern'); 40664 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 40665 className: "block-editor-block-draggable-chip-wrapper", 40666 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 40667 className: "block-editor-block-draggable-chip", 40668 "data-testid": "block-draggable-chip", 40669 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 40670 justify: "center", 40671 className: "block-editor-block-draggable-chip__content", 40672 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 40673 children: icon ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 40674 icon: icon 40675 }) : patternLabel || (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: Number of blocks. */ 40676 (0,external_wp_i18n_namespaceObject._n)('%d block', '%d blocks', count), count) 40677 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 40678 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 40679 icon: drag_handle 40680 }) 40681 }), fadeWhenDisabled && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 40682 className: "block-editor-block-draggable-chip__disabled", 40683 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 40684 className: "block-editor-block-draggable-chip__disabled-icon" 40685 }) 40686 })] 40687 }) 40688 }) 40689 }); 40690 } 40691 40692 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js 40693 /** 40694 * WordPress dependencies 40695 */ 40696 40697 40698 40699 40700 40701 40702 40703 /** 40704 * Internal dependencies 40705 */ 40706 40707 40708 40709 40710 /** 40711 * Adds block behaviour: 40712 * - Removes the block on BACKSPACE. 40713 * - Inserts a default block on ENTER. 40714 * - Disables dragging of block contents. 40715 * 40716 * @param {string} clientId Block client ID. 40717 */ 40718 40719 function useEventHandlers({ 40720 clientId, 40721 isSelected 40722 }) { 40723 const { 40724 getBlockType 40725 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 40726 const { 40727 getBlockRootClientId, 40728 isZoomOut, 40729 hasMultiSelection, 40730 getBlockName 40731 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 40732 const { 40733 insertAfterBlock, 40734 removeBlock, 40735 resetZoomLevel, 40736 startDraggingBlocks, 40737 stopDraggingBlocks 40738 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 40739 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40740 if (!isSelected) { 40741 return; 40742 } 40743 40744 /** 40745 * Interprets keydown event intent to remove or insert after block if 40746 * key event occurs on wrapper node. This can occur when the block has 40747 * no text fields of its own, particularly after initial insertion, to 40748 * allow for easy deletion and continuous writing flow to add additional 40749 * content. 40750 * 40751 * @param {KeyboardEvent} event Keydown event. 40752 */ 40753 function onKeyDown(event) { 40754 const { 40755 keyCode, 40756 target 40757 } = event; 40758 if (keyCode !== external_wp_keycodes_namespaceObject.ENTER && keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE && keyCode !== external_wp_keycodes_namespaceObject.DELETE) { 40759 return; 40760 } 40761 if (target !== node || (0,external_wp_dom_namespaceObject.isTextField)(target)) { 40762 return; 40763 } 40764 event.preventDefault(); 40765 if (keyCode === external_wp_keycodes_namespaceObject.ENTER && isZoomOut()) { 40766 resetZoomLevel(); 40767 } else if (keyCode === external_wp_keycodes_namespaceObject.ENTER) { 40768 insertAfterBlock(clientId); 40769 } else { 40770 removeBlock(clientId); 40771 } 40772 } 40773 40774 /** 40775 * Prevents default dragging behavior within a block. To do: we must 40776 * handle this in the future and clean up the drag target. 40777 * 40778 * @param {DragEvent} event Drag event. 40779 */ 40780 function onDragStart(event) { 40781 if (node !== event.target || node.isContentEditable || node.ownerDocument.activeElement !== node || hasMultiSelection()) { 40782 event.preventDefault(); 40783 return; 40784 } 40785 const data = JSON.stringify({ 40786 type: 'block', 40787 srcClientIds: [clientId], 40788 srcRootClientId: getBlockRootClientId(clientId) 40789 }); 40790 event.dataTransfer.effectAllowed = 'move'; // remove "+" cursor 40791 event.dataTransfer.clearData(); 40792 event.dataTransfer.setData('wp-blocks', data); 40793 const { 40794 ownerDocument 40795 } = node; 40796 const { 40797 defaultView 40798 } = ownerDocument; 40799 const selection = defaultView.getSelection(); 40800 selection.removeAllRanges(); 40801 const domNode = document.createElement('div'); 40802 const root = (0,external_wp_element_namespaceObject.createRoot)(domNode); 40803 root.render(/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockDraggableChip, { 40804 icon: getBlockType(getBlockName(clientId)).icon 40805 })); 40806 document.body.appendChild(domNode); 40807 domNode.style.position = 'absolute'; 40808 domNode.style.top = '0'; 40809 domNode.style.left = '0'; 40810 domNode.style.zIndex = '1000'; 40811 domNode.style.pointerEvents = 'none'; 40812 40813 // Setting the drag chip as the drag image actually works, but 40814 // the behaviour is slightly different in every browser. In 40815 // Safari, it animates, in Firefox it's slightly transparent... 40816 // So we set a fake drag image and have to reposition it 40817 // ourselves. 40818 const dragElement = ownerDocument.createElement('div'); 40819 // Chrome will show a globe icon if the drag element does not 40820 // have dimensions. 40821 dragElement.style.width = '1px'; 40822 dragElement.style.height = '1px'; 40823 dragElement.style.position = 'fixed'; 40824 dragElement.style.visibility = 'hidden'; 40825 ownerDocument.body.appendChild(dragElement); 40826 event.dataTransfer.setDragImage(dragElement, 0, 0); 40827 let offset = { 40828 x: 0, 40829 y: 0 40830 }; 40831 if (document !== ownerDocument) { 40832 const frame = defaultView.frameElement; 40833 if (frame) { 40834 const rect = frame.getBoundingClientRect(); 40835 offset = { 40836 x: rect.left, 40837 y: rect.top 40838 }; 40839 } 40840 } 40841 40842 // chip handle offset 40843 offset.x -= 58; 40844 function over(e) { 40845 domNode.style.transform = `translate( $e.clientX + offset.x}px, $e.clientY + offset.y}px )`; 40846 } 40847 over(event); 40848 function end() { 40849 ownerDocument.removeEventListener('dragover', over); 40850 ownerDocument.removeEventListener('dragend', end); 40851 domNode.remove(); 40852 dragElement.remove(); 40853 stopDraggingBlocks(); 40854 document.body.classList.remove('is-dragging-components-draggable'); 40855 ownerDocument.documentElement.classList.remove('is-dragging'); 40856 } 40857 ownerDocument.addEventListener('dragover', over); 40858 ownerDocument.addEventListener('dragend', end); 40859 ownerDocument.addEventListener('drop', end); 40860 startDraggingBlocks([clientId]); 40861 // Important because it hides the block toolbar. 40862 document.body.classList.add('is-dragging-components-draggable'); 40863 ownerDocument.documentElement.classList.add('is-dragging'); 40864 } 40865 node.addEventListener('keydown', onKeyDown); 40866 node.addEventListener('dragstart', onDragStart); 40867 return () => { 40868 node.removeEventListener('keydown', onKeyDown); 40869 node.removeEventListener('dragstart', onDragStart); 40870 }; 40871 }, [clientId, isSelected, getBlockRootClientId, insertAfterBlock, removeBlock, isZoomOut, resetZoomLevel, hasMultiSelection, startDraggingBlocks, stopDraggingBlocks]); 40872 } 40873 40874 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-intersection-observer.js 40875 /** 40876 * WordPress dependencies 40877 */ 40878 40879 40880 40881 /** 40882 * Internal dependencies 40883 */ 40884 40885 function useIntersectionObserver() { 40886 const observer = (0,external_wp_element_namespaceObject.useContext)(block_list_IntersectionObserver); 40887 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40888 if (observer) { 40889 observer.observe(node); 40890 return () => { 40891 observer.unobserve(node); 40892 }; 40893 } 40894 }, [observer]); 40895 } 40896 40897 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-scroll-into-view.js 40898 /** 40899 * WordPress dependencies 40900 */ 40901 40902 function useScrollIntoView({ 40903 isSelected 40904 }) { 40905 const prefersReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 40906 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 40907 if (isSelected) { 40908 const { 40909 ownerDocument 40910 } = node; 40911 const { 40912 defaultView 40913 } = ownerDocument; 40914 if (!defaultView.IntersectionObserver) { 40915 return; 40916 } 40917 const observer = new defaultView.IntersectionObserver(entries => { 40918 // Once observing starts, we always get an initial 40919 // entry with the intersecting state. 40920 if (!entries[0].isIntersecting) { 40921 node.scrollIntoView({ 40922 behavior: prefersReducedMotion ? 'instant' : 'smooth' 40923 }); 40924 } 40925 observer.disconnect(); 40926 }); 40927 observer.observe(node); 40928 return () => { 40929 observer.disconnect(); 40930 }; 40931 } 40932 }, [isSelected]); 40933 } 40934 40935 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-flash-editable-blocks/index.js 40936 /** 40937 * WordPress dependencies 40938 */ 40939 40940 40941 40942 /** 40943 * Internal dependencies 40944 */ 40945 40946 40947 function useFlashEditableBlocks({ 40948 clientId = '', 40949 isEnabled = true 40950 } = {}) { 40951 const { 40952 getEnabledClientIdsTree 40953 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 40954 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 40955 if (!isEnabled) { 40956 return; 40957 } 40958 const flashEditableBlocks = () => { 40959 getEnabledClientIdsTree(clientId).forEach(({ 40960 clientId: id 40961 }) => { 40962 const block = element.querySelector(`[data-block="$id}"]`); 40963 if (!block) { 40964 return; 40965 } 40966 block.classList.remove('has-editable-outline'); 40967 // Force reflow to trigger the animation. 40968 // eslint-disable-next-line no-unused-expressions 40969 block.offsetWidth; 40970 block.classList.add('has-editable-outline'); 40971 }); 40972 }; 40973 const handleClick = event => { 40974 const shouldFlash = event.target === element || event.target.classList.contains('is-root-container'); 40975 if (!shouldFlash) { 40976 return; 40977 } 40978 if (event.defaultPrevented) { 40979 return; 40980 } 40981 event.preventDefault(); 40982 flashEditableBlocks(); 40983 }; 40984 element.addEventListener('click', handleClick); 40985 return () => element.removeEventListener('click', handleClick); 40986 }, [isEnabled]); 40987 } 40988 40989 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-firefox-draggable-compatibility.js 40990 /** 40991 * WordPress dependencies 40992 */ 40993 40994 const nodesByDocument = new Map(); 40995 function add(doc, node) { 40996 let set = nodesByDocument.get(doc); 40997 if (!set) { 40998 set = new Set(); 40999 nodesByDocument.set(doc, set); 41000 doc.addEventListener('pointerdown', down); 41001 } 41002 set.add(node); 41003 } 41004 function remove(doc, node) { 41005 const set = nodesByDocument.get(doc); 41006 if (set) { 41007 set.delete(node); 41008 restore(node); 41009 if (set.size === 0) { 41010 nodesByDocument.delete(doc); 41011 doc.removeEventListener('pointerdown', down); 41012 } 41013 } 41014 } 41015 function restore(node) { 41016 const prevDraggable = node.getAttribute('data-draggable'); 41017 if (prevDraggable) { 41018 node.removeAttribute('data-draggable'); 41019 // Only restore if `draggable` is still removed. It could have been 41020 // changed by React in the meantime. 41021 if (prevDraggable === 'true' && !node.getAttribute('draggable')) { 41022 node.setAttribute('draggable', 'true'); 41023 } 41024 } 41025 } 41026 function down(event) { 41027 const { 41028 target 41029 } = event; 41030 const { 41031 ownerDocument, 41032 isContentEditable, 41033 tagName 41034 } = target; 41035 const isInputOrTextArea = ['INPUT', 'TEXTAREA'].includes(tagName); 41036 const nodes = nodesByDocument.get(ownerDocument); 41037 if (isContentEditable || isInputOrTextArea) { 41038 // Whenever an editable element or an input or textarea is clicked, 41039 // check which draggable blocks contain this element, and temporarily 41040 // disable draggability. 41041 for (const node of nodes) { 41042 if (node.getAttribute('draggable') === 'true' && node.contains(target)) { 41043 node.removeAttribute('draggable'); 41044 node.setAttribute('data-draggable', 'true'); 41045 } 41046 } 41047 } else { 41048 // Whenever a non-editable element or an input or textarea is clicked, 41049 // re-enable draggability for any blocks that were previously disabled. 41050 for (const node of nodes) { 41051 restore(node); 41052 } 41053 } 41054 } 41055 41056 /** 41057 * In Firefox, the `draggable` and `contenteditable` or `input` or `textarea` 41058 * elements don't play well together. When these elements are within a 41059 * `draggable` element, selection doesn't get set in the right place. The only 41060 * solution is to temporarily remove the `draggable` attribute clicking inside 41061 * these elements. 41062 * @return {Function} Cleanup function. 41063 */ 41064 function useFirefoxDraggableCompatibility() { 41065 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 41066 add(node.ownerDocument, node); 41067 return () => { 41068 remove(node.ownerDocument, node); 41069 }; 41070 }, []); 41071 } 41072 41073 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/index.js 41074 /** 41075 * External dependencies 41076 */ 41077 41078 41079 /** 41080 * WordPress dependencies 41081 */ 41082 41083 41084 41085 41086 41087 41088 /** 41089 * Internal dependencies 41090 */ 41091 41092 41093 41094 41095 41096 41097 41098 41099 41100 41101 41102 41103 41104 41105 /** 41106 * This hook is used to lightly mark an element as a block element. The element 41107 * should be the outermost element of a block. Call this hook and pass the 41108 * returned props to the element to mark as a block. If you define a ref for the 41109 * element, it is important to pass the ref to this hook, which the hook in turn 41110 * will pass to the component through the props it returns. Optionally, you can 41111 * also pass any other props through this hook, and they will be merged and 41112 * returned. 41113 * 41114 * Use of this hook on the outermost element of a block is required if using API >= v2. 41115 * 41116 * @example 41117 * ```js 41118 * import { useBlockProps } from '@wordpress/block-editor'; 41119 * 41120 * export default function Edit() { 41121 * 41122 * const blockProps = useBlockProps( { 41123 * className: 'my-custom-class', 41124 * style: { 41125 * color: '#222222', 41126 * backgroundColor: '#eeeeee' 41127 * } 41128 * } ) 41129 * 41130 * return ( 41131 * <div { ...blockProps }> 41132 * 41133 * </div> 41134 * ) 41135 * } 41136 * 41137 * ``` 41138 * 41139 * 41140 * @param {Object} props Optional. Props to pass to the element. Must contain 41141 * the ref if one is defined. 41142 * @param {Object} options Options for internal use only. 41143 * @param {boolean} options.__unstableIsHtml 41144 * 41145 * @return {Object} Props to pass to the element to mark as a block. 41146 */ 41147 function use_block_props_useBlockProps(props = {}, { 41148 __unstableIsHtml 41149 } = {}) { 41150 const { 41151 clientId, 41152 className, 41153 wrapperProps = {}, 41154 isAligned, 41155 index, 41156 mode, 41157 name, 41158 blockApiVersion, 41159 blockTitle, 41160 isSelected, 41161 isSubtreeDisabled, 41162 hasOverlay, 41163 initialPosition, 41164 blockEditingMode, 41165 isHighlighted, 41166 isMultiSelected, 41167 isPartiallySelected, 41168 isReusable, 41169 isDragging, 41170 hasChildSelected, 41171 isEditingDisabled, 41172 hasEditableOutline, 41173 isTemporarilyEditingAsBlocks, 41174 defaultClassName, 41175 isSectionBlock, 41176 canMove 41177 } = (0,external_wp_element_namespaceObject.useContext)(PrivateBlockContext); 41178 41179 // translators: %s: Type of block (i.e. Text, Image etc) 41180 const blockLabel = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Block: %s'), blockTitle); 41181 const htmlSuffix = mode === 'html' && !__unstableIsHtml ? '-visual' : ''; 41182 const ffDragRef = useFirefoxDraggableCompatibility(); 41183 const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, useFocusFirstElement({ 41184 clientId, 41185 initialPosition 41186 }), useBlockRefProvider(clientId), useFocusHandler(clientId), useEventHandlers({ 41187 clientId, 41188 isSelected 41189 }), useIsHovered({ 41190 clientId 41191 }), useIntersectionObserver(), use_moving_animation({ 41192 triggerAnimationOnChange: index, 41193 clientId 41194 }), (0,external_wp_compose_namespaceObject.useDisabled)({ 41195 isDisabled: !hasOverlay 41196 }), useFlashEditableBlocks({ 41197 clientId, 41198 isEnabled: isSectionBlock 41199 }), useScrollIntoView({ 41200 isSelected 41201 }), canMove ? ffDragRef : undefined]); 41202 const blockEditContext = useBlockEditContext(); 41203 const hasBlockBindings = !!blockEditContext[blockBindingsKey]; 41204 const bindingsStyle = hasBlockBindings && canBindBlock(name) ? { 41205 '--wp-admin-theme-color': 'var(--wp-block-synced-color)', 41206 '--wp-admin-theme-color--rgb': 'var(--wp-block-synced-color--rgb)' 41207 } : {}; 41208 41209 // Ensures it warns only inside the `edit` implementation for the block. 41210 if (blockApiVersion < 2 && clientId === blockEditContext.clientId) { 41211 true ? external_wp_warning_default()(`Block type "$name}" must support API version 2 or higher to work correctly with "useBlockProps" method.`) : 0; 41212 } 41213 let hasNegativeMargin = false; 41214 if (wrapperProps?.style?.marginTop?.charAt(0) === '-' || wrapperProps?.style?.marginBottom?.charAt(0) === '-' || wrapperProps?.style?.marginLeft?.charAt(0) === '-' || wrapperProps?.style?.marginRight?.charAt(0) === '-') { 41215 hasNegativeMargin = true; 41216 } 41217 return { 41218 tabIndex: blockEditingMode === 'disabled' ? -1 : 0, 41219 draggable: canMove && !hasChildSelected ? true : undefined, 41220 ...wrapperProps, 41221 ...props, 41222 ref: mergedRefs, 41223 id: `block-$clientId}$htmlSuffix}`, 41224 role: 'document', 41225 'aria-label': blockLabel, 41226 'data-block': clientId, 41227 'data-type': name, 41228 'data-title': blockTitle, 41229 inert: isSubtreeDisabled ? 'true' : undefined, 41230 className: dist_clsx('block-editor-block-list__block', { 41231 // The wp-block className is important for editor styles. 41232 'wp-block': !isAligned, 41233 'has-block-overlay': hasOverlay, 41234 'is-selected': isSelected, 41235 'is-highlighted': isHighlighted, 41236 'is-multi-selected': isMultiSelected, 41237 'is-partially-selected': isPartiallySelected, 41238 'is-reusable': isReusable, 41239 'is-dragging': isDragging, 41240 'has-child-selected': hasChildSelected, 41241 'is-editing-disabled': isEditingDisabled, 41242 'has-editable-outline': hasEditableOutline, 41243 'has-negative-margin': hasNegativeMargin, 41244 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks 41245 }, className, props.className, wrapperProps.className, defaultClassName), 41246 style: { 41247 ...wrapperProps.style, 41248 ...props.style, 41249 ...bindingsStyle 41250 } 41251 }; 41252 } 41253 41254 /** 41255 * Call within a save function to get the props for the block wrapper. 41256 * 41257 * @param {Object} props Optional. Props to pass to the element. 41258 */ 41259 use_block_props_useBlockProps.save = external_wp_blocks_namespaceObject.__unstableGetBlockProps; 41260 41261 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/block.js 41262 /** 41263 * External dependencies 41264 */ 41265 41266 41267 /** 41268 * WordPress dependencies 41269 */ 41270 41271 41272 41273 41274 41275 41276 41277 /** 41278 * Internal dependencies 41279 */ 41280 41281 41282 41283 41284 41285 41286 41287 41288 41289 41290 41291 /** 41292 * Merges wrapper props with special handling for classNames and styles. 41293 * 41294 * @param {Object} propsA 41295 * @param {Object} propsB 41296 * 41297 * @return {Object} Merged props. 41298 */ 41299 41300 function mergeWrapperProps(propsA, propsB) { 41301 const newProps = { 41302 ...propsA, 41303 ...propsB 41304 }; 41305 41306 // May be set to undefined, so check if the property is set! 41307 if (propsA?.hasOwnProperty('className') && propsB?.hasOwnProperty('className')) { 41308 newProps.className = dist_clsx(propsA.className, propsB.className); 41309 } 41310 if (propsA?.hasOwnProperty('style') && propsB?.hasOwnProperty('style')) { 41311 newProps.style = { 41312 ...propsA.style, 41313 ...propsB.style 41314 }; 41315 } 41316 return newProps; 41317 } 41318 function Block({ 41319 children, 41320 isHtml, 41321 ...props 41322 }) { 41323 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 41324 ...use_block_props_useBlockProps(props, { 41325 __unstableIsHtml: isHtml 41326 }), 41327 children: children 41328 }); 41329 } 41330 function BlockListBlock({ 41331 block: { 41332 __unstableBlockSource 41333 }, 41334 mode, 41335 isLocked, 41336 canRemove, 41337 clientId, 41338 isSelected, 41339 isSelectionEnabled, 41340 className, 41341 __unstableLayoutClassNames: layoutClassNames, 41342 name, 41343 isValid, 41344 attributes, 41345 wrapperProps, 41346 setAttributes, 41347 onReplace, 41348 onRemove, 41349 onInsertBlocksAfter, 41350 onMerge, 41351 toggleSelection 41352 }) { 41353 var _wrapperProps; 41354 const { 41355 mayDisplayControls, 41356 mayDisplayParentControls, 41357 themeSupportsLayout, 41358 ...context 41359 } = (0,external_wp_element_namespaceObject.useContext)(PrivateBlockContext); 41360 const parentLayout = useLayout() || {}; 41361 41362 // We wrap the BlockEdit component in a div that hides it when editing in 41363 // HTML mode. This allows us to render all of the ancillary pieces 41364 // (InspectorControls, etc.) which are inside `BlockEdit` but not 41365 // `BlockHTML`, even in HTML mode. 41366 let blockEdit = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockEdit, { 41367 name: name, 41368 isSelected: isSelected, 41369 attributes: attributes, 41370 setAttributes: setAttributes, 41371 insertBlocksAfter: isLocked ? undefined : onInsertBlocksAfter, 41372 onReplace: canRemove ? onReplace : undefined, 41373 onRemove: canRemove ? onRemove : undefined, 41374 mergeBlocks: canRemove ? onMerge : undefined, 41375 clientId: clientId, 41376 isSelectionEnabled: isSelectionEnabled, 41377 toggleSelection: toggleSelection, 41378 __unstableLayoutClassNames: layoutClassNames, 41379 __unstableParentLayout: Object.keys(parentLayout).length ? parentLayout : undefined, 41380 mayDisplayControls: mayDisplayControls, 41381 mayDisplayParentControls: mayDisplayParentControls, 41382 blockEditingMode: context.blockEditingMode, 41383 isPreviewMode: context.isPreviewMode 41384 }); 41385 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name); 41386 41387 // Determine whether the block has props to apply to the wrapper. 41388 if (blockType?.getEditWrapperProps) { 41389 wrapperProps = mergeWrapperProps(wrapperProps, blockType.getEditWrapperProps(attributes)); 41390 } 41391 const isAligned = wrapperProps && !!wrapperProps['data-align'] && !themeSupportsLayout; 41392 41393 // Support for sticky position in classic themes with alignment wrappers. 41394 41395 const isSticky = className?.includes('is-position-sticky'); 41396 41397 // For aligned blocks, provide a wrapper element so the block can be 41398 // positioned relative to the block column. 41399 // This is only kept for classic themes that don't support layout 41400 // Historically we used to rely on extra divs and data-align to 41401 // provide the alignments styles in the editor. 41402 // Due to the differences between frontend and backend, we migrated 41403 // to the layout feature, and we're now aligning the markup of frontend 41404 // and backend. 41405 if (isAligned) { 41406 blockEdit = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 41407 className: dist_clsx('wp-block', isSticky && className), 41408 "data-align": wrapperProps['data-align'], 41409 children: blockEdit 41410 }); 41411 } 41412 let block; 41413 if (!isValid) { 41414 const saveContent = __unstableBlockSource ? (0,external_wp_blocks_namespaceObject.serializeRawBlock)(__unstableBlockSource) : (0,external_wp_blocks_namespaceObject.getSaveContent)(blockType, attributes); 41415 block = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Block, { 41416 className: "has-warning", 41417 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockInvalidWarning, { 41418 clientId: clientId 41419 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.RawHTML, { 41420 children: (0,external_wp_dom_namespaceObject.safeHTML)(saveContent) 41421 })] 41422 }); 41423 } else if (mode === 'html') { 41424 // Render blockEdit so the inspector controls don't disappear. 41425 // See #8969. 41426 block = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 41427 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 41428 style: { 41429 display: 'none' 41430 }, 41431 children: blockEdit 41432 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Block, { 41433 isHtml: true, 41434 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_html, { 41435 clientId: clientId 41436 }) 41437 })] 41438 }); 41439 } else if (blockType?.apiVersion > 1) { 41440 block = blockEdit; 41441 } else { 41442 block = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Block, { 41443 children: blockEdit 41444 }); 41445 } 41446 const { 41447 'data-align': dataAlign, 41448 ...restWrapperProps 41449 } = (_wrapperProps = wrapperProps) !== null && _wrapperProps !== void 0 ? _wrapperProps : {}; 41450 const updatedWrapperProps = { 41451 ...restWrapperProps, 41452 className: dist_clsx(restWrapperProps.className, dataAlign && themeSupportsLayout && `align$dataAlign}`, !(dataAlign && isSticky) && className) 41453 }; 41454 41455 // We set a new context with the adjusted and filtered wrapperProps (through 41456 // `editor.BlockListBlock`), which the `BlockListBlockProvider` did not have 41457 // access to. 41458 // Note that the context value doesn't have to be memoized in this case 41459 // because when it changes, this component will be re-rendered anyway, and 41460 // none of the consumers (BlockListBlock and useBlockProps) are memoized or 41461 // "pure". This is different from the public BlockEditContext, where 41462 // consumers might be memoized or "pure". 41463 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockContext.Provider, { 41464 value: { 41465 wrapperProps: updatedWrapperProps, 41466 isAligned, 41467 ...context 41468 }, 41469 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_crash_boundary, { 41470 fallback: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Block, { 41471 className: "has-warning", 41472 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_crash_warning, {}) 41473 }), 41474 children: block 41475 }) 41476 }); 41477 } 41478 const applyWithDispatch = (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps, registry) => { 41479 const { 41480 updateBlockAttributes, 41481 insertBlocks, 41482 mergeBlocks, 41483 replaceBlocks, 41484 toggleSelection, 41485 __unstableMarkLastChangeAsPersistent, 41486 moveBlocksToPosition, 41487 removeBlock, 41488 selectBlock 41489 } = dispatch(store); 41490 41491 // Do not add new properties here, use `useDispatch` instead to avoid 41492 // leaking new props to the public API (editor.BlockListBlock filter). 41493 return { 41494 setAttributes(newAttributes) { 41495 const { 41496 getMultiSelectedBlockClientIds 41497 } = registry.select(store); 41498 const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(); 41499 const { 41500 clientId 41501 } = ownProps; 41502 const clientIds = multiSelectedBlockClientIds.length ? multiSelectedBlockClientIds : [clientId]; 41503 updateBlockAttributes(clientIds, newAttributes); 41504 }, 41505 onInsertBlocks(blocks, index) { 41506 const { 41507 rootClientId 41508 } = ownProps; 41509 insertBlocks(blocks, index, rootClientId); 41510 }, 41511 onInsertBlocksAfter(blocks) { 41512 const { 41513 clientId, 41514 rootClientId 41515 } = ownProps; 41516 const { 41517 getBlockIndex 41518 } = registry.select(store); 41519 const index = getBlockIndex(clientId); 41520 insertBlocks(blocks, index + 1, rootClientId); 41521 }, 41522 onMerge(forward) { 41523 const { 41524 clientId, 41525 rootClientId 41526 } = ownProps; 41527 const { 41528 getPreviousBlockClientId, 41529 getNextBlockClientId, 41530 getBlock, 41531 getBlockAttributes, 41532 getBlockName, 41533 getBlockOrder, 41534 getBlockIndex, 41535 getBlockRootClientId, 41536 canInsertBlockType 41537 } = registry.select(store); 41538 function switchToDefaultOrRemove() { 41539 const block = getBlock(clientId); 41540 const defaultBlockName = (0,external_wp_blocks_namespaceObject.getDefaultBlockName)(); 41541 const defaultBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(defaultBlockName); 41542 if (getBlockName(clientId) !== defaultBlockName) { 41543 const replacement = (0,external_wp_blocks_namespaceObject.switchToBlockType)(block, defaultBlockName); 41544 if (replacement && replacement.length) { 41545 replaceBlocks(clientId, replacement); 41546 } 41547 } else if ((0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(block)) { 41548 const nextBlockClientId = getNextBlockClientId(clientId); 41549 if (nextBlockClientId) { 41550 registry.batch(() => { 41551 removeBlock(clientId); 41552 selectBlock(nextBlockClientId); 41553 }); 41554 } 41555 } else if (defaultBlockType.merge) { 41556 const attributes = defaultBlockType.merge({}, block.attributes); 41557 replaceBlocks([clientId], [(0,external_wp_blocks_namespaceObject.createBlock)(defaultBlockName, attributes)]); 41558 } 41559 } 41560 41561 /** 41562 * Moves the block with clientId up one level. If the block type 41563 * cannot be inserted at the new location, it will be attempted to 41564 * convert to the default block type. 41565 * 41566 * @param {string} _clientId The block to move. 41567 * @param {boolean} changeSelection Whether to change the selection 41568 * to the moved block. 41569 */ 41570 function moveFirstItemUp(_clientId, changeSelection = true) { 41571 const wrapperBlockName = getBlockName(_clientId); 41572 const wrapperBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(wrapperBlockName); 41573 const isTextualWrapper = wrapperBlockType.category === 'text'; 41574 const targetRootClientId = getBlockRootClientId(_clientId); 41575 const blockOrder = getBlockOrder(_clientId); 41576 const [firstClientId] = blockOrder; 41577 if (blockOrder.length === 1 && (0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(getBlock(firstClientId))) { 41578 removeBlock(_clientId); 41579 } else if (isTextualWrapper) { 41580 registry.batch(() => { 41581 if (canInsertBlockType(getBlockName(firstClientId), targetRootClientId)) { 41582 moveBlocksToPosition([firstClientId], _clientId, targetRootClientId, getBlockIndex(_clientId)); 41583 } else { 41584 const replacement = (0,external_wp_blocks_namespaceObject.switchToBlockType)(getBlock(firstClientId), (0,external_wp_blocks_namespaceObject.getDefaultBlockName)()); 41585 if (replacement && replacement.length && replacement.every(block => canInsertBlockType(block.name, targetRootClientId))) { 41586 insertBlocks(replacement, getBlockIndex(_clientId), targetRootClientId, changeSelection); 41587 removeBlock(firstClientId, false); 41588 } else { 41589 switchToDefaultOrRemove(); 41590 } 41591 } 41592 if (!getBlockOrder(_clientId).length && (0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(getBlock(_clientId))) { 41593 removeBlock(_clientId, false); 41594 } 41595 }); 41596 } else { 41597 switchToDefaultOrRemove(); 41598 } 41599 } 41600 41601 // For `Delete` or forward merge, we should do the exact same thing 41602 // as `Backspace`, but from the other block. 41603 if (forward) { 41604 if (rootClientId) { 41605 const nextRootClientId = getNextBlockClientId(rootClientId); 41606 if (nextRootClientId) { 41607 // If there is a block that follows with the same parent 41608 // block name and the same attributes, merge the inner 41609 // blocks. 41610 if (getBlockName(rootClientId) === getBlockName(nextRootClientId)) { 41611 const rootAttributes = getBlockAttributes(rootClientId); 41612 const previousRootAttributes = getBlockAttributes(nextRootClientId); 41613 if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) { 41614 registry.batch(() => { 41615 moveBlocksToPosition(getBlockOrder(nextRootClientId), nextRootClientId, rootClientId); 41616 removeBlock(nextRootClientId, false); 41617 }); 41618 return; 41619 } 41620 } else { 41621 mergeBlocks(rootClientId, nextRootClientId); 41622 return; 41623 } 41624 } 41625 } 41626 const nextBlockClientId = getNextBlockClientId(clientId); 41627 if (!nextBlockClientId) { 41628 return; 41629 } 41630 if (getBlockOrder(nextBlockClientId).length) { 41631 moveFirstItemUp(nextBlockClientId, false); 41632 } else { 41633 mergeBlocks(clientId, nextBlockClientId); 41634 } 41635 } else { 41636 const previousBlockClientId = getPreviousBlockClientId(clientId); 41637 if (previousBlockClientId) { 41638 mergeBlocks(previousBlockClientId, clientId); 41639 } else if (rootClientId) { 41640 const previousRootClientId = getPreviousBlockClientId(rootClientId); 41641 41642 // If there is a preceding block with the same parent block 41643 // name and the same attributes, merge the inner blocks. 41644 if (previousRootClientId && getBlockName(rootClientId) === getBlockName(previousRootClientId)) { 41645 const rootAttributes = getBlockAttributes(rootClientId); 41646 const previousRootAttributes = getBlockAttributes(previousRootClientId); 41647 if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) { 41648 registry.batch(() => { 41649 moveBlocksToPosition(getBlockOrder(rootClientId), rootClientId, previousRootClientId); 41650 removeBlock(rootClientId, false); 41651 }); 41652 return; 41653 } 41654 } 41655 moveFirstItemUp(rootClientId); 41656 } else { 41657 switchToDefaultOrRemove(); 41658 } 41659 } 41660 }, 41661 onReplace(blocks, indexToSelect, initialPosition) { 41662 if (blocks.length && !(0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blocks[blocks.length - 1])) { 41663 __unstableMarkLastChangeAsPersistent(); 41664 } 41665 //Unsynced patterns are nested in an array so we need to flatten them. 41666 const replacementBlocks = blocks?.length === 1 && Array.isArray(blocks[0]) ? blocks[0] : blocks; 41667 replaceBlocks([ownProps.clientId], replacementBlocks, indexToSelect, initialPosition); 41668 }, 41669 onRemove() { 41670 removeBlock(ownProps.clientId); 41671 }, 41672 toggleSelection(selectionEnabled) { 41673 toggleSelection(selectionEnabled); 41674 } 41675 }; 41676 }); 41677 41678 // This component is used by the BlockListBlockProvider component below. It will 41679 // add the props necessary for the `editor.BlockListBlock` filters. 41680 BlockListBlock = (0,external_wp_compose_namespaceObject.compose)(applyWithDispatch, (0,external_wp_components_namespaceObject.withFilters)('editor.BlockListBlock'))(BlockListBlock); 41681 41682 // This component provides all the information we need through a single store 41683 // subscription (useSelect mapping). Only the necessary props are passed down 41684 // to the BlockListBlock component, which is a filtered component, so these 41685 // props are public API. To avoid adding to the public API, we use a private 41686 // context to pass the rest of the information to the filtered BlockListBlock 41687 // component, and useBlockProps. 41688 function BlockListBlockProvider(props) { 41689 const { 41690 clientId, 41691 rootClientId 41692 } = props; 41693 const selectedProps = (0,external_wp_data_namespaceObject.useSelect)(select => { 41694 const { 41695 isBlockSelected, 41696 getBlockMode, 41697 isSelectionEnabled, 41698 getTemplateLock, 41699 isSectionBlock: _isSectionBlock, 41700 getBlockWithoutAttributes, 41701 getBlockAttributes, 41702 canRemoveBlock, 41703 canMoveBlock, 41704 getSettings, 41705 getTemporarilyEditingAsBlocks, 41706 getBlockEditingMode, 41707 getBlockName, 41708 isFirstMultiSelectedBlock, 41709 getMultiSelectedBlockClientIds, 41710 hasSelectedInnerBlock, 41711 getBlocksByName, 41712 getBlockIndex, 41713 isBlockMultiSelected, 41714 isBlockSubtreeDisabled, 41715 isBlockHighlighted, 41716 __unstableIsFullySelected, 41717 __unstableSelectionHasUnmergeableBlock, 41718 isBlockBeingDragged, 41719 isDragging, 41720 __unstableHasActiveBlockOverlayActive, 41721 getSelectedBlocksInitialCaretPosition 41722 } = unlock(select(store)); 41723 const blockWithoutAttributes = getBlockWithoutAttributes(clientId); 41724 41725 // This is a temporary fix. 41726 // This function should never be called when a block is not 41727 // present in the state. It happens now because the order in 41728 // withSelect rendering is not correct. 41729 if (!blockWithoutAttributes) { 41730 return; 41731 } 41732 const { 41733 hasBlockSupport: _hasBlockSupport, 41734 getActiveBlockVariation 41735 } = select(external_wp_blocks_namespaceObject.store); 41736 const attributes = getBlockAttributes(clientId); 41737 const { 41738 name: blockName, 41739 isValid 41740 } = blockWithoutAttributes; 41741 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 41742 const { 41743 supportsLayout, 41744 isPreviewMode 41745 } = getSettings(); 41746 const hasLightBlockWrapper = blockType?.apiVersion > 1; 41747 const previewContext = { 41748 isPreviewMode, 41749 blockWithoutAttributes, 41750 name: blockName, 41751 attributes, 41752 isValid, 41753 themeSupportsLayout: supportsLayout, 41754 index: getBlockIndex(clientId), 41755 isReusable: (0,external_wp_blocks_namespaceObject.isReusableBlock)(blockType), 41756 className: hasLightBlockWrapper ? attributes.className : undefined, 41757 defaultClassName: hasLightBlockWrapper ? (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockName) : undefined, 41758 blockTitle: blockType?.title 41759 }; 41760 41761 // When in preview mode, we can avoid a lot of selection and 41762 // editing related selectors. 41763 if (isPreviewMode) { 41764 return previewContext; 41765 } 41766 const _isSelected = isBlockSelected(clientId); 41767 const canRemove = canRemoveBlock(clientId); 41768 const canMove = canMoveBlock(clientId); 41769 const match = getActiveBlockVariation(blockName, attributes); 41770 const isMultiSelected = isBlockMultiSelected(clientId); 41771 const checkDeep = true; 41772 const isAncestorOfSelectedBlock = hasSelectedInnerBlock(clientId, checkDeep); 41773 const blockEditingMode = getBlockEditingMode(clientId); 41774 const multiple = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'multiple', true); 41775 41776 // For block types with `multiple` support, there is no "original 41777 // block" to be found in the content, as the block itself is valid. 41778 const blocksWithSameName = multiple ? [] : getBlocksByName(blockName); 41779 const isInvalid = blocksWithSameName.length && blocksWithSameName[0] !== clientId; 41780 return { 41781 ...previewContext, 41782 mode: getBlockMode(clientId), 41783 isSelectionEnabled: isSelectionEnabled(), 41784 isLocked: !!getTemplateLock(rootClientId), 41785 isSectionBlock: _isSectionBlock(clientId), 41786 canRemove, 41787 canMove, 41788 isSelected: _isSelected, 41789 isTemporarilyEditingAsBlocks: getTemporarilyEditingAsBlocks() === clientId, 41790 blockEditingMode, 41791 mayDisplayControls: _isSelected || isFirstMultiSelectedBlock(clientId) && getMultiSelectedBlockClientIds().every(id => getBlockName(id) === blockName), 41792 mayDisplayParentControls: _hasBlockSupport(getBlockName(clientId), '__experimentalExposeControlsToChildren', false) && hasSelectedInnerBlock(clientId), 41793 blockApiVersion: blockType?.apiVersion || 1, 41794 blockTitle: match?.title || blockType?.title, 41795 isSubtreeDisabled: blockEditingMode === 'disabled' && isBlockSubtreeDisabled(clientId), 41796 hasOverlay: __unstableHasActiveBlockOverlayActive(clientId) && !isDragging(), 41797 initialPosition: _isSelected ? getSelectedBlocksInitialCaretPosition() : undefined, 41798 isHighlighted: isBlockHighlighted(clientId), 41799 isMultiSelected, 41800 isPartiallySelected: isMultiSelected && !__unstableIsFullySelected() && !__unstableSelectionHasUnmergeableBlock(), 41801 isDragging: isBlockBeingDragged(clientId), 41802 hasChildSelected: isAncestorOfSelectedBlock, 41803 isEditingDisabled: blockEditingMode === 'disabled', 41804 hasEditableOutline: blockEditingMode !== 'disabled' && getBlockEditingMode(rootClientId) === 'disabled', 41805 originalBlockClientId: isInvalid ? blocksWithSameName[0] : false 41806 }; 41807 }, [clientId, rootClientId]); 41808 const { 41809 isPreviewMode, 41810 // Fill values that end up as a public API and may not be defined in 41811 // preview mode. 41812 mode = 'visual', 41813 isSelectionEnabled = false, 41814 isLocked = false, 41815 canRemove = false, 41816 canMove = false, 41817 blockWithoutAttributes, 41818 name, 41819 attributes, 41820 isValid, 41821 isSelected = false, 41822 themeSupportsLayout, 41823 isTemporarilyEditingAsBlocks, 41824 blockEditingMode, 41825 mayDisplayControls, 41826 mayDisplayParentControls, 41827 index, 41828 blockApiVersion, 41829 blockTitle, 41830 isSubtreeDisabled, 41831 hasOverlay, 41832 initialPosition, 41833 isHighlighted, 41834 isMultiSelected, 41835 isPartiallySelected, 41836 isReusable, 41837 isDragging, 41838 hasChildSelected, 41839 isSectionBlock, 41840 isEditingDisabled, 41841 hasEditableOutline, 41842 className, 41843 defaultClassName, 41844 originalBlockClientId 41845 } = selectedProps; 41846 41847 // Users of the editor.BlockListBlock filter used to be able to 41848 // access the block prop. 41849 // Ideally these blocks would rely on the clientId prop only. 41850 // This is kept for backward compatibility reasons. 41851 const block = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 41852 ...blockWithoutAttributes, 41853 attributes 41854 }), [blockWithoutAttributes, attributes]); 41855 41856 // Block is sometimes not mounted at the right time, causing it be 41857 // undefined see issue for more info 41858 // https://github.com/WordPress/gutenberg/issues/17013 41859 if (!selectedProps) { 41860 return null; 41861 } 41862 const privateContext = { 41863 isPreviewMode, 41864 clientId, 41865 className, 41866 index, 41867 mode, 41868 name, 41869 blockApiVersion, 41870 blockTitle, 41871 isSelected, 41872 isSubtreeDisabled, 41873 hasOverlay, 41874 initialPosition, 41875 blockEditingMode, 41876 isHighlighted, 41877 isMultiSelected, 41878 isPartiallySelected, 41879 isReusable, 41880 isDragging, 41881 hasChildSelected, 41882 isSectionBlock, 41883 isEditingDisabled, 41884 hasEditableOutline, 41885 isTemporarilyEditingAsBlocks, 41886 defaultClassName, 41887 mayDisplayControls, 41888 mayDisplayParentControls, 41889 originalBlockClientId, 41890 themeSupportsLayout, 41891 canMove 41892 }; 41893 41894 // Here we separate between the props passed to BlockListBlock and any other 41895 // information we selected for internal use. BlockListBlock is a filtered 41896 // component and thus ALL the props are PUBLIC API. 41897 41898 // Note that the context value doesn't have to be memoized in this case 41899 // because when it changes, this component will be re-rendered anyway, and 41900 // none of the consumers (BlockListBlock and useBlockProps) are memoized or 41901 // "pure". This is different from the public BlockEditContext, where 41902 // consumers might be memoized or "pure". 41903 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockContext.Provider, { 41904 value: privateContext, 41905 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListBlock, { 41906 ...props, 41907 mode, 41908 isSelectionEnabled, 41909 isLocked, 41910 canRemove, 41911 canMove, 41912 // Users of the editor.BlockListBlock filter used to be able 41913 // to access the block prop. Ideally these blocks would rely 41914 // on the clientId prop only. This is kept for backward 41915 // compatibility reasons. 41916 block, 41917 name, 41918 attributes, 41919 isValid, 41920 isSelected 41921 }) 41922 }); 41923 } 41924 /* harmony default export */ const block = ((0,external_wp_element_namespaceObject.memo)(BlockListBlockProvider)); 41925 41926 ;// external ["wp","htmlEntities"] 41927 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 41928 ;// ./node_modules/@wordpress/block-editor/build-module/components/default-block-appender/index.js 41929 /** 41930 * External dependencies 41931 */ 41932 41933 41934 /** 41935 * WordPress dependencies 41936 */ 41937 41938 41939 41940 41941 41942 /** 41943 * Internal dependencies 41944 */ 41945 41946 41947 41948 /** 41949 * Zero width non-breaking space, used as padding for the paragraph when it is 41950 * empty. 41951 */ 41952 41953 const ZWNBSP = '\ufeff'; 41954 function DefaultBlockAppender({ 41955 rootClientId 41956 }) { 41957 const { 41958 showPrompt, 41959 isLocked, 41960 placeholder, 41961 isManualGrid 41962 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 41963 const { 41964 getBlockCount, 41965 getSettings, 41966 getTemplateLock, 41967 getBlockAttributes 41968 } = select(store); 41969 const isEmpty = !getBlockCount(rootClientId); 41970 const { 41971 bodyPlaceholder 41972 } = getSettings(); 41973 return { 41974 showPrompt: isEmpty, 41975 isLocked: !!getTemplateLock(rootClientId), 41976 placeholder: bodyPlaceholder, 41977 isManualGrid: getBlockAttributes(rootClientId)?.layout?.isManualPlacement 41978 }; 41979 }, [rootClientId]); 41980 const { 41981 insertDefaultBlock, 41982 startTyping 41983 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 41984 if (isLocked || isManualGrid) { 41985 return null; 41986 } 41987 const value = (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(placeholder) || (0,external_wp_i18n_namespaceObject.__)('Type / to choose a block'); 41988 const onAppend = () => { 41989 insertDefaultBlock(undefined, rootClientId); 41990 startTyping(); 41991 }; 41992 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 41993 "data-root-client-id": rootClientId || '', 41994 className: dist_clsx('block-editor-default-block-appender', { 41995 'has-visible-prompt': showPrompt 41996 }), 41997 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 41998 tabIndex: "0" 41999 // We want this element to be styled as a paragraph by themes. 42000 // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role 42001 , 42002 role: "button", 42003 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Add default block') 42004 // A wrapping container for this one already has the wp-block className. 42005 , 42006 className: "block-editor-default-block-appender__content", 42007 onKeyDown: event => { 42008 if (external_wp_keycodes_namespaceObject.ENTER === event.keyCode || external_wp_keycodes_namespaceObject.SPACE === event.keyCode) { 42009 onAppend(); 42010 } 42011 }, 42012 onClick: () => onAppend(), 42013 onFocus: () => { 42014 if (showPrompt) { 42015 onAppend(); 42016 } 42017 }, 42018 children: showPrompt ? value : ZWNBSP 42019 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter, { 42020 rootClientId: rootClientId, 42021 position: "bottom right", 42022 isAppender: true, 42023 __experimentalIsQuick: true 42024 })] 42025 }); 42026 } 42027 42028 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list-appender/index.js 42029 /** 42030 * External dependencies 42031 */ 42032 42033 42034 /** 42035 * WordPress dependencies 42036 */ 42037 42038 42039 42040 /** 42041 * Internal dependencies 42042 */ 42043 42044 42045 42046 42047 function DefaultAppender({ 42048 rootClientId 42049 }) { 42050 const canInsertDefaultBlock = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).canInsertBlockType((0,external_wp_blocks_namespaceObject.getDefaultBlockName)(), rootClientId)); 42051 if (canInsertDefaultBlock) { 42052 // Render the default block appender if the context supports use 42053 // of the default appender. 42054 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DefaultBlockAppender, { 42055 rootClientId: rootClientId 42056 }); 42057 } 42058 42059 // Fallback in case the default block can't be inserted. 42060 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(button_block_appender, { 42061 rootClientId: rootClientId, 42062 className: "block-list-appender__toggle" 42063 }); 42064 } 42065 function BlockListAppender({ 42066 rootClientId, 42067 CustomAppender, 42068 className, 42069 tagName: TagName = 'div' 42070 }) { 42071 const isDragOver = (0,external_wp_data_namespaceObject.useSelect)(select => { 42072 const { 42073 getBlockInsertionPoint, 42074 isBlockInsertionPointVisible, 42075 getBlockCount 42076 } = select(store); 42077 const insertionPoint = getBlockInsertionPoint(); 42078 // Ideally we should also check for `isDragging` but currently it 42079 // requires a lot more setup. We can revisit this once we refactor 42080 // the DnD utility hooks. 42081 return isBlockInsertionPointVisible() && rootClientId === insertionPoint?.rootClientId && getBlockCount(rootClientId) === 0; 42082 }, [rootClientId]); 42083 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TagName 42084 // A `tabIndex` is used on the wrapping `div` element in order to 42085 // force a focus event to occur when an appender `button` element 42086 // is clicked. In some browsers (Firefox, Safari), button clicks do 42087 // not emit a focus event, which could cause this event to propagate 42088 // unexpectedly. The `tabIndex` ensures that the interaction is 42089 // captured as a focus, without also adding an extra tab stop. 42090 // 42091 // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus 42092 , { 42093 tabIndex: -1, 42094 className: dist_clsx('block-list-appender wp-block', className, { 42095 'is-drag-over': isDragOver 42096 }) 42097 // Needed in case the whole editor is content editable (for multi 42098 // selection). It fixes an edge case where ArrowDown and ArrowRight 42099 // should collapse the selection to the end of that selection and 42100 // not into the appender. 42101 , 42102 contentEditable: false 42103 // The appender exists to let you add the first Paragraph before 42104 // any is inserted. To that end, this appender should visually be 42105 // presented as a block. That means theme CSS should style it as if 42106 // it were an empty paragraph block. That means a `wp-block` class to 42107 // ensure the width is correct, and a [data-block] attribute to ensure 42108 // the correct margin is applied, especially for classic themes which 42109 // have commonly targeted that attribute for margins. 42110 , 42111 "data-block": true, 42112 children: CustomAppender ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CustomAppender, {}) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DefaultAppender, { 42113 rootClientId: rootClientId 42114 }) 42115 }); 42116 } 42117 42118 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-popover/inbetween.js 42119 /** 42120 * External dependencies 42121 */ 42122 42123 42124 /** 42125 * WordPress dependencies 42126 */ 42127 42128 42129 42130 42131 42132 /** 42133 * Internal dependencies 42134 */ 42135 42136 42137 42138 42139 const inbetween_MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER; 42140 const InsertionPointOpenRef = (0,external_wp_element_namespaceObject.createContext)(); 42141 function BlockPopoverInbetween({ 42142 previousClientId, 42143 nextClientId, 42144 children, 42145 __unstablePopoverSlot, 42146 __unstableContentRef, 42147 operation = 'insert', 42148 nearestSide = 'right', 42149 ...props 42150 }) { 42151 // This is a temporary hack to get the inbetween inserter to recompute properly. 42152 const [popoverRecomputeCounter, forcePopoverRecompute] = (0,external_wp_element_namespaceObject.useReducer)( 42153 // Module is there to make sure that the counter doesn't overflow. 42154 s => (s + 1) % inbetween_MAX_POPOVER_RECOMPUTE_COUNTER, 0); 42155 const { 42156 orientation, 42157 rootClientId, 42158 isVisible 42159 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 42160 const { 42161 getBlockListSettings, 42162 getBlockRootClientId, 42163 isBlockVisible 42164 } = select(store); 42165 const _rootClientId = getBlockRootClientId(previousClientId !== null && previousClientId !== void 0 ? previousClientId : nextClientId); 42166 return { 42167 orientation: getBlockListSettings(_rootClientId)?.orientation || 'vertical', 42168 rootClientId: _rootClientId, 42169 isVisible: isBlockVisible(previousClientId) && isBlockVisible(nextClientId) 42170 }; 42171 }, [previousClientId, nextClientId]); 42172 const previousElement = useBlockElement(previousClientId); 42173 const nextElement = useBlockElement(nextClientId); 42174 const isVertical = orientation === 'vertical'; 42175 const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 42176 if ( 42177 // popoverRecomputeCounter is by definition always equal or greater than 0. 42178 // This check is only there to satisfy the correctness of the 42179 // exhaustive-deps rule for the `useMemo` hook. 42180 popoverRecomputeCounter < 0 || !previousElement && !nextElement || !isVisible) { 42181 return undefined; 42182 } 42183 const contextElement = operation === 'group' ? nextElement || previousElement : previousElement || nextElement; 42184 return { 42185 contextElement, 42186 getBoundingClientRect() { 42187 const previousRect = previousElement ? previousElement.getBoundingClientRect() : null; 42188 const nextRect = nextElement ? nextElement.getBoundingClientRect() : null; 42189 let left = 0; 42190 let top = 0; 42191 let width = 0; 42192 let height = 0; 42193 if (operation === 'group') { 42194 const targetRect = nextRect || previousRect; 42195 top = targetRect.top; 42196 // No spacing is likely around blocks in this operation. 42197 // So width of the inserter containing rect is set to 0. 42198 width = 0; 42199 height = targetRect.bottom - targetRect.top; 42200 // Popover calculates its distance from mid-block so some 42201 // adjustments are needed to make it appear in the right place. 42202 left = nearestSide === 'left' ? targetRect.left - 2 : targetRect.right - 2; 42203 } else if (isVertical) { 42204 // vertical 42205 top = previousRect ? previousRect.bottom : nextRect.top; 42206 width = previousRect ? previousRect.width : nextRect.width; 42207 height = nextRect && previousRect ? nextRect.top - previousRect.bottom : 0; 42208 left = previousRect ? previousRect.left : nextRect.left; 42209 } else { 42210 top = previousRect ? previousRect.top : nextRect.top; 42211 height = previousRect ? previousRect.height : nextRect.height; 42212 if ((0,external_wp_i18n_namespaceObject.isRTL)()) { 42213 // non vertical, rtl 42214 left = nextRect ? nextRect.right : previousRect.left; 42215 width = previousRect && nextRect ? previousRect.left - nextRect.right : 0; 42216 } else { 42217 // non vertical, ltr 42218 left = previousRect ? previousRect.right : nextRect.left; 42219 width = previousRect && nextRect ? nextRect.left - previousRect.right : 0; 42220 } 42221 42222 // Avoid a negative width which happens when the next rect 42223 // is on the next line. 42224 width = Math.max(width, 0); 42225 } 42226 return new window.DOMRect(left, top, width, height); 42227 } 42228 }; 42229 }, [previousElement, nextElement, popoverRecomputeCounter, isVertical, isVisible, operation, nearestSide]); 42230 const popoverScrollRef = use_popover_scroll(__unstableContentRef); 42231 42232 // This is only needed for a smooth transition when moving blocks. 42233 // When blocks are moved up/down, their position can be set by 42234 // updating the `transform` property manually (i.e. without using CSS 42235 // transitions or animations). The animation, which can also scroll the block 42236 // editor, can sometimes cause the position of the Popover to get out of sync. 42237 // A MutationObserver is therefore used to make sure that changes to the 42238 // selectedElement's attribute (i.e. `transform`) can be tracked and used to 42239 // trigger the Popover to rerender. 42240 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 42241 if (!previousElement) { 42242 return; 42243 } 42244 const observer = new window.MutationObserver(forcePopoverRecompute); 42245 observer.observe(previousElement, { 42246 attributes: true 42247 }); 42248 return () => { 42249 observer.disconnect(); 42250 }; 42251 }, [previousElement]); 42252 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 42253 if (!nextElement) { 42254 return; 42255 } 42256 const observer = new window.MutationObserver(forcePopoverRecompute); 42257 observer.observe(nextElement, { 42258 attributes: true 42259 }); 42260 return () => { 42261 observer.disconnect(); 42262 }; 42263 }, [nextElement]); 42264 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 42265 if (!previousElement) { 42266 return; 42267 } 42268 previousElement.ownerDocument.defaultView.addEventListener('resize', forcePopoverRecompute); 42269 return () => { 42270 previousElement.ownerDocument.defaultView?.removeEventListener('resize', forcePopoverRecompute); 42271 }; 42272 }, [previousElement]); 42273 42274 // If there's either a previous or a next element, show the inbetween popover. 42275 // Note that drag and drop uses the inbetween popover to show the drop indicator 42276 // before the first block and after the last block. 42277 if (!previousElement && !nextElement || !isVisible) { 42278 return null; 42279 } 42280 42281 /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ 42282 // While ideally it would be enough to capture the 42283 // bubbling focus event from the Inserter, due to the 42284 // characteristics of click focusing of `button`s in 42285 // Firefox and Safari, it is not reliable. 42286 // 42287 // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus 42288 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 42289 ref: popoverScrollRef, 42290 animate: false, 42291 anchor: popoverAnchor, 42292 focusOnMount: false 42293 // Render in the old slot if needed for backward compatibility, 42294 // otherwise render in place (not in the default popover slot). 42295 , 42296 __unstableSlotName: __unstablePopoverSlot, 42297 inline: !__unstablePopoverSlot 42298 // Forces a remount of the popover when its position changes 42299 // This makes sure the popover doesn't animate from its previous position. 42300 , 42301 ...props, 42302 className: dist_clsx('block-editor-block-popover', 'block-editor-block-popover__inbetween', props.className), 42303 resize: false, 42304 flip: false, 42305 placement: "overlay", 42306 variant: "unstyled", 42307 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 42308 className: "block-editor-block-popover__inbetween-container", 42309 children: children 42310 }) 42311 }, nextClientId + '--' + rootClientId); 42312 /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ 42313 } 42314 /* harmony default export */ const inbetween = (BlockPopoverInbetween); 42315 42316 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-popover/drop-zone.js 42317 /** 42318 * WordPress dependencies 42319 */ 42320 42321 42322 42323 42324 /** 42325 * Internal dependencies 42326 */ 42327 42328 42329 42330 const animateVariants = { 42331 hide: { 42332 opacity: 0, 42333 scaleY: 0.75 42334 }, 42335 show: { 42336 opacity: 1, 42337 scaleY: 1 42338 }, 42339 exit: { 42340 opacity: 0, 42341 scaleY: 0.9 42342 } 42343 }; 42344 function BlockDropZonePopover({ 42345 __unstablePopoverSlot, 42346 __unstableContentRef 42347 }) { 42348 const { 42349 clientId 42350 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 42351 const { 42352 getBlockOrder, 42353 getBlockInsertionPoint 42354 } = select(store); 42355 const insertionPoint = getBlockInsertionPoint(); 42356 const order = getBlockOrder(insertionPoint.rootClientId); 42357 if (!order.length) { 42358 return {}; 42359 } 42360 return { 42361 clientId: order[insertionPoint.index] 42362 }; 42363 }, []); 42364 const reducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 42365 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(cover, { 42366 clientId: clientId, 42367 __unstablePopoverSlot: __unstablePopoverSlot, 42368 __unstableContentRef: __unstableContentRef, 42369 className: "block-editor-block-popover__drop-zone", 42370 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 42371 "data-testid": "block-popover-drop-zone", 42372 initial: reducedMotion ? animateVariants.show : animateVariants.hide, 42373 animate: animateVariants.show, 42374 exit: reducedMotion ? animateVariants.show : animateVariants.exit, 42375 className: "block-editor-block-popover__drop-zone-foreground" 42376 }) 42377 }); 42378 } 42379 /* harmony default export */ const drop_zone = (BlockDropZonePopover); 42380 42381 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/insertion-point.js 42382 /** 42383 * External dependencies 42384 */ 42385 42386 42387 /** 42388 * WordPress dependencies 42389 */ 42390 42391 42392 42393 42394 42395 /** 42396 * Internal dependencies 42397 */ 42398 42399 42400 42401 42402 42403 42404 const insertion_point_InsertionPointOpenRef = (0,external_wp_element_namespaceObject.createContext)(); 42405 function InbetweenInsertionPointPopover({ 42406 __unstablePopoverSlot, 42407 __unstableContentRef, 42408 operation = 'insert', 42409 nearestSide = 'right' 42410 }) { 42411 const { 42412 selectBlock, 42413 hideInsertionPoint 42414 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 42415 const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef); 42416 const ref = (0,external_wp_element_namespaceObject.useRef)(); 42417 const { 42418 orientation, 42419 previousClientId, 42420 nextClientId, 42421 rootClientId, 42422 isInserterShown, 42423 isDistractionFree, 42424 isZoomOutMode 42425 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 42426 const { 42427 getBlockOrder, 42428 getBlockListSettings, 42429 getBlockInsertionPoint, 42430 isBlockBeingDragged, 42431 getPreviousBlockClientId, 42432 getNextBlockClientId, 42433 getSettings, 42434 isZoomOut 42435 } = unlock(select(store)); 42436 const insertionPoint = getBlockInsertionPoint(); 42437 const order = getBlockOrder(insertionPoint.rootClientId); 42438 if (!order.length) { 42439 return {}; 42440 } 42441 let _previousClientId = order[insertionPoint.index - 1]; 42442 let _nextClientId = order[insertionPoint.index]; 42443 while (isBlockBeingDragged(_previousClientId)) { 42444 _previousClientId = getPreviousBlockClientId(_previousClientId); 42445 } 42446 while (isBlockBeingDragged(_nextClientId)) { 42447 _nextClientId = getNextBlockClientId(_nextClientId); 42448 } 42449 const settings = getSettings(); 42450 return { 42451 previousClientId: _previousClientId, 42452 nextClientId: _nextClientId, 42453 orientation: getBlockListSettings(insertionPoint.rootClientId)?.orientation || 'vertical', 42454 rootClientId: insertionPoint.rootClientId, 42455 isDistractionFree: settings.isDistractionFree, 42456 isInserterShown: insertionPoint?.__unstableWithInserter, 42457 isZoomOutMode: isZoomOut() 42458 }; 42459 }, []); 42460 const { 42461 getBlockEditingMode 42462 } = (0,external_wp_data_namespaceObject.useSelect)(store); 42463 const disableMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 42464 function onClick(event) { 42465 if (event.target === ref.current && nextClientId && getBlockEditingMode(nextClientId) !== 'disabled') { 42466 selectBlock(nextClientId, -1); 42467 } 42468 } 42469 function maybeHideInserterPoint(event) { 42470 // Only hide the inserter if it's triggered on the wrapper, 42471 // and the inserter is not open. 42472 if (event.target === ref.current && !openRef.current) { 42473 hideInsertionPoint(); 42474 } 42475 } 42476 function onFocus(event) { 42477 // Only handle click on the wrapper specifically, and not an event 42478 // bubbled from the inserter itself. 42479 if (event.target !== ref.current) { 42480 openRef.current = true; 42481 } 42482 } 42483 const lineVariants = { 42484 // Initial position starts from the center and invisible. 42485 start: { 42486 opacity: 0, 42487 scale: 0 42488 }, 42489 // The line expands to fill the container. If the inserter is visible it 42490 // is delayed so it appears orchestrated. 42491 rest: { 42492 opacity: 1, 42493 scale: 1, 42494 transition: { 42495 delay: isInserterShown ? 0.5 : 0, 42496 type: 'tween' 42497 } 42498 }, 42499 hover: { 42500 opacity: 1, 42501 scale: 1, 42502 transition: { 42503 delay: 0.5, 42504 type: 'tween' 42505 } 42506 } 42507 }; 42508 const inserterVariants = { 42509 start: { 42510 scale: disableMotion ? 1 : 0 42511 }, 42512 rest: { 42513 scale: 1, 42514 transition: { 42515 delay: 0.4, 42516 type: 'tween' 42517 } 42518 } 42519 }; 42520 if (isDistractionFree) { 42521 return null; 42522 } 42523 42524 // Zoom out mode should only show the insertion point for the insert operation. 42525 // Other operations such as "group" are when the editor tries to create a row 42526 // block by grouping the block being dragged with the block it's being dropped 42527 // onto. 42528 if (isZoomOutMode && operation !== 'insert') { 42529 return null; 42530 } 42531 const orientationClassname = orientation === 'horizontal' || operation === 'group' ? 'is-horizontal' : 'is-vertical'; 42532 const className = dist_clsx('block-editor-block-list__insertion-point', orientationClassname); 42533 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inbetween, { 42534 previousClientId: previousClientId, 42535 nextClientId: nextClientId, 42536 __unstablePopoverSlot: __unstablePopoverSlot, 42537 __unstableContentRef: __unstableContentRef, 42538 operation: operation, 42539 nearestSide: nearestSide, 42540 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__unstableMotion.div, { 42541 layout: !disableMotion, 42542 initial: disableMotion ? 'rest' : 'start', 42543 animate: "rest", 42544 whileHover: "hover", 42545 whileTap: "pressed", 42546 exit: "start", 42547 ref: ref, 42548 tabIndex: -1, 42549 onClick: onClick, 42550 onFocus: onFocus, 42551 className: dist_clsx(className, { 42552 'is-with-inserter': isInserterShown 42553 }), 42554 onHoverEnd: maybeHideInserterPoint, 42555 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 42556 variants: lineVariants, 42557 className: "block-editor-block-list__insertion-point-indicator", 42558 "data-testid": "block-list-insertion-point-indicator" 42559 }), isInserterShown && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 42560 variants: inserterVariants, 42561 className: dist_clsx('block-editor-block-list__insertion-point-inserter'), 42562 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter, { 42563 position: "bottom center", 42564 clientId: nextClientId, 42565 rootClientId: rootClientId, 42566 __experimentalIsQuick: true, 42567 onToggle: isOpen => { 42568 openRef.current = isOpen; 42569 }, 42570 onSelectOrClose: () => { 42571 openRef.current = false; 42572 } 42573 }) 42574 })] 42575 }) 42576 }); 42577 } 42578 function InsertionPoint(props) { 42579 const { 42580 insertionPoint, 42581 isVisible, 42582 isBlockListEmpty 42583 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 42584 const { 42585 getBlockInsertionPoint, 42586 isBlockInsertionPointVisible, 42587 getBlockCount 42588 } = select(store); 42589 const blockInsertionPoint = getBlockInsertionPoint(); 42590 return { 42591 insertionPoint: blockInsertionPoint, 42592 isVisible: isBlockInsertionPointVisible(), 42593 isBlockListEmpty: getBlockCount(blockInsertionPoint?.rootClientId) === 0 42594 }; 42595 }, []); 42596 if (!isVisible || 42597 // Don't render the insertion point if the block list is empty. 42598 // The insertion point will be represented by the appender instead. 42599 isBlockListEmpty) { 42600 return null; 42601 } 42602 42603 /** 42604 * Render a popover that overlays the block when the desired operation is to replace it. 42605 * Otherwise, render a popover in between blocks for the indication of inserting between them. 42606 */ 42607 return insertionPoint.operation === 'replace' ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(drop_zone 42608 // Force remount to trigger the animation. 42609 , { 42610 ...props 42611 }, `$insertionPoint.rootClientId}-$insertionPoint.index}`) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InbetweenInsertionPointPopover, { 42612 operation: insertionPoint.operation, 42613 nearestSide: insertionPoint.nearestSide, 42614 ...props 42615 }); 42616 } 42617 42618 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-in-between-inserter.js 42619 /** 42620 * WordPress dependencies 42621 */ 42622 42623 42624 42625 42626 42627 /** 42628 * Internal dependencies 42629 */ 42630 42631 42632 42633 function useInBetweenInserter() { 42634 const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef); 42635 const isInBetweenInserterDisabled = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree || unlock(select(store)).isZoomOut(), []); 42636 const { 42637 getBlockListSettings, 42638 getBlockIndex, 42639 isMultiSelecting, 42640 getSelectedBlockClientIds, 42641 getSettings, 42642 getTemplateLock, 42643 __unstableIsWithinBlockOverlay, 42644 getBlockEditingMode, 42645 getBlockName, 42646 getBlockAttributes, 42647 getParentSectionBlock 42648 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 42649 const { 42650 showInsertionPoint, 42651 hideInsertionPoint 42652 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 42653 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 42654 if (isInBetweenInserterDisabled) { 42655 return; 42656 } 42657 function onMouseMove(event) { 42658 // openRef is the reference to the insertion point between blocks. 42659 // If the reference is not set or the insertion point is already open, return. 42660 if (openRef === undefined || openRef.current) { 42661 return; 42662 } 42663 42664 // Ignore text nodes sometimes detected in FireFox. 42665 if (event.target.nodeType === event.target.TEXT_NODE) { 42666 return; 42667 } 42668 if (isMultiSelecting()) { 42669 return; 42670 } 42671 if (!event.target.classList.contains('block-editor-block-list__layout')) { 42672 hideInsertionPoint(); 42673 return; 42674 } 42675 let rootClientId; 42676 if (!event.target.classList.contains('is-root-container')) { 42677 const blockElement = !!event.target.getAttribute('data-block') ? event.target : event.target.closest('[data-block]'); 42678 rootClientId = blockElement.getAttribute('data-block'); 42679 } 42680 if (getTemplateLock(rootClientId) || getBlockEditingMode(rootClientId) === 'disabled' || getBlockName(rootClientId) === 'core/block' || rootClientId && getBlockAttributes(rootClientId).layout?.isManualPlacement) { 42681 return; 42682 } 42683 const blockListSettings = getBlockListSettings(rootClientId); 42684 const orientation = blockListSettings?.orientation || 'vertical'; 42685 const captureToolbars = !!blockListSettings?.__experimentalCaptureToolbars; 42686 const offsetTop = event.clientY; 42687 const offsetLeft = event.clientX; 42688 const children = Array.from(event.target.children); 42689 let element = children.find(blockEl => { 42690 const blockElRect = blockEl.getBoundingClientRect(); 42691 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); 42692 }); 42693 if (!element) { 42694 hideInsertionPoint(); 42695 return; 42696 } 42697 42698 // The block may be in an alignment wrapper, so check the first direct 42699 // child if the element has no ID. 42700 if (!element.id) { 42701 element = element.firstElementChild; 42702 if (!element) { 42703 hideInsertionPoint(); 42704 return; 42705 } 42706 } 42707 42708 // Don't show the insertion point if a parent block has an "overlay" 42709 // See https://github.com/WordPress/gutenberg/pull/34012#pullrequestreview-727762337 42710 const clientId = element.id.slice('block-'.length); 42711 if (!clientId || __unstableIsWithinBlockOverlay(clientId) || !!getParentSectionBlock(clientId)) { 42712 return; 42713 } 42714 42715 // Don't show the inserter if the following conditions are met, 42716 // as it conflicts with the block toolbar: 42717 // 1. when hovering above or inside selected block(s) 42718 // 2. when the orientation is vertical 42719 // 3. when the __experimentalCaptureToolbars is not enabled 42720 // 4. when the Top Toolbar is not disabled 42721 if (getSelectedBlockClientIds().includes(clientId) && orientation === 'vertical' && !captureToolbars && !getSettings().hasFixedToolbar) { 42722 return; 42723 } 42724 const elementRect = element.getBoundingClientRect(); 42725 if (orientation === 'horizontal' && (event.clientY > elementRect.bottom || event.clientY < elementRect.top) || orientation === 'vertical' && (event.clientX > elementRect.right || event.clientX < elementRect.left)) { 42726 hideInsertionPoint(); 42727 return; 42728 } 42729 const index = getBlockIndex(clientId); 42730 42731 // Don't show the in-between inserter before the first block in 42732 // the list (preserves the original behaviour). 42733 if (index === 0) { 42734 hideInsertionPoint(); 42735 return; 42736 } 42737 showInsertionPoint(rootClientId, index, { 42738 __unstableWithInserter: true 42739 }); 42740 } 42741 node.addEventListener('mousemove', onMouseMove); 42742 return () => { 42743 node.removeEventListener('mousemove', onMouseMove); 42744 }; 42745 }, [openRef, getBlockListSettings, getBlockIndex, isMultiSelecting, showInsertionPoint, hideInsertionPoint, getSelectedBlockClientIds, isInBetweenInserterDisabled]); 42746 } 42747 42748 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-selection-clearer/index.js 42749 /** 42750 * WordPress dependencies 42751 */ 42752 42753 42754 42755 /** 42756 * Internal dependencies 42757 */ 42758 42759 42760 /** 42761 * Pass the returned ref callback to an element that should clear block 42762 * selection. Selection will only be cleared if the element is clicked directly, 42763 * not if a child element is clicked. 42764 * 42765 * @return {import('react').RefCallback} Ref callback. 42766 */ 42767 42768 function useBlockSelectionClearer() { 42769 const { 42770 getSettings, 42771 hasSelectedBlock, 42772 hasMultiSelection 42773 } = (0,external_wp_data_namespaceObject.useSelect)(store); 42774 const { 42775 clearSelectedBlock 42776 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 42777 const { 42778 clearBlockSelection: isEnabled 42779 } = getSettings(); 42780 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 42781 if (!isEnabled) { 42782 return; 42783 } 42784 function onMouseDown(event) { 42785 if (!hasSelectedBlock() && !hasMultiSelection()) { 42786 return; 42787 } 42788 42789 // Only handle clicks on the element, not the children. 42790 if (event.target !== node) { 42791 return; 42792 } 42793 clearSelectedBlock(); 42794 } 42795 node.addEventListener('mousedown', onMouseDown); 42796 return () => { 42797 node.removeEventListener('mousedown', onMouseDown); 42798 }; 42799 }, [hasSelectedBlock, hasMultiSelection, clearSelectedBlock, isEnabled]); 42800 } 42801 function BlockSelectionClearer(props) { 42802 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 42803 ref: useBlockSelectionClearer(), 42804 ...props 42805 }); 42806 } 42807 42808 ;// ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/button-block-appender.js 42809 /** 42810 * External dependencies 42811 */ 42812 42813 42814 /** 42815 * Internal dependencies 42816 */ 42817 42818 42819 42820 function ButtonBlockAppender({ 42821 showSeparator, 42822 isFloating, 42823 onAddBlock, 42824 isToggle 42825 }) { 42826 const { 42827 clientId 42828 } = useBlockEditContext(); 42829 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(button_block_appender, { 42830 className: dist_clsx({ 42831 'block-list-appender__toggle': isToggle 42832 }), 42833 rootClientId: clientId, 42834 showSeparator: showSeparator, 42835 isFloating: isFloating, 42836 onAddBlock: onAddBlock 42837 }); 42838 } 42839 42840 ;// ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/default-block-appender.js 42841 /** 42842 * Internal dependencies 42843 */ 42844 42845 42846 42847 function default_block_appender_DefaultBlockAppender() { 42848 const { 42849 clientId 42850 } = useBlockEditContext(); 42851 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DefaultBlockAppender, { 42852 rootClientId: clientId 42853 }); 42854 } 42855 42856 ;// ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-nested-settings-update.js 42857 /** 42858 * WordPress dependencies 42859 */ 42860 42861 42862 42863 42864 42865 /** 42866 * Internal dependencies 42867 */ 42868 42869 42870 42871 /** @typedef {import('../../selectors').WPDirectInsertBlock } WPDirectInsertBlock */ 42872 42873 const pendingSettingsUpdates = new WeakMap(); 42874 42875 // Creates a memoizing caching function that remembers the last value and keeps returning it 42876 // as long as the new values are shallowly equal. Helps keep dependencies stable. 42877 function createShallowMemo() { 42878 let value; 42879 return newValue => { 42880 if (value === undefined || !external_wp_isShallowEqual_default()(value, newValue)) { 42881 value = newValue; 42882 } 42883 return value; 42884 }; 42885 } 42886 function useShallowMemo(value) { 42887 const [memo] = (0,external_wp_element_namespaceObject.useState)(createShallowMemo); 42888 return memo(value); 42889 } 42890 42891 /** 42892 * This hook is a side effect which updates the block-editor store when changes 42893 * happen to inner block settings. The given props are transformed into a 42894 * settings object, and if that is different from the current settings object in 42895 * the block-editor store, then the store is updated with the new settings which 42896 * came from props. 42897 * 42898 * @param {string} clientId The client ID of the block to update. 42899 * @param {string} parentLock 42900 * @param {string[]} allowedBlocks An array of block names which are permitted 42901 * in inner blocks. 42902 * @param {string[]} prioritizedInserterBlocks Block names and/or block variations to be prioritized in the inserter, in the format {blockName}/{variationName}. 42903 * @param {?WPDirectInsertBlock} defaultBlock The default block to insert: [ blockName, { blockAttributes } ]. 42904 * @param {?boolean} directInsert If a default block should be inserted directly by the appender. 42905 * 42906 * @param {?WPDirectInsertBlock} __experimentalDefaultBlock A deprecated prop for the default block to insert: [ blockName, { blockAttributes } ]. Use `defaultBlock` instead. 42907 * 42908 * @param {?boolean} __experimentalDirectInsert A deprecated prop for whether a default block should be inserted directly by the appender. Use `directInsert` instead. 42909 * 42910 * @param {string} [templateLock] The template lock specified for the inner 42911 * blocks component. (e.g. "all") 42912 * @param {boolean} captureToolbars Whether or children toolbars should be shown 42913 * in the inner blocks component rather than on 42914 * the child block. 42915 * @param {string} orientation The direction in which the block 42916 * should face. 42917 * @param {Object} layout The layout object for the block container. 42918 */ 42919 function useNestedSettingsUpdate(clientId, parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout) { 42920 // Instead of adding a useSelect mapping here, please add to the useSelect 42921 // mapping in InnerBlocks! Every subscription impacts performance. 42922 42923 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 42924 42925 // Implementors often pass a new array on every render, 42926 // and the contents of the arrays are just strings, so the entire array 42927 // can be passed as dependencies but We need to include the length of the array, 42928 // otherwise if the arrays change length but the first elements are equal the comparison, 42929 // does not works as expected. 42930 const _allowedBlocks = useShallowMemo(allowedBlocks); 42931 const _prioritizedInserterBlocks = useShallowMemo(prioritizedInserterBlocks); 42932 const _templateLock = templateLock === undefined || parentLock === 'contentOnly' ? parentLock : templateLock; 42933 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 42934 const newSettings = { 42935 allowedBlocks: _allowedBlocks, 42936 prioritizedInserterBlocks: _prioritizedInserterBlocks, 42937 templateLock: _templateLock 42938 }; 42939 42940 // These values are not defined for RN, so only include them if they 42941 // are defined. 42942 if (captureToolbars !== undefined) { 42943 newSettings.__experimentalCaptureToolbars = captureToolbars; 42944 } 42945 42946 // Orientation depends on layout, 42947 // ideally the separate orientation prop should be deprecated. 42948 if (orientation !== undefined) { 42949 newSettings.orientation = orientation; 42950 } else { 42951 const layoutType = getLayoutType(layout?.type); 42952 newSettings.orientation = layoutType.getOrientation(layout); 42953 } 42954 if (__experimentalDefaultBlock !== undefined) { 42955 external_wp_deprecated_default()('__experimentalDefaultBlock', { 42956 alternative: 'defaultBlock', 42957 since: '6.3', 42958 version: '6.4' 42959 }); 42960 newSettings.defaultBlock = __experimentalDefaultBlock; 42961 } 42962 if (defaultBlock !== undefined) { 42963 newSettings.defaultBlock = defaultBlock; 42964 } 42965 if (__experimentalDirectInsert !== undefined) { 42966 external_wp_deprecated_default()('__experimentalDirectInsert', { 42967 alternative: 'directInsert', 42968 since: '6.3', 42969 version: '6.4' 42970 }); 42971 newSettings.directInsert = __experimentalDirectInsert; 42972 } 42973 if (directInsert !== undefined) { 42974 newSettings.directInsert = directInsert; 42975 } 42976 if (newSettings.directInsert !== undefined && typeof newSettings.directInsert !== 'boolean') { 42977 external_wp_deprecated_default()('Using `Function` as a `directInsert` argument', { 42978 alternative: '`boolean` values', 42979 since: '6.5' 42980 }); 42981 } 42982 42983 // Batch updates to block list settings to avoid triggering cascading renders 42984 // for each container block included in a tree and optimize initial render. 42985 // To avoid triggering updateBlockListSettings for each container block 42986 // causing X re-renderings for X container blocks, 42987 // we batch all the updatedBlockListSettings in a single "data" batch 42988 // which results in a single re-render. 42989 if (!pendingSettingsUpdates.get(registry)) { 42990 pendingSettingsUpdates.set(registry, {}); 42991 } 42992 pendingSettingsUpdates.get(registry)[clientId] = newSettings; 42993 window.queueMicrotask(() => { 42994 const settings = pendingSettingsUpdates.get(registry); 42995 if (Object.keys(settings).length) { 42996 const { 42997 updateBlockListSettings 42998 } = registry.dispatch(store); 42999 updateBlockListSettings(settings); 43000 pendingSettingsUpdates.set(registry, {}); 43001 } 43002 }); 43003 }, [clientId, _allowedBlocks, _prioritizedInserterBlocks, _templateLock, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, captureToolbars, orientation, layout, registry]); 43004 } 43005 43006 ;// ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-inner-block-template-sync.js 43007 /** 43008 * External dependencies 43009 */ 43010 43011 43012 /** 43013 * WordPress dependencies 43014 */ 43015 43016 43017 43018 43019 /** 43020 * Internal dependencies 43021 */ 43022 43023 43024 /** 43025 * This hook makes sure that a block's inner blocks stay in sync with the given 43026 * block "template". The template is a block hierarchy to which inner blocks must 43027 * conform. If the blocks get "out of sync" with the template and the template 43028 * is meant to be locked (e.g. templateLock = "all" or templateLock = "contentOnly"), 43029 * then we replace the inner blocks with the correct value after synchronizing it with the template. 43030 * 43031 * @param {string} clientId The block client ID. 43032 * @param {Object} template The template to match. 43033 * @param {string} templateLock The template lock state for the inner blocks. For 43034 * example, if the template lock is set to "all", 43035 * then the inner blocks will stay in sync with the 43036 * template. If not defined or set to false, then 43037 * the inner blocks will not be synchronized with 43038 * the given template. 43039 * @param {boolean} templateInsertUpdatesSelection Whether or not to update the 43040 * block-editor selection state when inner blocks 43041 * are replaced after template synchronization. 43042 */ 43043 function useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection) { 43044 // Instead of adding a useSelect mapping here, please add to the useSelect 43045 // mapping in InnerBlocks! Every subscription impacts performance. 43046 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 43047 43048 // Maintain a reference to the previous value so we can do a deep equality check. 43049 const existingTemplateRef = (0,external_wp_element_namespaceObject.useRef)(null); 43050 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 43051 let isCancelled = false; 43052 const { 43053 getBlocks, 43054 getSelectedBlocksInitialCaretPosition, 43055 isBlockSelected 43056 } = registry.select(store); 43057 const { 43058 replaceInnerBlocks, 43059 __unstableMarkNextChangeAsNotPersistent 43060 } = registry.dispatch(store); 43061 43062 // There's an implicit dependency between useInnerBlockTemplateSync and useNestedSettingsUpdate 43063 // The former needs to happen after the latter and since the latter is using microtasks to batch updates (performance optimization), 43064 // we need to schedule this one in a microtask as well. 43065 // Example: If you remove queueMicrotask here, ctrl + click to insert quote block won't close the inserter. 43066 window.queueMicrotask(() => { 43067 if (isCancelled) { 43068 return; 43069 } 43070 43071 // Only synchronize innerBlocks with template if innerBlocks are empty 43072 // or a locking "all" or "contentOnly" exists directly on the block. 43073 const currentInnerBlocks = getBlocks(clientId); 43074 const shouldApplyTemplate = currentInnerBlocks.length === 0 || templateLock === 'all' || templateLock === 'contentOnly'; 43075 const hasTemplateChanged = !es6_default()(template, existingTemplateRef.current); 43076 if (!shouldApplyTemplate || !hasTemplateChanged) { 43077 return; 43078 } 43079 existingTemplateRef.current = template; 43080 const nextBlocks = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(currentInnerBlocks, template); 43081 if (!es6_default()(nextBlocks, currentInnerBlocks)) { 43082 __unstableMarkNextChangeAsNotPersistent(); 43083 replaceInnerBlocks(clientId, nextBlocks, currentInnerBlocks.length === 0 && templateInsertUpdatesSelection && nextBlocks.length !== 0 && isBlockSelected(clientId), 43084 // This ensures the "initialPosition" doesn't change when applying the template 43085 // If we're supposed to focus the block, we'll focus the first inner block 43086 // otherwise, we won't apply any auto-focus. 43087 // This ensures for instance that the focus stays in the inserter when inserting the "buttons" block. 43088 getSelectedBlocksInitialCaretPosition()); 43089 } 43090 }); 43091 return () => { 43092 isCancelled = true; 43093 }; 43094 }, [template, templateLock, clientId, registry, templateInsertUpdatesSelection]); 43095 } 43096 43097 ;// ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-block-context.js 43098 /** 43099 * WordPress dependencies 43100 */ 43101 43102 43103 43104 /** 43105 * Internal dependencies 43106 */ 43107 43108 43109 /** 43110 * Returns a context object for a given block. 43111 * 43112 * @param {string} clientId The block client ID. 43113 * 43114 * @return {Record<string,*>} Context value. 43115 */ 43116 function useBlockContext(clientId) { 43117 return (0,external_wp_data_namespaceObject.useSelect)(select => { 43118 const block = select(store).getBlock(clientId); 43119 if (!block) { 43120 return undefined; 43121 } 43122 const blockType = select(external_wp_blocks_namespaceObject.store).getBlockType(block.name); 43123 if (!blockType) { 43124 return undefined; 43125 } 43126 if (Object.keys(blockType.providesContext).length === 0) { 43127 return undefined; 43128 } 43129 return Object.fromEntries(Object.entries(blockType.providesContext).map(([contextName, attributeName]) => [contextName, block.attributes[attributeName]])); 43130 }, [clientId]); 43131 } 43132 43133 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-on-block-drop/index.js 43134 /** 43135 * WordPress dependencies 43136 */ 43137 43138 43139 43140 43141 43142 /** 43143 * Internal dependencies 43144 */ 43145 43146 43147 /** @typedef {import('react').SyntheticEvent} SyntheticEvent */ 43148 /** @typedef {import('./types').WPDropOperation} WPDropOperation */ 43149 43150 /** 43151 * Retrieve the data for a block drop event. 43152 * 43153 * @param {SyntheticEvent} event The drop event. 43154 * 43155 * @return {Object} An object with block drag and drop data. 43156 */ 43157 function parseDropEvent(event) { 43158 let result = { 43159 srcRootClientId: null, 43160 srcClientIds: null, 43161 srcIndex: null, 43162 type: null, 43163 blocks: null 43164 }; 43165 if (!event.dataTransfer) { 43166 return result; 43167 } 43168 try { 43169 result = Object.assign(result, JSON.parse(event.dataTransfer.getData('wp-blocks'))); 43170 } catch (err) { 43171 return result; 43172 } 43173 return result; 43174 } 43175 43176 /** 43177 * A function that returns an event handler function for block drop events. 43178 * 43179 * @param {string} targetRootClientId The root client id where the block(s) will be inserted. 43180 * @param {number} targetBlockIndex The index where the block(s) will be inserted. 43181 * @param {Function} getBlockIndex A function that gets the index of a block. 43182 * @param {Function} getClientIdsOfDescendants A function that gets the client ids of descendant blocks. 43183 * @param {Function} moveBlocks A function that moves blocks. 43184 * @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks. 43185 * @param {Function} clearSelectedBlock A function that clears block selection. 43186 * @param {string} operation The type of operation to perform on drop. Could be `insert` or `replace` or `group`. 43187 * @param {Function} getBlock A function that returns a block given its client id. 43188 * @return {Function} The event handler for a block drop event. 43189 */ 43190 function onBlockDrop(targetRootClientId, targetBlockIndex, getBlockIndex, getClientIdsOfDescendants, moveBlocks, insertOrReplaceBlocks, clearSelectedBlock, operation, getBlock) { 43191 return event => { 43192 const { 43193 srcRootClientId: sourceRootClientId, 43194 srcClientIds: sourceClientIds, 43195 type: dropType, 43196 blocks 43197 } = parseDropEvent(event); 43198 43199 // If the user is inserting a block. 43200 if (dropType === 'inserter') { 43201 clearSelectedBlock(); 43202 const blocksToInsert = blocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 43203 insertOrReplaceBlocks(blocksToInsert, true, null); 43204 } 43205 43206 // If the user is moving a block. 43207 if (dropType === 'block') { 43208 const sourceBlockIndex = getBlockIndex(sourceClientIds[0]); 43209 43210 // If the user is dropping to the same position, return early. 43211 if (sourceRootClientId === targetRootClientId && sourceBlockIndex === targetBlockIndex) { 43212 return; 43213 } 43214 43215 // If the user is attempting to drop a block within its own 43216 // nested blocks, return early as this would create infinite 43217 // recursion. 43218 if (sourceClientIds.includes(targetRootClientId) || getClientIdsOfDescendants(sourceClientIds).some(id => id === targetRootClientId)) { 43219 return; 43220 } 43221 43222 // If the user is dropping a block over another block, replace both blocks 43223 // with a group block containing them 43224 if (operation === 'group') { 43225 const blocksToInsert = sourceClientIds.map(clientId => getBlock(clientId)); 43226 insertOrReplaceBlocks(blocksToInsert, true, null, sourceClientIds); 43227 return; 43228 } 43229 const isAtSameLevel = sourceRootClientId === targetRootClientId; 43230 const draggedBlockCount = sourceClientIds.length; 43231 43232 // If the block is kept at the same level and moved downwards, 43233 // subtract to take into account that the blocks being dragged 43234 // were removed from the block list above the insertion point. 43235 const insertIndex = isAtSameLevel && sourceBlockIndex < targetBlockIndex ? targetBlockIndex - draggedBlockCount : targetBlockIndex; 43236 moveBlocks(sourceClientIds, sourceRootClientId, insertIndex); 43237 } 43238 }; 43239 } 43240 43241 /** 43242 * A function that returns an event handler function for block-related file drop events. 43243 * 43244 * @param {string} targetRootClientId The root client id where the block(s) will be inserted. 43245 * @param {Function} getSettings A function that gets the block editor settings. 43246 * @param {Function} updateBlockAttributes A function that updates a block's attributes. 43247 * @param {Function} canInsertBlockType A function that returns checks whether a block type can be inserted. 43248 * @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks. 43249 * 43250 * @return {Function} The event handler for a block-related file drop event. 43251 */ 43252 function onFilesDrop(targetRootClientId, getSettings, updateBlockAttributes, canInsertBlockType, insertOrReplaceBlocks) { 43253 return files => { 43254 if (!getSettings().mediaUpload) { 43255 return; 43256 } 43257 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)); 43258 if (transformation) { 43259 const blocks = transformation.transform(files, updateBlockAttributes); 43260 insertOrReplaceBlocks(blocks); 43261 } 43262 }; 43263 } 43264 43265 /** 43266 * A function that returns an event handler function for block-related HTML drop events. 43267 * 43268 * @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks. 43269 * 43270 * @return {Function} The event handler for a block-related HTML drop event. 43271 */ 43272 function onHTMLDrop(insertOrReplaceBlocks) { 43273 return HTML => { 43274 const blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 43275 HTML, 43276 mode: 'BLOCKS' 43277 }); 43278 if (blocks.length) { 43279 insertOrReplaceBlocks(blocks); 43280 } 43281 }; 43282 } 43283 43284 /** 43285 * A React hook for handling block drop events. 43286 * 43287 * @param {string} targetRootClientId The root client id where the block(s) will be inserted. 43288 * @param {number} targetBlockIndex The index where the block(s) will be inserted. 43289 * @param {Object} options The optional options. 43290 * @param {WPDropOperation} [options.operation] The type of operation to perform on drop. Could be `insert` or `replace` for now. 43291 * 43292 * @return {Function} A function to be passed to the onDrop handler. 43293 */ 43294 function useOnBlockDrop(targetRootClientId, targetBlockIndex, options = {}) { 43295 const { 43296 operation = 'insert', 43297 nearestSide = 'right' 43298 } = options; 43299 const { 43300 canInsertBlockType, 43301 getBlockIndex, 43302 getClientIdsOfDescendants, 43303 getBlockOrder, 43304 getBlocksByClientId, 43305 getSettings, 43306 getBlock 43307 } = (0,external_wp_data_namespaceObject.useSelect)(store); 43308 const { 43309 getGroupingBlockName 43310 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 43311 const { 43312 insertBlocks, 43313 moveBlocksToPosition, 43314 updateBlockAttributes, 43315 clearSelectedBlock, 43316 replaceBlocks, 43317 removeBlocks 43318 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 43319 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 43320 const insertOrReplaceBlocks = (0,external_wp_element_namespaceObject.useCallback)((blocks, updateSelection = true, initialPosition = 0, clientIdsToReplace = []) => { 43321 if (!Array.isArray(blocks)) { 43322 blocks = [blocks]; 43323 } 43324 const clientIds = getBlockOrder(targetRootClientId); 43325 const clientId = clientIds[targetBlockIndex]; 43326 if (operation === 'replace') { 43327 replaceBlocks(clientId, blocks, undefined, initialPosition); 43328 } else if (operation === 'group') { 43329 const targetBlock = getBlock(clientId); 43330 if (nearestSide === 'left') { 43331 blocks.push(targetBlock); 43332 } else { 43333 blocks.unshift(targetBlock); 43334 } 43335 const groupInnerBlocks = blocks.map(block => { 43336 return (0,external_wp_blocks_namespaceObject.createBlock)(block.name, block.attributes, block.innerBlocks); 43337 }); 43338 const areAllImages = blocks.every(block => { 43339 return block.name === 'core/image'; 43340 }); 43341 const galleryBlock = canInsertBlockType('core/gallery', targetRootClientId); 43342 const wrappedBlocks = (0,external_wp_blocks_namespaceObject.createBlock)(areAllImages && galleryBlock ? 'core/gallery' : getGroupingBlockName(), { 43343 layout: { 43344 type: 'flex', 43345 flexWrap: areAllImages && galleryBlock ? null : 'nowrap' 43346 } 43347 }, groupInnerBlocks); 43348 // Need to make sure both the target block and the block being dragged are replaced 43349 // otherwise the dragged block will be duplicated. 43350 replaceBlocks([clientId, ...clientIdsToReplace], wrappedBlocks, undefined, initialPosition); 43351 } else { 43352 insertBlocks(blocks, targetBlockIndex, targetRootClientId, updateSelection, initialPosition); 43353 } 43354 }, [getBlockOrder, targetRootClientId, targetBlockIndex, operation, replaceBlocks, getBlock, nearestSide, canInsertBlockType, getGroupingBlockName, insertBlocks]); 43355 const moveBlocks = (0,external_wp_element_namespaceObject.useCallback)((sourceClientIds, sourceRootClientId, insertIndex) => { 43356 if (operation === 'replace') { 43357 const sourceBlocks = getBlocksByClientId(sourceClientIds); 43358 const targetBlockClientIds = getBlockOrder(targetRootClientId); 43359 const targetBlockClientId = targetBlockClientIds[targetBlockIndex]; 43360 registry.batch(() => { 43361 // Remove the source blocks. 43362 removeBlocks(sourceClientIds, false); 43363 // Replace the target block with the source blocks. 43364 replaceBlocks(targetBlockClientId, sourceBlocks, undefined, 0); 43365 }); 43366 } else { 43367 moveBlocksToPosition(sourceClientIds, sourceRootClientId, targetRootClientId, insertIndex); 43368 } 43369 }, [operation, getBlockOrder, getBlocksByClientId, moveBlocksToPosition, registry, removeBlocks, replaceBlocks, targetBlockIndex, targetRootClientId]); 43370 const _onDrop = onBlockDrop(targetRootClientId, targetBlockIndex, getBlockIndex, getClientIdsOfDescendants, moveBlocks, insertOrReplaceBlocks, clearSelectedBlock, operation, getBlock); 43371 const _onFilesDrop = onFilesDrop(targetRootClientId, getSettings, updateBlockAttributes, canInsertBlockType, insertOrReplaceBlocks); 43372 const _onHTMLDrop = onHTMLDrop(insertOrReplaceBlocks); 43373 return event => { 43374 const files = (0,external_wp_dom_namespaceObject.getFilesFromDataTransfer)(event.dataTransfer); 43375 const html = event.dataTransfer.getData('text/html'); 43376 43377 /** 43378 * From Windows Chrome 96, the `event.dataTransfer` returns both file object and HTML. 43379 * The order of the checks is important to recognise the HTML drop. 43380 */ 43381 if (html) { 43382 _onHTMLDrop(html); 43383 } else if (files.length) { 43384 _onFilesDrop(files); 43385 } else { 43386 _onDrop(event); 43387 } 43388 }; 43389 } 43390 43391 ;// ./node_modules/@wordpress/block-editor/build-module/utils/math.js 43392 /** 43393 * A string representing the name of an edge. 43394 * 43395 * @typedef {'top'|'right'|'bottom'|'left'} WPEdgeName 43396 */ 43397 43398 /** 43399 * @typedef {Object} WPPoint 43400 * @property {number} x The horizontal position. 43401 * @property {number} y The vertical position. 43402 */ 43403 43404 /** 43405 * Given a point, a DOMRect and the name of an edge, returns the distance to 43406 * that edge of the rect. 43407 * 43408 * This function works for edges that are horizontal or vertical (e.g. not 43409 * rotated), the following terms are used so that the function works in both 43410 * orientations: 43411 * 43412 * - Forward, meaning the axis running horizontally when an edge is vertical 43413 * and vertically when an edge is horizontal. 43414 * - Lateral, meaning the axis running vertically when an edge is vertical 43415 * and horizontally when an edge is horizontal. 43416 * 43417 * @param {WPPoint} point The point to measure distance from. 43418 * @param {DOMRect} rect A DOM Rect containing edge positions. 43419 * @param {WPEdgeName} edge The edge to measure to. 43420 */ 43421 function getDistanceFromPointToEdge(point, rect, edge) { 43422 const isHorizontal = edge === 'top' || edge === 'bottom'; 43423 const { 43424 x, 43425 y 43426 } = point; 43427 const pointLateralPosition = isHorizontal ? x : y; 43428 const pointForwardPosition = isHorizontal ? y : x; 43429 const edgeStart = isHorizontal ? rect.left : rect.top; 43430 const edgeEnd = isHorizontal ? rect.right : rect.bottom; 43431 const edgeForwardPosition = rect[edge]; 43432 43433 // Measure the straight line distance to the edge of the rect, when the 43434 // point is adjacent to the edge. 43435 // Else, if the point is positioned diagonally to the edge of the rect, 43436 // measure diagonally to the nearest corner that the edge meets. 43437 let edgeLateralPosition; 43438 if (pointLateralPosition >= edgeStart && pointLateralPosition <= edgeEnd) { 43439 edgeLateralPosition = pointLateralPosition; 43440 } else if (pointLateralPosition < edgeEnd) { 43441 edgeLateralPosition = edgeStart; 43442 } else { 43443 edgeLateralPosition = edgeEnd; 43444 } 43445 return Math.sqrt((pointLateralPosition - edgeLateralPosition) ** 2 + (pointForwardPosition - edgeForwardPosition) ** 2); 43446 } 43447 43448 /** 43449 * Given a point, a DOMRect and a list of allowed edges returns the name of and 43450 * distance to the nearest edge. 43451 * 43452 * @param {WPPoint} point The point to measure distance from. 43453 * @param {DOMRect} rect A DOM Rect containing edge positions. 43454 * @param {WPEdgeName[]} allowedEdges A list of the edges included in the 43455 * calculation. Defaults to all edges. 43456 * 43457 * @return {[number, string]} An array where the first value is the distance 43458 * and a second is the edge name. 43459 */ 43460 function getDistanceToNearestEdge(point, rect, allowedEdges = ['top', 'bottom', 'left', 'right']) { 43461 let candidateDistance; 43462 let candidateEdge; 43463 allowedEdges.forEach(edge => { 43464 const distance = getDistanceFromPointToEdge(point, rect, edge); 43465 if (candidateDistance === undefined || distance < candidateDistance) { 43466 candidateDistance = distance; 43467 candidateEdge = edge; 43468 } 43469 }); 43470 return [candidateDistance, candidateEdge]; 43471 } 43472 43473 /** 43474 * Is the point contained by the rectangle. 43475 * 43476 * @param {WPPoint} point The point. 43477 * @param {DOMRect} rect The rectangle. 43478 * 43479 * @return {boolean} True if the point is contained by the rectangle, false otherwise. 43480 */ 43481 function isPointContainedByRect(point, rect) { 43482 return rect.left <= point.x && rect.right >= point.x && rect.top <= point.y && rect.bottom >= point.y; 43483 } 43484 43485 /** 43486 * Is the point within the top and bottom boundaries of the rectangle. 43487 * 43488 * @param {WPPoint} point The point. 43489 * @param {DOMRect} rect The rectangle. 43490 * 43491 * @return {boolean} True if the point is within top and bottom of rectangle, false otherwise. 43492 */ 43493 function isPointWithinTopAndBottomBoundariesOfRect(point, rect) { 43494 return rect.top <= point.y && rect.bottom >= point.y; 43495 } 43496 43497 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-block-drop-zone/index.js 43498 /** 43499 * WordPress dependencies 43500 */ 43501 43502 43503 43504 43505 43506 43507 /** 43508 * Internal dependencies 43509 */ 43510 43511 43512 43513 43514 const THRESHOLD_DISTANCE = 30; 43515 const MINIMUM_HEIGHT_FOR_THRESHOLD = 120; 43516 const MINIMUM_WIDTH_FOR_THRESHOLD = 120; 43517 43518 /** @typedef {import('../../utils/math').WPPoint} WPPoint */ 43519 /** @typedef {import('../use-on-block-drop/types').WPDropOperation} WPDropOperation */ 43520 43521 /** 43522 * The orientation of a block list. 43523 * 43524 * @typedef {'horizontal'|'vertical'|undefined} WPBlockListOrientation 43525 */ 43526 43527 /** 43528 * The insert position when dropping a block. 43529 * 43530 * @typedef {'before'|'after'} WPInsertPosition 43531 */ 43532 43533 /** 43534 * @typedef {Object} WPBlockData 43535 * @property {boolean} isUnmodifiedDefaultBlock Is the block unmodified default block. 43536 * @property {() => DOMRect} getBoundingClientRect Get the bounding client rect of the block. 43537 * @property {number} blockIndex The index of the block. 43538 */ 43539 43540 /** 43541 * Get the drop target position from a given drop point and the orientation. 43542 * 43543 * @param {WPBlockData[]} blocksData The block data list. 43544 * @param {WPPoint} position The position of the item being dragged. 43545 * @param {WPBlockListOrientation} orientation The orientation of the block list. 43546 * @param {Object} options Additional options. 43547 * @return {[number, WPDropOperation]} The drop target position. 43548 */ 43549 function getDropTargetPosition(blocksData, position, orientation = 'vertical', options = {}) { 43550 const allowedEdges = orientation === 'horizontal' ? ['left', 'right'] : ['top', 'bottom']; 43551 let nearestIndex = 0; 43552 let insertPosition = 'before'; 43553 let minDistance = Infinity; 43554 let targetBlockIndex = null; 43555 let nearestSide = 'right'; 43556 const { 43557 dropZoneElement, 43558 parentBlockOrientation, 43559 rootBlockIndex = 0 43560 } = options; 43561 43562 // Allow before/after when dragging over the top/bottom edges of the drop zone. 43563 if (dropZoneElement && parentBlockOrientation !== 'horizontal') { 43564 const rect = dropZoneElement.getBoundingClientRect(); 43565 const [distance, edge] = getDistanceToNearestEdge(position, rect, ['top', 'bottom']); 43566 43567 // If dragging over the top or bottom of the drop zone, insert the block 43568 // before or after the parent block. This only applies to blocks that use 43569 // a drop zone element, typically container blocks such as Group or Cover. 43570 if (rect.height > MINIMUM_HEIGHT_FOR_THRESHOLD && distance < THRESHOLD_DISTANCE) { 43571 if (edge === 'top') { 43572 return [rootBlockIndex, 'before']; 43573 } 43574 if (edge === 'bottom') { 43575 return [rootBlockIndex + 1, 'after']; 43576 } 43577 } 43578 } 43579 const isRightToLeft = (0,external_wp_i18n_namespaceObject.isRTL)(); 43580 43581 // Allow before/after when dragging over the left/right edges of the drop zone. 43582 if (dropZoneElement && parentBlockOrientation === 'horizontal') { 43583 const rect = dropZoneElement.getBoundingClientRect(); 43584 const [distance, edge] = getDistanceToNearestEdge(position, rect, ['left', 'right']); 43585 43586 // If dragging over the left or right of the drop zone, insert the block 43587 // before or after the parent block. This only applies to blocks that use 43588 // a drop zone element, typically container blocks such as Group. 43589 if (rect.width > MINIMUM_WIDTH_FOR_THRESHOLD && distance < THRESHOLD_DISTANCE) { 43590 if (isRightToLeft && edge === 'right' || !isRightToLeft && edge === 'left') { 43591 return [rootBlockIndex, 'before']; 43592 } 43593 if (isRightToLeft && edge === 'left' || !isRightToLeft && edge === 'right') { 43594 return [rootBlockIndex + 1, 'after']; 43595 } 43596 } 43597 } 43598 blocksData.forEach(({ 43599 isUnmodifiedDefaultBlock, 43600 getBoundingClientRect, 43601 blockIndex, 43602 blockOrientation 43603 }) => { 43604 const rect = getBoundingClientRect(); 43605 let [distance, edge] = getDistanceToNearestEdge(position, rect, allowedEdges); 43606 // If the the point is close to a side, prioritize that side. 43607 const [sideDistance, sideEdge] = getDistanceToNearestEdge(position, rect, ['left', 'right']); 43608 const isPointInsideRect = isPointContainedByRect(position, rect); 43609 43610 // Prioritize the element if the point is inside of an unmodified default block. 43611 if (isUnmodifiedDefaultBlock && isPointInsideRect) { 43612 distance = 0; 43613 } else if (orientation === 'vertical' && blockOrientation !== 'horizontal' && (isPointInsideRect && sideDistance < THRESHOLD_DISTANCE || !isPointInsideRect && isPointWithinTopAndBottomBoundariesOfRect(position, rect))) { 43614 /** 43615 * This condition should only apply when the layout is vertical (otherwise there's 43616 * no need to create a Row) and dropzones should only activate when the block is 43617 * either within and close to the sides of the target block or on its outer sides. 43618 */ 43619 targetBlockIndex = blockIndex; 43620 nearestSide = sideEdge; 43621 } 43622 if (distance < minDistance) { 43623 // Where the dropped block will be inserted on the nearest block. 43624 insertPosition = edge === 'bottom' || !isRightToLeft && edge === 'right' || isRightToLeft && edge === 'left' ? 'after' : 'before'; 43625 43626 // Update the currently known best candidate. 43627 minDistance = distance; 43628 nearestIndex = blockIndex; 43629 } 43630 }); 43631 const adjacentIndex = nearestIndex + (insertPosition === 'after' ? 1 : -1); 43632 const isNearestBlockUnmodifiedDefaultBlock = !!blocksData[nearestIndex]?.isUnmodifiedDefaultBlock; 43633 const isAdjacentBlockUnmodifiedDefaultBlock = !!blocksData[adjacentIndex]?.isUnmodifiedDefaultBlock; 43634 43635 // If the target index is set then group with the block at that index. 43636 if (targetBlockIndex !== null) { 43637 return [targetBlockIndex, 'group', nearestSide]; 43638 } 43639 // If both blocks are not unmodified default blocks then just insert between them. 43640 if (!isNearestBlockUnmodifiedDefaultBlock && !isAdjacentBlockUnmodifiedDefaultBlock) { 43641 // If the user is dropping to the trailing edge of the block 43642 // add 1 to the index to represent dragging after. 43643 const insertionIndex = insertPosition === 'after' ? nearestIndex + 1 : nearestIndex; 43644 return [insertionIndex, 'insert']; 43645 } 43646 43647 // Otherwise, replace the nearest unmodified default block. 43648 return [isNearestBlockUnmodifiedDefaultBlock ? nearestIndex : adjacentIndex, 'replace']; 43649 } 43650 43651 /** 43652 * Check if the dragged blocks can be dropped on the target. 43653 * @param {Function} getBlockType 43654 * @param {Object[]} allowedBlocks 43655 * @param {string[]} draggedBlockNames 43656 * @param {string} targetBlockName 43657 * @return {boolean} Whether the dragged blocks can be dropped on the target. 43658 */ 43659 function isDropTargetValid(getBlockType, allowedBlocks, draggedBlockNames, targetBlockName) { 43660 // At root level allowedBlocks is undefined and all blocks are allowed. 43661 // Otherwise, check if all dragged blocks are allowed. 43662 let areBlocksAllowed = true; 43663 if (allowedBlocks) { 43664 const allowedBlockNames = allowedBlocks?.map(({ 43665 name 43666 }) => name); 43667 areBlocksAllowed = draggedBlockNames.every(name => allowedBlockNames?.includes(name)); 43668 } 43669 43670 // Work out if dragged blocks have an allowed parent and if so 43671 // check target block matches the allowed parent. 43672 const draggedBlockTypes = draggedBlockNames.map(name => getBlockType(name)); 43673 const targetMatchesDraggedBlockParents = draggedBlockTypes.every(block => { 43674 const [allowedParentName] = block?.parent || []; 43675 if (!allowedParentName) { 43676 return true; 43677 } 43678 return allowedParentName === targetBlockName; 43679 }); 43680 return areBlocksAllowed && targetMatchesDraggedBlockParents; 43681 } 43682 43683 /** 43684 * Checks if the given element is an insertion point. 43685 * 43686 * @param {EventTarget|null} targetToCheck - The element to check. 43687 * @param {Document} ownerDocument - The owner document of the element. 43688 * @return {boolean} True if the element is a insertion point, false otherwise. 43689 */ 43690 function isInsertionPoint(targetToCheck, ownerDocument) { 43691 const { 43692 defaultView 43693 } = ownerDocument; 43694 return !!(defaultView && targetToCheck instanceof defaultView.HTMLElement && targetToCheck.closest('[data-is-insertion-point]')); 43695 } 43696 43697 /** 43698 * @typedef {Object} WPBlockDropZoneConfig 43699 * @property {?HTMLElement} dropZoneElement Optional element to be used as the drop zone. 43700 * @property {string} rootClientId The root client id for the block list. 43701 */ 43702 43703 /** 43704 * A React hook that can be used to make a block list handle drag and drop. 43705 * 43706 * @param {WPBlockDropZoneConfig} dropZoneConfig configuration data for the drop zone. 43707 */ 43708 function useBlockDropZone({ 43709 dropZoneElement, 43710 // An undefined value represents a top-level block. Default to an empty 43711 // string for this so that `targetRootClientId` can be easily compared to 43712 // values returned by the `getRootBlockClientId` selector, which also uses 43713 // an empty string to represent top-level blocks. 43714 rootClientId: targetRootClientId = '', 43715 parentClientId: parentBlockClientId = '', 43716 isDisabled = false 43717 } = {}) { 43718 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 43719 const [dropTarget, setDropTarget] = (0,external_wp_element_namespaceObject.useState)({ 43720 index: null, 43721 operation: 'insert' 43722 }); 43723 const { 43724 getBlockType, 43725 getBlockVariations, 43726 getGroupingBlockName 43727 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 43728 const { 43729 canInsertBlockType, 43730 getBlockListSettings, 43731 getBlocks, 43732 getBlockIndex, 43733 getDraggedBlockClientIds, 43734 getBlockNamesByClientId, 43735 getAllowedBlocks, 43736 isDragging, 43737 isGroupable, 43738 isZoomOut, 43739 getSectionRootClientId, 43740 getBlockParents 43741 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 43742 const { 43743 showInsertionPoint, 43744 hideInsertionPoint, 43745 startDragging, 43746 stopDragging 43747 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 43748 const onBlockDrop = useOnBlockDrop(dropTarget.operation === 'before' || dropTarget.operation === 'after' ? parentBlockClientId : targetRootClientId, dropTarget.index, { 43749 operation: dropTarget.operation, 43750 nearestSide: dropTarget.nearestSide 43751 }); 43752 const throttled = (0,external_wp_compose_namespaceObject.useThrottle)((0,external_wp_element_namespaceObject.useCallback)((event, ownerDocument) => { 43753 if (!isDragging()) { 43754 // When dragging from the desktop, no drag start event is fired. 43755 // So, ensure that the drag state is set when the user drags over a drop zone. 43756 startDragging(); 43757 } 43758 const draggedBlockClientIds = getDraggedBlockClientIds(); 43759 const targetParents = [targetRootClientId, ...getBlockParents(targetRootClientId, true)]; 43760 43761 // Check if the target is within any of the dragged blocks. 43762 const isTargetWithinDraggedBlocks = draggedBlockClientIds.some(clientId => targetParents.includes(clientId)); 43763 if (isTargetWithinDraggedBlocks) { 43764 return; 43765 } 43766 const allowedBlocks = getAllowedBlocks(targetRootClientId); 43767 const targetBlockName = getBlockNamesByClientId([targetRootClientId])[0]; 43768 const draggedBlockNames = getBlockNamesByClientId(draggedBlockClientIds); 43769 const isBlockDroppingAllowed = isDropTargetValid(getBlockType, allowedBlocks, draggedBlockNames, targetBlockName); 43770 if (!isBlockDroppingAllowed) { 43771 return; 43772 } 43773 const sectionRootClientId = getSectionRootClientId(); 43774 43775 // In Zoom Out mode, if the target is not the section root provided by settings then 43776 // do not allow dropping as the drop target is not within the root (that which is 43777 // treated as "the content" by Zoom Out Mode). 43778 if (isZoomOut() && sectionRootClientId !== targetRootClientId) { 43779 return; 43780 } 43781 const blocks = getBlocks(targetRootClientId); 43782 43783 // The block list is empty, don't show the insertion point but still allow dropping. 43784 if (blocks.length === 0) { 43785 registry.batch(() => { 43786 setDropTarget({ 43787 index: 0, 43788 operation: 'insert' 43789 }); 43790 showInsertionPoint(targetRootClientId, 0, { 43791 operation: 'insert' 43792 }); 43793 }); 43794 return; 43795 } 43796 const blocksData = blocks.map(block => { 43797 const clientId = block.clientId; 43798 return { 43799 isUnmodifiedDefaultBlock: (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(block), 43800 getBoundingClientRect: () => ownerDocument.getElementById(`block-$clientId}`).getBoundingClientRect(), 43801 blockIndex: getBlockIndex(clientId), 43802 blockOrientation: getBlockListSettings(clientId)?.orientation 43803 }; 43804 }); 43805 const dropTargetPosition = getDropTargetPosition(blocksData, { 43806 x: event.clientX, 43807 y: event.clientY 43808 }, getBlockListSettings(targetRootClientId)?.orientation, { 43809 dropZoneElement, 43810 parentBlockClientId, 43811 parentBlockOrientation: parentBlockClientId ? getBlockListSettings(parentBlockClientId)?.orientation : undefined, 43812 rootBlockIndex: getBlockIndex(targetRootClientId) 43813 }); 43814 const [targetIndex, operation, nearestSide] = dropTargetPosition; 43815 const isTargetIndexEmptyDefaultBlock = blocksData[targetIndex]?.isUnmodifiedDefaultBlock; 43816 if (isZoomOut() && !isTargetIndexEmptyDefaultBlock && operation !== 'insert') { 43817 return; 43818 } 43819 if (operation === 'group') { 43820 const targetBlock = blocks[targetIndex]; 43821 const areAllImages = [targetBlock.name, ...draggedBlockNames].every(name => name === 'core/image'); 43822 const canInsertGalleryBlock = canInsertBlockType('core/gallery', targetRootClientId); 43823 const areGroupableBlocks = isGroupable([targetBlock.clientId, getDraggedBlockClientIds()]); 43824 const groupBlockVariations = getBlockVariations(getGroupingBlockName(), 'block'); 43825 const canInsertRow = groupBlockVariations && groupBlockVariations.find(({ 43826 name 43827 }) => name === 'group-row'); 43828 43829 // If the dragged blocks and the target block are all images, 43830 // check if it is creatable either a Row variation or a Gallery block. 43831 if (areAllImages && !canInsertGalleryBlock && (!areGroupableBlocks || !canInsertRow)) { 43832 return; 43833 } 43834 // If the dragged blocks and the target block are not all images, 43835 // check if it is creatable a Row variation. 43836 if (!areAllImages && (!areGroupableBlocks || !canInsertRow)) { 43837 return; 43838 } 43839 } 43840 registry.batch(() => { 43841 setDropTarget({ 43842 index: targetIndex, 43843 operation, 43844 nearestSide 43845 }); 43846 const insertionPointClientId = ['before', 'after'].includes(operation) ? parentBlockClientId : targetRootClientId; 43847 showInsertionPoint(insertionPointClientId, targetIndex, { 43848 operation, 43849 nearestSide 43850 }); 43851 }); 43852 }, [isDragging, getAllowedBlocks, targetRootClientId, getBlockNamesByClientId, getDraggedBlockClientIds, getBlockType, getSectionRootClientId, isZoomOut, getBlocks, getBlockListSettings, dropZoneElement, parentBlockClientId, getBlockIndex, registry, startDragging, showInsertionPoint, canInsertBlockType, isGroupable, getBlockVariations, getGroupingBlockName]), 200); 43853 return (0,external_wp_compose_namespaceObject.__experimentalUseDropZone)({ 43854 dropZoneElement, 43855 isDisabled, 43856 onDrop: onBlockDrop, 43857 onDragOver(event) { 43858 // `currentTarget` is only available while the event is being 43859 // handled, so get it now and pass it to the thottled function. 43860 // https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget 43861 throttled(event, event.currentTarget.ownerDocument); 43862 }, 43863 onDragLeave(event) { 43864 const { 43865 ownerDocument 43866 } = event.currentTarget; 43867 43868 // If the drag event is leaving the drop zone and entering an insertion point, 43869 // do not hide the insertion point as it is conceptually within the dropzone. 43870 if (isInsertionPoint(event.relatedTarget, ownerDocument) || isInsertionPoint(event.target, ownerDocument)) { 43871 return; 43872 } 43873 throttled.cancel(); 43874 hideInsertionPoint(); 43875 }, 43876 onDragEnd() { 43877 throttled.cancel(); 43878 stopDragging(); 43879 hideInsertionPoint(); 43880 } 43881 }); 43882 } 43883 43884 ;// ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/index.js 43885 /** 43886 * External dependencies 43887 */ 43888 43889 43890 /** 43891 * WordPress dependencies 43892 */ 43893 43894 43895 43896 43897 43898 /** 43899 * Internal dependencies 43900 */ 43901 43902 43903 43904 43905 43906 43907 43908 43909 43910 43911 43912 43913 43914 const EMPTY_OBJECT = {}; 43915 function BlockContext({ 43916 children, 43917 clientId 43918 }) { 43919 const context = useBlockContext(clientId); 43920 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockContextProvider, { 43921 value: context, 43922 children: children 43923 }); 43924 } 43925 const BlockListItemsMemo = (0,external_wp_element_namespaceObject.memo)(BlockListItems); 43926 43927 /** 43928 * InnerBlocks is a component which allows a single block to have multiple blocks 43929 * as children. The UncontrolledInnerBlocks component is used whenever the inner 43930 * blocks are not controlled by another entity. In other words, it is normally 43931 * used for inner blocks in the post editor 43932 * 43933 * @param {Object} props The component props. 43934 */ 43935 function UncontrolledInnerBlocks(props) { 43936 const { 43937 clientId, 43938 allowedBlocks, 43939 prioritizedInserterBlocks, 43940 defaultBlock, 43941 directInsert, 43942 __experimentalDefaultBlock, 43943 __experimentalDirectInsert, 43944 template, 43945 templateLock, 43946 wrapperRef, 43947 templateInsertUpdatesSelection, 43948 __experimentalCaptureToolbars: captureToolbars, 43949 __experimentalAppenderTagName, 43950 renderAppender, 43951 orientation, 43952 placeholder, 43953 layout, 43954 name, 43955 blockType, 43956 parentLock, 43957 defaultLayout 43958 } = props; 43959 useNestedSettingsUpdate(clientId, parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout); 43960 useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection); 43961 const defaultLayoutBlockSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'layout') || (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, '__experimentalLayout') || EMPTY_OBJECT; 43962 const { 43963 allowSizingOnChildren = false 43964 } = defaultLayoutBlockSupport; 43965 const usedLayout = layout || defaultLayoutBlockSupport; 43966 const memoedLayout = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 43967 // Default layout will know about any content/wide size defined by the theme. 43968 ...defaultLayout, 43969 ...usedLayout, 43970 ...(allowSizingOnChildren && { 43971 allowSizingOnChildren: true 43972 }) 43973 }), [defaultLayout, usedLayout, allowSizingOnChildren]); 43974 43975 // For controlled inner blocks, we don't want a change in blocks to 43976 // re-render the blocks list. 43977 const items = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListItemsMemo, { 43978 rootClientId: clientId, 43979 renderAppender: renderAppender, 43980 __experimentalAppenderTagName: __experimentalAppenderTagName, 43981 layout: memoedLayout, 43982 wrapperRef: wrapperRef, 43983 placeholder: placeholder 43984 }); 43985 if (!blockType?.providesContext || Object.keys(blockType.providesContext).length === 0) { 43986 return items; 43987 } 43988 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockContext, { 43989 clientId: clientId, 43990 children: items 43991 }); 43992 } 43993 43994 /** 43995 * The controlled inner blocks component wraps the uncontrolled inner blocks 43996 * component with the blockSync hook. This keeps the innerBlocks of the block in 43997 * the block-editor store in sync with the blocks of the controlling entity. An 43998 * example of an inner block controller is a template part block, which provides 43999 * its own blocks from the template part entity data source. 44000 * 44001 * @param {Object} props The component props. 44002 */ 44003 function ControlledInnerBlocks(props) { 44004 useBlockSync(props); 44005 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(UncontrolledInnerBlocks, { 44006 ...props 44007 }); 44008 } 44009 const ForwardedInnerBlocks = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 44010 const innerBlocksProps = useInnerBlocksProps({ 44011 ref 44012 }, props); 44013 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 44014 className: "block-editor-inner-blocks", 44015 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 44016 ...innerBlocksProps 44017 }) 44018 }); 44019 }); 44020 44021 /** 44022 * This hook is used to lightly mark an element as an inner blocks wrapper 44023 * element. Call this hook and pass the returned props to the element to mark as 44024 * an inner blocks wrapper, automatically rendering inner blocks as children. If 44025 * you define a ref for the element, it is important to pass the ref to this 44026 * hook, which the hook in turn will pass to the component through the props it 44027 * returns. Optionally, you can also pass any other props through this hook, and 44028 * they will be merged and returned. 44029 * 44030 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md 44031 * 44032 * @param {Object} props Optional. Props to pass to the element. Must contain 44033 * the ref if one is defined. 44034 * @param {Object} options Optional. Inner blocks options. 44035 */ 44036 function useInnerBlocksProps(props = {}, options = {}) { 44037 const { 44038 __unstableDisableLayoutClassNames, 44039 __unstableDisableDropZone, 44040 dropZoneElement 44041 } = options; 44042 const { 44043 clientId, 44044 layout = null, 44045 __unstableLayoutClassNames: layoutClassNames = '' 44046 } = useBlockEditContext(); 44047 const selected = (0,external_wp_data_namespaceObject.useSelect)(select => { 44048 const { 44049 getBlockName, 44050 isZoomOut, 44051 getTemplateLock, 44052 getBlockRootClientId, 44053 getBlockEditingMode, 44054 getBlockSettings, 44055 getSectionRootClientId 44056 } = unlock(select(store)); 44057 if (!clientId) { 44058 const sectionRootClientId = getSectionRootClientId(); 44059 // Disable the root drop zone when zoomed out and the section root client id 44060 // is not the root block list (represented by an empty string). 44061 // This avoids drag handling bugs caused by having two block lists acting as 44062 // drop zones - the actual 'root' block list and the section root. 44063 return { 44064 isDropZoneDisabled: isZoomOut() && sectionRootClientId !== '' 44065 }; 44066 } 44067 const { 44068 hasBlockSupport, 44069 getBlockType 44070 } = select(external_wp_blocks_namespaceObject.store); 44071 const blockName = getBlockName(clientId); 44072 const blockEditingMode = getBlockEditingMode(clientId); 44073 const parentClientId = getBlockRootClientId(clientId); 44074 const [defaultLayout] = getBlockSettings(clientId, 'layout'); 44075 let _isDropZoneDisabled = blockEditingMode === 'disabled'; 44076 if (isZoomOut()) { 44077 // In zoom out mode, we want to disable the drop zone for the sections. 44078 // The inner blocks belonging to the section drop zone is 44079 // already disabled by the blocks themselves being disabled. 44080 const sectionRootClientId = getSectionRootClientId(); 44081 _isDropZoneDisabled = clientId !== sectionRootClientId; 44082 } 44083 return { 44084 __experimentalCaptureToolbars: hasBlockSupport(blockName, '__experimentalExposeControlsToChildren', false), 44085 name: blockName, 44086 blockType: getBlockType(blockName), 44087 parentLock: getTemplateLock(parentClientId), 44088 parentClientId, 44089 isDropZoneDisabled: _isDropZoneDisabled, 44090 defaultLayout 44091 }; 44092 }, [clientId]); 44093 const { 44094 __experimentalCaptureToolbars, 44095 name, 44096 blockType, 44097 parentLock, 44098 parentClientId, 44099 isDropZoneDisabled, 44100 defaultLayout 44101 } = selected; 44102 const blockDropZoneRef = useBlockDropZone({ 44103 dropZoneElement, 44104 rootClientId: clientId, 44105 parentClientId 44106 }); 44107 const ref = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, __unstableDisableDropZone || isDropZoneDisabled || layout?.isManualPlacement && window.__experimentalEnableGridInteractivity ? null : blockDropZoneRef]); 44108 const innerBlocksProps = { 44109 __experimentalCaptureToolbars, 44110 layout, 44111 name, 44112 blockType, 44113 parentLock, 44114 defaultLayout, 44115 ...options 44116 }; 44117 const InnerBlocks = innerBlocksProps.value && innerBlocksProps.onChange ? ControlledInnerBlocks : UncontrolledInnerBlocks; 44118 return { 44119 ...props, 44120 ref, 44121 className: dist_clsx(props.className, 'block-editor-block-list__layout', __unstableDisableLayoutClassNames ? '' : layoutClassNames), 44122 children: clientId ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InnerBlocks, { 44123 ...innerBlocksProps, 44124 clientId: clientId 44125 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListItems, { 44126 ...options 44127 }) 44128 }; 44129 } 44130 useInnerBlocksProps.save = external_wp_blocks_namespaceObject.__unstableGetInnerBlocksProps; 44131 44132 // Expose default appender placeholders as components. 44133 ForwardedInnerBlocks.DefaultBlockAppender = default_block_appender_DefaultBlockAppender; 44134 ForwardedInnerBlocks.ButtonBlockAppender = ButtonBlockAppender; 44135 ForwardedInnerBlocks.Content = () => useInnerBlocksProps.save().children; 44136 44137 /** 44138 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md 44139 */ 44140 /* harmony default export */ const inner_blocks = (ForwardedInnerBlocks); 44141 44142 ;// ./node_modules/@wordpress/block-editor/build-module/components/observe-typing/index.js 44143 /** 44144 * WordPress dependencies 44145 */ 44146 44147 44148 44149 44150 44151 /** 44152 * Internal dependencies 44153 */ 44154 44155 44156 /** 44157 * Set of key codes upon which typing is to be initiated on a keydown event. 44158 * 44159 * @type {Set<number>} 44160 */ 44161 44162 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]); 44163 44164 /** 44165 * Returns true if a given keydown event can be inferred as intent to start 44166 * typing, or false otherwise. A keydown is considered eligible if it is a 44167 * text navigation without shift active. 44168 * 44169 * @param {KeyboardEvent} event Keydown event to test. 44170 * 44171 * @return {boolean} Whether event is eligible to start typing. 44172 */ 44173 function isKeyDownEligibleForStartTyping(event) { 44174 const { 44175 keyCode, 44176 shiftKey 44177 } = event; 44178 return !shiftKey && KEY_DOWN_ELIGIBLE_KEY_CODES.has(keyCode); 44179 } 44180 44181 /** 44182 * Removes the `isTyping` flag when the mouse moves in the document of the given 44183 * element. 44184 */ 44185 function useMouseMoveTypingReset() { 44186 const isTyping = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).isTyping(), []); 44187 const { 44188 stopTyping 44189 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 44190 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 44191 if (!isTyping) { 44192 return; 44193 } 44194 const { 44195 ownerDocument 44196 } = node; 44197 let lastClientX; 44198 let lastClientY; 44199 44200 /** 44201 * On mouse move, unset typing flag if user has moved cursor. 44202 * 44203 * @param {MouseEvent} event Mousemove event. 44204 */ 44205 function stopTypingOnMouseMove(event) { 44206 const { 44207 clientX, 44208 clientY 44209 } = event; 44210 44211 // We need to check that the mouse really moved because Safari 44212 // triggers mousemove events when shift or ctrl are pressed. 44213 if (lastClientX && lastClientY && (lastClientX !== clientX || lastClientY !== clientY)) { 44214 stopTyping(); 44215 } 44216 lastClientX = clientX; 44217 lastClientY = clientY; 44218 } 44219 ownerDocument.addEventListener('mousemove', stopTypingOnMouseMove); 44220 return () => { 44221 ownerDocument.removeEventListener('mousemove', stopTypingOnMouseMove); 44222 }; 44223 }, [isTyping, stopTyping]); 44224 } 44225 44226 /** 44227 * Sets and removes the `isTyping` flag based on user actions: 44228 * 44229 * - Sets the flag if the user types within the given element. 44230 * - Removes the flag when the user selects some text, focuses a non-text 44231 * field, presses ESC or TAB, or moves the mouse in the document. 44232 */ 44233 function useTypingObserver() { 44234 const { 44235 isTyping 44236 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44237 const { 44238 isTyping: _isTyping 44239 } = select(store); 44240 return { 44241 isTyping: _isTyping() 44242 }; 44243 }, []); 44244 const { 44245 startTyping, 44246 stopTyping 44247 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 44248 const ref1 = useMouseMoveTypingReset(); 44249 const ref2 = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 44250 const { 44251 ownerDocument 44252 } = node; 44253 const { 44254 defaultView 44255 } = ownerDocument; 44256 const selection = defaultView.getSelection(); 44257 44258 // Listeners to stop typing should only be added when typing. 44259 // Listeners to start typing should only be added when not typing. 44260 if (isTyping) { 44261 let timerId; 44262 44263 /** 44264 * Stops typing when focus transitions to a non-text field element. 44265 * 44266 * @param {FocusEvent} event Focus event. 44267 */ 44268 function stopTypingOnNonTextField(event) { 44269 const { 44270 target 44271 } = event; 44272 44273 // Since focus to a non-text field via arrow key will trigger 44274 // before the keydown event, wait until after current stack 44275 // before evaluating whether typing is to be stopped. Otherwise, 44276 // typing will re-start. 44277 timerId = defaultView.setTimeout(() => { 44278 if (!(0,external_wp_dom_namespaceObject.isTextField)(target)) { 44279 stopTyping(); 44280 } 44281 }); 44282 } 44283 44284 /** 44285 * Unsets typing flag if user presses Escape while typing flag is 44286 * active. 44287 * 44288 * @param {KeyboardEvent} event Keypress or keydown event to 44289 * interpret. 44290 */ 44291 function stopTypingOnEscapeKey(event) { 44292 const { 44293 keyCode 44294 } = event; 44295 if (keyCode === external_wp_keycodes_namespaceObject.ESCAPE || keyCode === external_wp_keycodes_namespaceObject.TAB) { 44296 stopTyping(); 44297 } 44298 } 44299 44300 /** 44301 * On selection change, unset typing flag if user has made an 44302 * uncollapsed (shift) selection. 44303 */ 44304 function stopTypingOnSelectionUncollapse() { 44305 if (!selection.isCollapsed) { 44306 stopTyping(); 44307 } 44308 } 44309 node.addEventListener('focus', stopTypingOnNonTextField); 44310 node.addEventListener('keydown', stopTypingOnEscapeKey); 44311 ownerDocument.addEventListener('selectionchange', stopTypingOnSelectionUncollapse); 44312 return () => { 44313 defaultView.clearTimeout(timerId); 44314 node.removeEventListener('focus', stopTypingOnNonTextField); 44315 node.removeEventListener('keydown', stopTypingOnEscapeKey); 44316 ownerDocument.removeEventListener('selectionchange', stopTypingOnSelectionUncollapse); 44317 }; 44318 } 44319 44320 /** 44321 * Handles a keypress or keydown event to infer intention to start 44322 * typing. 44323 * 44324 * @param {KeyboardEvent} event Keypress or keydown event to interpret. 44325 */ 44326 function startTypingInTextField(event) { 44327 const { 44328 type, 44329 target 44330 } = event; 44331 44332 // Abort early if already typing, or key press is incurred outside a 44333 // text field (e.g. arrow-ing through toolbar buttons). 44334 // Ignore typing if outside the current DOM container 44335 if (!(0,external_wp_dom_namespaceObject.isTextField)(target) || !node.contains(target)) { 44336 return; 44337 } 44338 44339 // Special-case keydown because certain keys do not emit a keypress 44340 // event. Conversely avoid keydown as the canonical event since 44341 // there are many keydown which are explicitly not targeted for 44342 // typing. 44343 if (type === 'keydown' && !isKeyDownEligibleForStartTyping(event)) { 44344 return; 44345 } 44346 startTyping(); 44347 } 44348 node.addEventListener('keypress', startTypingInTextField); 44349 node.addEventListener('keydown', startTypingInTextField); 44350 return () => { 44351 node.removeEventListener('keypress', startTypingInTextField); 44352 node.removeEventListener('keydown', startTypingInTextField); 44353 }; 44354 }, [isTyping, startTyping, stopTyping]); 44355 return (0,external_wp_compose_namespaceObject.useMergeRefs)([ref1, ref2]); 44356 } 44357 function ObserveTyping({ 44358 children 44359 }) { 44360 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 44361 ref: useTypingObserver(), 44362 children: children 44363 }); 44364 } 44365 44366 /** 44367 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/observe-typing/README.md 44368 */ 44369 /* harmony default export */ const observe_typing = (ObserveTyping); 44370 44371 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/zoom-out-separator.js 44372 /** 44373 * External dependencies 44374 */ 44375 44376 44377 /** 44378 * WordPress dependencies 44379 */ 44380 44381 44382 44383 44384 44385 44386 /** 44387 * Internal dependencies 44388 */ 44389 44390 44391 44392 function ZoomOutSeparator({ 44393 clientId, 44394 rootClientId = '', 44395 position = 'top' 44396 }) { 44397 const [isDraggedOver, setIsDraggedOver] = (0,external_wp_element_namespaceObject.useState)(false); 44398 const { 44399 sectionRootClientId, 44400 sectionClientIds, 44401 insertionPoint, 44402 blockInsertionPointVisible, 44403 blockInsertionPoint, 44404 blocksBeingDragged 44405 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44406 const { 44407 getInsertionPoint, 44408 getBlockOrder, 44409 getSectionRootClientId, 44410 isBlockInsertionPointVisible, 44411 getBlockInsertionPoint, 44412 getDraggedBlockClientIds 44413 } = unlock(select(store)); 44414 const root = getSectionRootClientId(); 44415 const sectionRootClientIds = getBlockOrder(root); 44416 return { 44417 sectionRootClientId: root, 44418 sectionClientIds: sectionRootClientIds, 44419 blockOrder: getBlockOrder(root), 44420 insertionPoint: getInsertionPoint(), 44421 blockInsertionPoint: getBlockInsertionPoint(), 44422 blockInsertionPointVisible: isBlockInsertionPointVisible(), 44423 blocksBeingDragged: getDraggedBlockClientIds() 44424 }; 44425 }, []); 44426 const isReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 44427 if (!clientId) { 44428 return; 44429 } 44430 let isVisible = false; 44431 const isSectionBlock = rootClientId === sectionRootClientId && sectionClientIds && sectionClientIds.includes(clientId); 44432 if (!isSectionBlock) { 44433 return null; 44434 } 44435 const hasTopInsertionPoint = insertionPoint?.index === 0 && clientId === sectionClientIds[insertionPoint.index]; 44436 const hasBottomInsertionPoint = insertionPoint && insertionPoint.hasOwnProperty('index') && clientId === sectionClientIds[insertionPoint.index - 1]; 44437 44438 // We want to show the zoom out separator in either of these conditions: 44439 // 1. If the inserter has an insertion index set 44440 // 2. We are dragging a pattern over an insertion point 44441 if (position === 'top') { 44442 isVisible = hasTopInsertionPoint || blockInsertionPointVisible && blockInsertionPoint.index === 0 && clientId === sectionClientIds[blockInsertionPoint.index]; 44443 } 44444 if (position === 'bottom') { 44445 isVisible = hasBottomInsertionPoint || blockInsertionPointVisible && clientId === sectionClientIds[blockInsertionPoint.index - 1]; 44446 } 44447 const blockBeingDraggedClientId = blocksBeingDragged[0]; 44448 const isCurrentBlockBeingDragged = blocksBeingDragged.includes(clientId); 44449 const blockBeingDraggedIndex = sectionClientIds.indexOf(blockBeingDraggedClientId); 44450 const blockBeingDraggedPreviousSiblingClientId = blockBeingDraggedIndex > 0 ? sectionClientIds[blockBeingDraggedIndex - 1] : null; 44451 const isCurrentBlockPreviousSiblingOfBlockBeingDragged = blockBeingDraggedPreviousSiblingClientId === clientId; 44452 44453 // The separators are visually top/bottom of the block, but in actual fact 44454 // the "top" separator is the "bottom" separator of the previous block. 44455 // Therefore, this logic hides the separator if the current block is being dragged 44456 // or if the current block is the previous sibling of the block being dragged. 44457 if (isCurrentBlockBeingDragged || isCurrentBlockPreviousSiblingOfBlockBeingDragged) { 44458 isVisible = false; 44459 } 44460 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableAnimatePresence, { 44461 children: isVisible && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 44462 initial: { 44463 height: 0 44464 }, 44465 animate: { 44466 // Use a height equal to that of the zoom out frame size. 44467 height: 'calc(1 * var(--wp-block-editor-iframe-zoom-out-frame-size) / var(--wp-block-editor-iframe-zoom-out-scale)' 44468 }, 44469 exit: { 44470 height: 0 44471 }, 44472 transition: { 44473 type: 'tween', 44474 duration: isReducedMotion ? 0 : 0.2, 44475 ease: [0.6, 0, 0.4, 1] 44476 }, 44477 className: dist_clsx('block-editor-block-list__zoom-out-separator', { 44478 'is-dragged-over': isDraggedOver 44479 }), 44480 "data-is-insertion-point": "true", 44481 onDragOver: () => setIsDraggedOver(true), 44482 onDragLeave: () => setIsDraggedOver(false), 44483 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 44484 initial: { 44485 opacity: 0 44486 }, 44487 animate: { 44488 opacity: 1 44489 }, 44490 exit: { 44491 opacity: 0, 44492 transition: { 44493 delay: -0.125 44494 } 44495 }, 44496 transition: { 44497 ease: 'linear', 44498 duration: 0.1, 44499 delay: 0.125 44500 }, 44501 children: (0,external_wp_i18n_namespaceObject.__)('Drop pattern.') 44502 }) 44503 }) 44504 }); 44505 } 44506 44507 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-list/index.js 44508 /** 44509 * External dependencies 44510 */ 44511 44512 44513 /** 44514 * WordPress dependencies 44515 */ 44516 44517 44518 44519 44520 44521 /** 44522 * Internal dependencies 44523 */ 44524 44525 44526 44527 44528 44529 44530 44531 44532 44533 44534 44535 44536 const block_list_IntersectionObserver = (0,external_wp_element_namespaceObject.createContext)(); 44537 const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap(); 44538 function Root({ 44539 className, 44540 ...settings 44541 }) { 44542 const { 44543 isOutlineMode, 44544 isFocusMode, 44545 temporarilyEditingAsBlocks 44546 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44547 const { 44548 getSettings, 44549 getTemporarilyEditingAsBlocks, 44550 isTyping 44551 } = unlock(select(store)); 44552 const { 44553 outlineMode, 44554 focusMode 44555 } = getSettings(); 44556 return { 44557 isOutlineMode: outlineMode && !isTyping(), 44558 isFocusMode: focusMode, 44559 temporarilyEditingAsBlocks: getTemporarilyEditingAsBlocks() 44560 }; 44561 }, []); 44562 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 44563 const { 44564 setBlockVisibility 44565 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 44566 const delayedBlockVisibilityUpdates = (0,external_wp_compose_namespaceObject.useDebounce)((0,external_wp_element_namespaceObject.useCallback)(() => { 44567 const updates = {}; 44568 pendingBlockVisibilityUpdatesPerRegistry.get(registry).forEach(([id, isIntersecting]) => { 44569 updates[id] = isIntersecting; 44570 }); 44571 setBlockVisibility(updates); 44572 }, [registry]), 300, { 44573 trailing: true 44574 }); 44575 const intersectionObserver = (0,external_wp_element_namespaceObject.useMemo)(() => { 44576 const { 44577 IntersectionObserver: Observer 44578 } = window; 44579 if (!Observer) { 44580 return; 44581 } 44582 return new Observer(entries => { 44583 if (!pendingBlockVisibilityUpdatesPerRegistry.get(registry)) { 44584 pendingBlockVisibilityUpdatesPerRegistry.set(registry, []); 44585 } 44586 for (const entry of entries) { 44587 const clientId = entry.target.getAttribute('data-block'); 44588 pendingBlockVisibilityUpdatesPerRegistry.get(registry).push([clientId, entry.isIntersecting]); 44589 } 44590 delayedBlockVisibilityUpdates(); 44591 }); 44592 }, []); 44593 const innerBlocksProps = useInnerBlocksProps({ 44594 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([useBlockSelectionClearer(), useInBetweenInserter(), useTypingObserver()]), 44595 className: dist_clsx('is-root-container', className, { 44596 'is-outline-mode': isOutlineMode, 44597 'is-focus-mode': isFocusMode 44598 }) 44599 }, settings); 44600 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(block_list_IntersectionObserver.Provider, { 44601 value: intersectionObserver, 44602 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 44603 ...innerBlocksProps 44604 }), !!temporarilyEditingAsBlocks && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(StopEditingAsBlocksOnOutsideSelect, { 44605 clientId: temporarilyEditingAsBlocks 44606 })] 44607 }); 44608 } 44609 function StopEditingAsBlocksOnOutsideSelect({ 44610 clientId 44611 }) { 44612 const { 44613 stopEditingAsBlocks 44614 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 44615 const isBlockOrDescendantSelected = (0,external_wp_data_namespaceObject.useSelect)(select => { 44616 const { 44617 isBlockSelected, 44618 hasSelectedInnerBlock 44619 } = select(store); 44620 return isBlockSelected(clientId) || hasSelectedInnerBlock(clientId, true); 44621 }, [clientId]); 44622 (0,external_wp_element_namespaceObject.useEffect)(() => { 44623 if (!isBlockOrDescendantSelected) { 44624 stopEditingAsBlocks(clientId); 44625 } 44626 }, [isBlockOrDescendantSelected, clientId, stopEditingAsBlocks]); 44627 return null; 44628 } 44629 function BlockList(settings) { 44630 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Provider, { 44631 value: DEFAULT_BLOCK_EDIT_CONTEXT, 44632 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Root, { 44633 ...settings 44634 }) 44635 }); 44636 } 44637 const block_list_EMPTY_ARRAY = []; 44638 const block_list_EMPTY_SET = new Set(); 44639 function Items({ 44640 placeholder, 44641 rootClientId, 44642 renderAppender: CustomAppender, 44643 __experimentalAppenderTagName, 44644 layout = defaultLayout 44645 }) { 44646 // Avoid passing CustomAppender to useSelect because it could be a new 44647 // function on every render. 44648 const hasAppender = CustomAppender !== false; 44649 const hasCustomAppender = !!CustomAppender; 44650 const { 44651 order, 44652 isZoomOut, 44653 selectedBlocks, 44654 visibleBlocks, 44655 shouldRenderAppender 44656 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 44657 const { 44658 getSettings, 44659 getBlockOrder, 44660 getSelectedBlockClientIds, 44661 __unstableGetVisibleBlocks, 44662 getTemplateLock, 44663 getBlockEditingMode, 44664 isSectionBlock, 44665 isZoomOut: _isZoomOut, 44666 canInsertBlockType 44667 } = unlock(select(store)); 44668 const _order = getBlockOrder(rootClientId); 44669 if (getSettings().isPreviewMode) { 44670 return { 44671 order: _order, 44672 selectedBlocks: block_list_EMPTY_ARRAY, 44673 visibleBlocks: block_list_EMPTY_SET 44674 }; 44675 } 44676 const selectedBlockClientIds = getSelectedBlockClientIds(); 44677 const selectedBlockClientId = selectedBlockClientIds[0]; 44678 const showRootAppender = !rootClientId && !selectedBlockClientId && (!_order.length || !canInsertBlockType((0,external_wp_blocks_namespaceObject.getDefaultBlockName)(), rootClientId)); 44679 const hasSelectedRoot = !!(rootClientId && selectedBlockClientId && rootClientId === selectedBlockClientId); 44680 return { 44681 order: _order, 44682 selectedBlocks: selectedBlockClientIds, 44683 visibleBlocks: __unstableGetVisibleBlocks(), 44684 isZoomOut: _isZoomOut(), 44685 shouldRenderAppender: !isSectionBlock(rootClientId) && getBlockEditingMode(rootClientId) !== 'disabled' && !getTemplateLock(rootClientId) && hasAppender && !_isZoomOut() && (hasCustomAppender || hasSelectedRoot || showRootAppender) 44686 }; 44687 }, [rootClientId, hasAppender, hasCustomAppender]); 44688 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(LayoutProvider, { 44689 value: layout, 44690 children: [order.map(clientId => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_data_namespaceObject.AsyncModeProvider, { 44691 value: 44692 // Only provide data asynchronously if the block is 44693 // not visible and not selected. 44694 !visibleBlocks.has(clientId) && !selectedBlocks.includes(clientId), 44695 children: [isZoomOut && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ZoomOutSeparator, { 44696 clientId: clientId, 44697 rootClientId: rootClientId, 44698 position: "top" 44699 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block, { 44700 rootClientId: rootClientId, 44701 clientId: clientId 44702 }), isZoomOut && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ZoomOutSeparator, { 44703 clientId: clientId, 44704 rootClientId: rootClientId, 44705 position: "bottom" 44706 })] 44707 }, clientId)), order.length < 1 && placeholder, shouldRenderAppender && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListAppender, { 44708 tagName: __experimentalAppenderTagName, 44709 rootClientId: rootClientId, 44710 CustomAppender: CustomAppender 44711 })] 44712 }); 44713 } 44714 function BlockListItems(props) { 44715 // This component needs to always be synchronous as it's the one changing 44716 // the async mode depending on the block selection. 44717 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_data_namespaceObject.AsyncModeProvider, { 44718 value: false, 44719 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Items, { 44720 ...props 44721 }) 44722 }); 44723 } 44724 44725 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-multi-selection.js 44726 /** 44727 * WordPress dependencies 44728 */ 44729 44730 44731 44732 /** 44733 * Internal dependencies 44734 */ 44735 44736 function selector(select) { 44737 const { 44738 isMultiSelecting, 44739 getMultiSelectedBlockClientIds, 44740 hasMultiSelection, 44741 getSelectedBlockClientId, 44742 getSelectedBlocksInitialCaretPosition, 44743 __unstableIsFullySelected 44744 } = select(store); 44745 return { 44746 isMultiSelecting: isMultiSelecting(), 44747 multiSelectedBlockClientIds: getMultiSelectedBlockClientIds(), 44748 hasMultiSelection: hasMultiSelection(), 44749 selectedBlockClientId: getSelectedBlockClientId(), 44750 initialPosition: getSelectedBlocksInitialCaretPosition(), 44751 isFullSelection: __unstableIsFullySelected() 44752 }; 44753 } 44754 function useMultiSelection() { 44755 const { 44756 initialPosition, 44757 isMultiSelecting, 44758 multiSelectedBlockClientIds, 44759 hasMultiSelection, 44760 selectedBlockClientId, 44761 isFullSelection 44762 } = (0,external_wp_data_namespaceObject.useSelect)(selector, []); 44763 44764 /** 44765 * When the component updates, and there is multi selection, we need to 44766 * select the entire block contents. 44767 */ 44768 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 44769 const { 44770 ownerDocument 44771 } = node; 44772 const { 44773 defaultView 44774 } = ownerDocument; 44775 44776 // Allow initialPosition to bypass focus behavior. This is useful 44777 // for the list view or other areas where we don't want to transfer 44778 // focus to the editor canvas. 44779 if (initialPosition === undefined || initialPosition === null) { 44780 return; 44781 } 44782 if (!hasMultiSelection || isMultiSelecting) { 44783 return; 44784 } 44785 const { 44786 length 44787 } = multiSelectedBlockClientIds; 44788 if (length < 2) { 44789 return; 44790 } 44791 if (!isFullSelection) { 44792 return; 44793 } 44794 44795 // Allow cross contentEditable selection by temporarily making 44796 // all content editable. We can't rely on using the store and 44797 // React because re-rending happens too slowly. We need to be 44798 // able to select across instances immediately. 44799 node.contentEditable = true; 44800 44801 // For some browsers, like Safari, it is important that focus 44802 // happens BEFORE selection removal. 44803 node.focus(); 44804 defaultView.getSelection().removeAllRanges(); 44805 }, [hasMultiSelection, isMultiSelecting, multiSelectedBlockClientIds, selectedBlockClientId, initialPosition, isFullSelection]); 44806 } 44807 44808 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-tab-nav.js 44809 /** 44810 * WordPress dependencies 44811 */ 44812 44813 44814 44815 44816 44817 44818 /** 44819 * Internal dependencies 44820 */ 44821 44822 44823 44824 44825 function useTabNav() { 44826 const containerRef = /** @type {typeof useRef<HTMLElement>} */(0,external_wp_element_namespaceObject.useRef)(); 44827 const focusCaptureBeforeRef = (0,external_wp_element_namespaceObject.useRef)(); 44828 const focusCaptureAfterRef = (0,external_wp_element_namespaceObject.useRef)(); 44829 const { 44830 hasMultiSelection, 44831 getSelectedBlockClientId, 44832 getBlockCount, 44833 getBlockOrder, 44834 getLastFocus, 44835 getSectionRootClientId, 44836 isZoomOut 44837 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 44838 const { 44839 setLastFocus 44840 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 44841 44842 // Reference that holds the a flag for enabling or disabling 44843 // capturing on the focus capture elements. 44844 const noCaptureRef = (0,external_wp_element_namespaceObject.useRef)(); 44845 function onFocusCapture(event) { 44846 const canvasElement = containerRef.current.ownerDocument === event.target.ownerDocument ? containerRef.current : containerRef.current.ownerDocument.defaultView.frameElement; 44847 44848 // Do not capture incoming focus if set by us in WritingFlow. 44849 if (noCaptureRef.current) { 44850 noCaptureRef.current = null; 44851 } else if (hasMultiSelection()) { 44852 containerRef.current.focus(); 44853 } else if (getSelectedBlockClientId()) { 44854 if (getLastFocus()?.current) { 44855 getLastFocus().current.focus(); 44856 } else { 44857 // Handles when the last focus has not been set yet, or has been cleared by new blocks being added via the inserter. 44858 containerRef.current.querySelector(`[data-block="$getSelectedBlockClientId()}"]`).focus(); 44859 } 44860 } 44861 // In "compose" mode without a selected ID, we want to place focus on the section root when tabbing to the canvas. 44862 else if (isZoomOut()) { 44863 const sectionRootClientId = getSectionRootClientId(); 44864 const sectionBlocks = getBlockOrder(sectionRootClientId); 44865 44866 // If we have section within the section root, focus the first one. 44867 if (sectionBlocks.length) { 44868 containerRef.current.querySelector(`[data-block="$sectionBlocks[0]}"]`).focus(); 44869 } 44870 // If we don't have any section blocks, focus the section root. 44871 else if (sectionRootClientId) { 44872 containerRef.current.querySelector(`[data-block="$sectionRootClientId}"]`).focus(); 44873 } else { 44874 // If we don't have any section root, focus the canvas. 44875 canvasElement.focus(); 44876 } 44877 } else { 44878 const isBefore = 44879 // eslint-disable-next-line no-bitwise 44880 event.target.compareDocumentPosition(canvasElement) & event.target.DOCUMENT_POSITION_FOLLOWING; 44881 const tabbables = external_wp_dom_namespaceObject.focus.tabbable.find(containerRef.current); 44882 if (tabbables.length) { 44883 const next = isBefore ? tabbables[0] : tabbables[tabbables.length - 1]; 44884 next.focus(); 44885 } 44886 } 44887 } 44888 const before = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 44889 ref: focusCaptureBeforeRef, 44890 tabIndex: "0", 44891 onFocus: onFocusCapture 44892 }); 44893 const after = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 44894 ref: focusCaptureAfterRef, 44895 tabIndex: "0", 44896 onFocus: onFocusCapture 44897 }); 44898 const ref = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 44899 function onKeyDown(event) { 44900 if (event.defaultPrevented) { 44901 return; 44902 } 44903 44904 // In Edit mode, Tab should focus the first tabbable element after 44905 // the content, which is normally the sidebar (with block controls) 44906 // and Shift+Tab should focus the first tabbable element before the 44907 // content, which is normally the block toolbar. 44908 // Arrow keys can be used, and Tab and arrow keys can be used in 44909 // Navigation mode (press Esc), to navigate through blocks. 44910 if (event.keyCode !== external_wp_keycodes_namespaceObject.TAB) { 44911 return; 44912 } 44913 if ( 44914 // Bails in case the focus capture elements aren’t present. They 44915 // may be omitted to avoid silent tab stops in preview mode. 44916 // See: https://github.com/WordPress/gutenberg/pull/59317 44917 !focusCaptureAfterRef.current || !focusCaptureBeforeRef.current) { 44918 return; 44919 } 44920 const { 44921 target, 44922 shiftKey: isShift 44923 } = event; 44924 const direction = isShift ? 'findPrevious' : 'findNext'; 44925 const nextTabbable = external_wp_dom_namespaceObject.focus.tabbable[direction](target); 44926 44927 // We want to constrain the tabbing to the block and its child blocks. 44928 // If the preceding form element is within a different block, 44929 // such as two sibling image blocks in the placeholder state, 44930 // we want shift + tab from the first form element to move to the image 44931 // block toolbar and not the previous image block's form element. 44932 const currentBlock = target.closest('[data-block]'); 44933 const isElementPartOfSelectedBlock = currentBlock && nextTabbable && (isInSameBlock(currentBlock, nextTabbable) || isInsideRootBlock(currentBlock, nextTabbable)); 44934 44935 // Allow tabbing from the block wrapper to a form element, 44936 // and between form elements rendered in a block and its child blocks, 44937 // such as inside a placeholder. Form elements are generally 44938 // meant to be UI rather than part of the content. Ideally 44939 // these are not rendered in the content and perhaps in the 44940 // future they can be rendered in an iframe or shadow DOM. 44941 if ((0,external_wp_dom_namespaceObject.isFormElement)(nextTabbable) && isElementPartOfSelectedBlock) { 44942 return; 44943 } 44944 const next = isShift ? focusCaptureBeforeRef : focusCaptureAfterRef; 44945 44946 // Disable focus capturing on the focus capture element, so it 44947 // doesn't refocus this block and so it allows default behaviour 44948 // (moving focus to the next tabbable element). 44949 noCaptureRef.current = true; 44950 44951 // Focusing the focus capture element, which is located above and 44952 // below the editor, should not scroll the page all the way up or 44953 // down. 44954 next.current.focus({ 44955 preventScroll: true 44956 }); 44957 } 44958 function onFocusOut(event) { 44959 setLastFocus({ 44960 ...getLastFocus(), 44961 current: event.target 44962 }); 44963 const { 44964 ownerDocument 44965 } = node; 44966 44967 // If focus disappears due to there being no blocks, move focus to 44968 // the writing flow wrapper. 44969 if (!event.relatedTarget && event.target.hasAttribute('data-block') && ownerDocument.activeElement === ownerDocument.body && getBlockCount() === 0) { 44970 node.focus(); 44971 } 44972 } 44973 44974 // When tabbing back to an element in block list, this event handler prevents scrolling if the 44975 // focus capture divs (before/after) are outside of the viewport. (For example shift+tab back to a paragraph 44976 // when focus is on a sidebar element. This prevents the scrollable writing area from jumping either to the 44977 // top or bottom of the document. 44978 // 44979 // Note that it isn't possible to disable scrolling in the onFocus event. We need to intercept this 44980 // earlier in the keypress handler, and call focus( { preventScroll: true } ) instead. 44981 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus#parameters 44982 function preventScrollOnTab(event) { 44983 if (event.keyCode !== external_wp_keycodes_namespaceObject.TAB) { 44984 return; 44985 } 44986 if (event.target?.getAttribute('role') === 'region') { 44987 return; 44988 } 44989 if (containerRef.current === event.target) { 44990 return; 44991 } 44992 const isShift = event.shiftKey; 44993 const direction = isShift ? 'findPrevious' : 'findNext'; 44994 const target = external_wp_dom_namespaceObject.focus.tabbable[direction](event.target); 44995 // Only do something when the next tabbable is a focus capture div (before/after) 44996 if (target === focusCaptureBeforeRef.current || target === focusCaptureAfterRef.current) { 44997 event.preventDefault(); 44998 target.focus({ 44999 preventScroll: true 45000 }); 45001 } 45002 } 45003 const { 45004 ownerDocument 45005 } = node; 45006 const { 45007 defaultView 45008 } = ownerDocument; 45009 defaultView.addEventListener('keydown', preventScrollOnTab); 45010 node.addEventListener('keydown', onKeyDown); 45011 node.addEventListener('focusout', onFocusOut); 45012 return () => { 45013 defaultView.removeEventListener('keydown', preventScrollOnTab); 45014 node.removeEventListener('keydown', onKeyDown); 45015 node.removeEventListener('focusout', onFocusOut); 45016 }; 45017 }, []); 45018 const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([containerRef, ref]); 45019 return [before, mergedRefs, after]; 45020 } 45021 45022 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-arrow-nav.js 45023 /** 45024 * WordPress dependencies 45025 */ 45026 45027 45028 45029 45030 45031 /** 45032 * Internal dependencies 45033 */ 45034 45035 45036 45037 /** 45038 * Returns true if the element should consider edge navigation upon a keyboard 45039 * event of the given directional key code, or false otherwise. 45040 * 45041 * @param {Element} element HTML element to test. 45042 * @param {number} keyCode KeyboardEvent keyCode to test. 45043 * @param {boolean} hasModifier Whether a modifier is pressed. 45044 * 45045 * @return {boolean} Whether element should consider edge navigation. 45046 */ 45047 function isNavigationCandidate(element, keyCode, hasModifier) { 45048 const isVertical = keyCode === external_wp_keycodes_namespaceObject.UP || keyCode === external_wp_keycodes_namespaceObject.DOWN; 45049 const { 45050 tagName 45051 } = element; 45052 const elementType = element.getAttribute('type'); 45053 45054 // Native inputs should not navigate vertically, unless they are simple types that don't need up/down arrow keys. 45055 if (isVertical && !hasModifier) { 45056 if (tagName === 'INPUT') { 45057 const verticalInputTypes = ['date', 'datetime-local', 'month', 'number', 'range', 'time', 'week']; 45058 return !verticalInputTypes.includes(elementType); 45059 } 45060 return true; 45061 } 45062 45063 // Native inputs should not navigate horizontally, unless they are simple types that don't need left/right arrow keys. 45064 if (tagName === 'INPUT') { 45065 const simpleInputTypes = ['button', 'checkbox', 'number', 'color', 'file', 'image', 'radio', 'reset', 'submit']; 45066 return simpleInputTypes.includes(elementType); 45067 } 45068 45069 // Native textareas should not navigate horizontally. 45070 return tagName !== 'TEXTAREA'; 45071 } 45072 45073 /** 45074 * Returns the optimal tab target from the given focused element in the desired 45075 * direction. A preference is made toward text fields, falling back to the block 45076 * focus stop if no other candidates exist for the block. 45077 * 45078 * @param {Element} target Currently focused text field. 45079 * @param {boolean} isReverse True if considering as the first field. 45080 * @param {Element} containerElement Element containing all blocks. 45081 * @param {boolean} onlyVertical Whether to only consider tabbable elements 45082 * that are visually above or under the 45083 * target. 45084 * 45085 * @return {?Element} Optimal tab target, if one exists. 45086 */ 45087 function getClosestTabbable(target, isReverse, containerElement, onlyVertical) { 45088 // Since the current focus target is not guaranteed to be a text field, find 45089 // all focusables. Tabbability is considered later. 45090 let focusableNodes = external_wp_dom_namespaceObject.focus.focusable.find(containerElement); 45091 if (isReverse) { 45092 focusableNodes.reverse(); 45093 } 45094 45095 // Consider as candidates those focusables after the current target. It's 45096 // assumed this can only be reached if the target is focusable (on its 45097 // keydown event), so no need to verify it exists in the set. 45098 focusableNodes = focusableNodes.slice(focusableNodes.indexOf(target) + 1); 45099 let targetRect; 45100 if (onlyVertical) { 45101 targetRect = target.getBoundingClientRect(); 45102 } 45103 function isTabCandidate(node) { 45104 if (node.closest('[inert]')) { 45105 return; 45106 } 45107 45108 // Skip if there's only one child that is content editable (and thus a 45109 // better candidate). 45110 if (node.children.length === 1 && isInSameBlock(node, node.firstElementChild) && node.firstElementChild.getAttribute('contenteditable') === 'true') { 45111 return; 45112 } 45113 45114 // Not a candidate if the node is not tabbable. 45115 if (!external_wp_dom_namespaceObject.focus.tabbable.isTabbableIndex(node)) { 45116 return false; 45117 } 45118 45119 // Skip focusable elements such as links within content editable nodes. 45120 if (node.isContentEditable && node.contentEditable !== 'true') { 45121 return false; 45122 } 45123 if (onlyVertical) { 45124 const nodeRect = node.getBoundingClientRect(); 45125 if (nodeRect.left >= targetRect.right || nodeRect.right <= targetRect.left) { 45126 return false; 45127 } 45128 } 45129 return true; 45130 } 45131 return focusableNodes.find(isTabCandidate); 45132 } 45133 function useArrowNav() { 45134 const { 45135 getMultiSelectedBlocksStartClientId, 45136 getMultiSelectedBlocksEndClientId, 45137 getSettings, 45138 hasMultiSelection, 45139 __unstableIsFullySelected 45140 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45141 const { 45142 selectBlock 45143 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45144 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45145 // Here a DOMRect is stored while moving the caret vertically so 45146 // vertical position of the start position can be restored. This is to 45147 // recreate browser behaviour across blocks. 45148 let verticalRect; 45149 function onMouseDown() { 45150 verticalRect = null; 45151 } 45152 function isClosestTabbableABlock(target, isReverse) { 45153 const closestTabbable = getClosestTabbable(target, isReverse, node); 45154 return closestTabbable && getBlockClientId(closestTabbable); 45155 } 45156 function onKeyDown(event) { 45157 // Abort if navigation has already been handled (e.g. RichText 45158 // inline boundaries). 45159 if (event.defaultPrevented) { 45160 return; 45161 } 45162 const { 45163 keyCode, 45164 target, 45165 shiftKey, 45166 ctrlKey, 45167 altKey, 45168 metaKey 45169 } = event; 45170 const isUp = keyCode === external_wp_keycodes_namespaceObject.UP; 45171 const isDown = keyCode === external_wp_keycodes_namespaceObject.DOWN; 45172 const isLeft = keyCode === external_wp_keycodes_namespaceObject.LEFT; 45173 const isRight = keyCode === external_wp_keycodes_namespaceObject.RIGHT; 45174 const isReverse = isUp || isLeft; 45175 const isHorizontal = isLeft || isRight; 45176 const isVertical = isUp || isDown; 45177 const isNav = isHorizontal || isVertical; 45178 const hasModifier = shiftKey || ctrlKey || altKey || metaKey; 45179 const isNavEdge = isVertical ? external_wp_dom_namespaceObject.isVerticalEdge : external_wp_dom_namespaceObject.isHorizontalEdge; 45180 const { 45181 ownerDocument 45182 } = node; 45183 const { 45184 defaultView 45185 } = ownerDocument; 45186 if (!isNav) { 45187 return; 45188 } 45189 45190 // If there is a multi-selection, the arrow keys should collapse the 45191 // selection to the start or end of the selection. 45192 if (hasMultiSelection()) { 45193 if (shiftKey) { 45194 return; 45195 } 45196 45197 // Only handle if we have a full selection (not a native partial 45198 // selection). 45199 if (!__unstableIsFullySelected()) { 45200 return; 45201 } 45202 event.preventDefault(); 45203 if (isReverse) { 45204 selectBlock(getMultiSelectedBlocksStartClientId()); 45205 } else { 45206 selectBlock(getMultiSelectedBlocksEndClientId(), -1); 45207 } 45208 return; 45209 } 45210 45211 // Abort if our current target is not a candidate for navigation 45212 // (e.g. preserve native input behaviors). 45213 if (!isNavigationCandidate(target, keyCode, hasModifier)) { 45214 return; 45215 } 45216 45217 // When presing any key other than up or down, the initial vertical 45218 // position must ALWAYS be reset. The vertical position is saved so 45219 // it can be restored as well as possible on sebsequent vertical 45220 // arrow key presses. It may not always be possible to restore the 45221 // exact same position (such as at an empty line), so it wouldn't be 45222 // good to compute the position right before any vertical arrow key 45223 // press. 45224 if (!isVertical) { 45225 verticalRect = null; 45226 } else if (!verticalRect) { 45227 verticalRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView); 45228 } 45229 45230 // In the case of RTL scripts, right means previous and left means 45231 // next, which is the exact reverse of LTR. 45232 const isReverseDir = (0,external_wp_dom_namespaceObject.isRTL)(target) ? !isReverse : isReverse; 45233 const { 45234 keepCaretInsideBlock 45235 } = getSettings(); 45236 if (shiftKey) { 45237 if (isClosestTabbableABlock(target, isReverse) && isNavEdge(target, isReverse)) { 45238 node.contentEditable = true; 45239 // Firefox doesn't automatically move focus. 45240 node.focus(); 45241 } 45242 } else if (isVertical && (0,external_wp_dom_namespaceObject.isVerticalEdge)(target, isReverse) && ( 45243 // When Alt is pressed, only intercept if the caret is also at 45244 // the horizontal edge. 45245 altKey ? (0,external_wp_dom_namespaceObject.isHorizontalEdge)(target, isReverseDir) : true) && !keepCaretInsideBlock) { 45246 const closestTabbable = getClosestTabbable(target, isReverse, node, true); 45247 if (closestTabbable) { 45248 (0,external_wp_dom_namespaceObject.placeCaretAtVerticalEdge)(closestTabbable, 45249 // When Alt is pressed, place the caret at the furthest 45250 // horizontal edge and the furthest vertical edge. 45251 altKey ? !isReverse : isReverse, altKey ? undefined : verticalRect); 45252 event.preventDefault(); 45253 } 45254 } else if (isHorizontal && defaultView.getSelection().isCollapsed && (0,external_wp_dom_namespaceObject.isHorizontalEdge)(target, isReverseDir) && !keepCaretInsideBlock) { 45255 const closestTabbable = getClosestTabbable(target, isReverseDir, node); 45256 (0,external_wp_dom_namespaceObject.placeCaretAtHorizontalEdge)(closestTabbable, isReverse); 45257 event.preventDefault(); 45258 } 45259 } 45260 node.addEventListener('mousedown', onMouseDown); 45261 node.addEventListener('keydown', onKeyDown); 45262 return () => { 45263 node.removeEventListener('mousedown', onMouseDown); 45264 node.removeEventListener('keydown', onKeyDown); 45265 }; 45266 }, []); 45267 } 45268 45269 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-select-all.js 45270 /** 45271 * WordPress dependencies 45272 */ 45273 45274 45275 45276 45277 45278 /** 45279 * Internal dependencies 45280 */ 45281 45282 function useSelectAll() { 45283 const { 45284 getBlockOrder, 45285 getSelectedBlockClientIds, 45286 getBlockRootClientId 45287 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45288 const { 45289 multiSelect, 45290 selectBlock 45291 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45292 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 45293 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45294 function onKeyDown(event) { 45295 if (!isMatch('core/block-editor/select-all', event)) { 45296 return; 45297 } 45298 const selectedClientIds = getSelectedBlockClientIds(); 45299 if (selectedClientIds.length < 2 && !(0,external_wp_dom_namespaceObject.isEntirelySelected)(event.target)) { 45300 return; 45301 } 45302 event.preventDefault(); 45303 const [firstSelectedClientId] = selectedClientIds; 45304 const rootClientId = getBlockRootClientId(firstSelectedClientId); 45305 const blockClientIds = getBlockOrder(rootClientId); 45306 45307 // If we have selected all sibling nested blocks, try selecting up a 45308 // level. See: https://github.com/WordPress/gutenberg/pull/31859/ 45309 if (selectedClientIds.length === blockClientIds.length) { 45310 if (rootClientId) { 45311 node.ownerDocument.defaultView.getSelection().removeAllRanges(); 45312 selectBlock(rootClientId); 45313 } 45314 return; 45315 } 45316 multiSelect(blockClientIds[0], blockClientIds[blockClientIds.length - 1]); 45317 } 45318 node.addEventListener('keydown', onKeyDown); 45319 return () => { 45320 node.removeEventListener('keydown', onKeyDown); 45321 }; 45322 }, []); 45323 } 45324 45325 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-drag-selection.js 45326 /** 45327 * WordPress dependencies 45328 */ 45329 45330 45331 45332 /** 45333 * Internal dependencies 45334 */ 45335 45336 45337 /** 45338 * Sets the `contenteditable` wrapper element to `value`. 45339 * 45340 * @param {HTMLElement} node Block element. 45341 * @param {boolean} value `contentEditable` value (true or false) 45342 */ 45343 function setContentEditableWrapper(node, value) { 45344 node.contentEditable = value; 45345 // Firefox doesn't automatically move focus. 45346 if (value) { 45347 node.focus(); 45348 } 45349 } 45350 45351 /** 45352 * Sets a multi-selection based on the native selection across blocks. 45353 */ 45354 function useDragSelection() { 45355 const { 45356 startMultiSelect, 45357 stopMultiSelect 45358 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45359 const { 45360 isSelectionEnabled, 45361 hasSelectedBlock, 45362 isDraggingBlocks, 45363 isMultiSelecting 45364 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45365 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45366 const { 45367 ownerDocument 45368 } = node; 45369 const { 45370 defaultView 45371 } = ownerDocument; 45372 let anchorElement; 45373 let rafId; 45374 function onMouseUp() { 45375 stopMultiSelect(); 45376 // Equivalent to attaching the listener once. 45377 defaultView.removeEventListener('mouseup', onMouseUp); 45378 // The browser selection won't have updated yet at this point, 45379 // so wait until the next animation frame to get the browser 45380 // selection. 45381 rafId = defaultView.requestAnimationFrame(() => { 45382 if (!hasSelectedBlock()) { 45383 return; 45384 } 45385 45386 // If the selection is complete (on mouse up), and no 45387 // multiple blocks have been selected, set focus back to the 45388 // anchor element. if the anchor element contains the 45389 // selection. Additionally, the contentEditable wrapper can 45390 // now be disabled again. 45391 setContentEditableWrapper(node, false); 45392 const selection = defaultView.getSelection(); 45393 if (selection.rangeCount) { 45394 const range = selection.getRangeAt(0); 45395 const { 45396 commonAncestorContainer 45397 } = range; 45398 const clonedRange = range.cloneRange(); 45399 if (anchorElement.contains(commonAncestorContainer)) { 45400 anchorElement.focus(); 45401 selection.removeAllRanges(); 45402 selection.addRange(clonedRange); 45403 } 45404 } 45405 }); 45406 } 45407 let lastMouseDownTarget; 45408 function onMouseDown({ 45409 target 45410 }) { 45411 lastMouseDownTarget = target; 45412 } 45413 function onMouseLeave({ 45414 buttons, 45415 target, 45416 relatedTarget 45417 }) { 45418 if (!target.contains(lastMouseDownTarget)) { 45419 return; 45420 } 45421 45422 // If we're moving into a child element, ignore. We're tracking 45423 // the mouse leaving the element to a parent, no a child. 45424 if (target.contains(relatedTarget)) { 45425 return; 45426 } 45427 45428 // Avoid triggering a multi-selection if the user is already 45429 // dragging blocks. 45430 if (isDraggingBlocks()) { 45431 return; 45432 } 45433 45434 // The primary button must be pressed to initiate selection. 45435 // See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons 45436 if (buttons !== 1) { 45437 return; 45438 } 45439 45440 // Abort if we are already multi-selecting. 45441 if (isMultiSelecting()) { 45442 return; 45443 } 45444 45445 // Abort if selection is leaving writing flow. 45446 if (node === target) { 45447 return; 45448 } 45449 45450 // Check the attribute, not the contentEditable attribute. All 45451 // child elements of the content editable wrapper are editable 45452 // and return true for this property. We only want to start 45453 // multi selecting when the mouse leaves the wrapper. 45454 if (target.getAttribute('contenteditable') !== 'true') { 45455 return; 45456 } 45457 if (!isSelectionEnabled()) { 45458 return; 45459 } 45460 45461 // Do not rely on the active element because it may change after 45462 // the mouse leaves for the first time. See 45463 // https://github.com/WordPress/gutenberg/issues/48747. 45464 anchorElement = target; 45465 startMultiSelect(); 45466 45467 // `onSelectionStart` is called after `mousedown` and 45468 // `mouseleave` (from a block). The selection ends when 45469 // `mouseup` happens anywhere in the window. 45470 defaultView.addEventListener('mouseup', onMouseUp); 45471 45472 // Allow cross contentEditable selection by temporarily making 45473 // all content editable. We can't rely on using the store and 45474 // React because re-rending happens too slowly. We need to be 45475 // able to select across instances immediately. 45476 setContentEditableWrapper(node, true); 45477 } 45478 node.addEventListener('mouseout', onMouseLeave); 45479 node.addEventListener('mousedown', onMouseDown); 45480 return () => { 45481 node.removeEventListener('mouseout', onMouseLeave); 45482 defaultView.removeEventListener('mouseup', onMouseUp); 45483 defaultView.cancelAnimationFrame(rafId); 45484 }; 45485 }, [startMultiSelect, stopMultiSelect, isSelectionEnabled, hasSelectedBlock]); 45486 } 45487 45488 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-selection-observer.js 45489 /** 45490 * WordPress dependencies 45491 */ 45492 45493 45494 45495 45496 45497 /** 45498 * Internal dependencies 45499 */ 45500 45501 45502 45503 /** 45504 * Extract the selection start node from the selection. When the anchor node is 45505 * not a text node, the selection offset is the index of a child node. 45506 * 45507 * @param {Selection} selection The selection. 45508 * 45509 * @return {Element} The selection start node. 45510 */ 45511 function extractSelectionStartNode(selection) { 45512 const { 45513 anchorNode, 45514 anchorOffset 45515 } = selection; 45516 if (anchorNode.nodeType === anchorNode.TEXT_NODE) { 45517 return anchorNode; 45518 } 45519 if (anchorOffset === 0) { 45520 return anchorNode; 45521 } 45522 return anchorNode.childNodes[anchorOffset - 1]; 45523 } 45524 45525 /** 45526 * Extract the selection end node from the selection. When the focus node is not 45527 * a text node, the selection offset is the index of a child node. The selection 45528 * reaches up to but excluding that child node. 45529 * 45530 * @param {Selection} selection The selection. 45531 * 45532 * @return {Element} The selection start node. 45533 */ 45534 function extractSelectionEndNode(selection) { 45535 const { 45536 focusNode, 45537 focusOffset 45538 } = selection; 45539 if (focusNode.nodeType === focusNode.TEXT_NODE) { 45540 return focusNode; 45541 } 45542 if (focusOffset === focusNode.childNodes.length) { 45543 return focusNode; 45544 } 45545 45546 // When the selection is forward (the selection ends with the focus node), 45547 // the selection may extend into the next element with an offset of 0. This 45548 // may trigger multi selection even though the selection does not visually 45549 // end in the next block. 45550 if (focusOffset === 0 && (0,external_wp_dom_namespaceObject.isSelectionForward)(selection)) { 45551 var _focusNode$previousSi; 45552 return (_focusNode$previousSi = focusNode.previousSibling) !== null && _focusNode$previousSi !== void 0 ? _focusNode$previousSi : focusNode.parentElement; 45553 } 45554 return focusNode.childNodes[focusOffset]; 45555 } 45556 function findDepth(a, b) { 45557 let depth = 0; 45558 while (a[depth] === b[depth]) { 45559 depth++; 45560 } 45561 return depth; 45562 } 45563 45564 /** 45565 * Sets the `contenteditable` wrapper element to `value`. 45566 * 45567 * @param {HTMLElement} node Block element. 45568 * @param {boolean} value `contentEditable` value (true or false) 45569 */ 45570 function use_selection_observer_setContentEditableWrapper(node, value) { 45571 // Since we are calling this on every selection change, check if the value 45572 // needs to be updated first because it trigger the browser to recalculate 45573 // style. 45574 if (node.contentEditable !== String(value)) { 45575 node.contentEditable = value; 45576 45577 // Firefox doesn't automatically move focus. 45578 if (value) { 45579 node.focus(); 45580 } 45581 } 45582 } 45583 function getRichTextElement(node) { 45584 const element = node.nodeType === node.ELEMENT_NODE ? node : node.parentElement; 45585 return element?.closest('[data-wp-block-attribute-key]'); 45586 } 45587 45588 /** 45589 * Sets a multi-selection based on the native selection across blocks. 45590 */ 45591 function useSelectionObserver() { 45592 const { 45593 multiSelect, 45594 selectBlock, 45595 selectionChange 45596 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45597 const { 45598 getBlockParents, 45599 getBlockSelectionStart, 45600 isMultiSelecting 45601 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45602 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45603 const { 45604 ownerDocument 45605 } = node; 45606 const { 45607 defaultView 45608 } = ownerDocument; 45609 function onSelectionChange(event) { 45610 const selection = defaultView.getSelection(); 45611 if (!selection.rangeCount) { 45612 return; 45613 } 45614 const startNode = extractSelectionStartNode(selection); 45615 const endNode = extractSelectionEndNode(selection); 45616 if (!node.contains(startNode) || !node.contains(endNode)) { 45617 return; 45618 } 45619 45620 // If selection is collapsed and we haven't used `shift+click`, 45621 // end multi selection and disable the contentEditable wrapper. 45622 // We have to check about `shift+click` case because elements 45623 // that don't support text selection might be involved, and we might 45624 // update the clientIds to multi-select blocks. 45625 // For now we check if the event is a `mouse` event. 45626 const isClickShift = event.shiftKey && event.type === 'mouseup'; 45627 if (selection.isCollapsed && !isClickShift) { 45628 if (node.contentEditable === 'true' && !isMultiSelecting()) { 45629 use_selection_observer_setContentEditableWrapper(node, false); 45630 let element = startNode.nodeType === startNode.ELEMENT_NODE ? startNode : startNode.parentElement; 45631 element = element?.closest('[contenteditable]'); 45632 element?.focus(); 45633 } 45634 return; 45635 } 45636 let startClientId = getBlockClientId(startNode); 45637 let endClientId = getBlockClientId(endNode); 45638 45639 // If the selection has changed and we had pressed `shift+click`, 45640 // we need to check if in an element that doesn't support 45641 // text selection has been clicked. 45642 if (isClickShift) { 45643 const selectedClientId = getBlockSelectionStart(); 45644 const clickedClientId = getBlockClientId(event.target); 45645 // `endClientId` is not defined if we end the selection by clicking a non-selectable block. 45646 // We need to check if there was already a selection with a non-selectable focusNode. 45647 const focusNodeIsNonSelectable = clickedClientId !== endClientId; 45648 if (startClientId === endClientId && selection.isCollapsed || !endClientId || focusNodeIsNonSelectable) { 45649 endClientId = clickedClientId; 45650 } 45651 // Handle the case when we have a non-selectable block 45652 // selected and click another one. 45653 if (startClientId !== selectedClientId) { 45654 startClientId = selectedClientId; 45655 } 45656 } 45657 45658 // If the selection did not involve a block, return. 45659 if (startClientId === undefined && endClientId === undefined) { 45660 use_selection_observer_setContentEditableWrapper(node, false); 45661 return; 45662 } 45663 const isSingularSelection = startClientId === endClientId; 45664 if (isSingularSelection) { 45665 if (!isMultiSelecting()) { 45666 selectBlock(startClientId); 45667 } else { 45668 multiSelect(startClientId, startClientId); 45669 } 45670 } else { 45671 const startPath = [...getBlockParents(startClientId), startClientId]; 45672 const endPath = [...getBlockParents(endClientId), endClientId]; 45673 const depth = findDepth(startPath, endPath); 45674 if (startPath[depth] !== startClientId || endPath[depth] !== endClientId) { 45675 multiSelect(startPath[depth], endPath[depth]); 45676 return; 45677 } 45678 const richTextElementStart = getRichTextElement(startNode); 45679 const richTextElementEnd = getRichTextElement(endNode); 45680 if (richTextElementStart && richTextElementEnd) { 45681 var _richTextDataStart$st, _richTextDataEnd$star; 45682 const range = selection.getRangeAt(0); 45683 const richTextDataStart = (0,external_wp_richText_namespaceObject.create)({ 45684 element: richTextElementStart, 45685 range, 45686 __unstableIsEditableTree: true 45687 }); 45688 const richTextDataEnd = (0,external_wp_richText_namespaceObject.create)({ 45689 element: richTextElementEnd, 45690 range, 45691 __unstableIsEditableTree: true 45692 }); 45693 const startOffset = (_richTextDataStart$st = richTextDataStart.start) !== null && _richTextDataStart$st !== void 0 ? _richTextDataStart$st : richTextDataStart.end; 45694 const endOffset = (_richTextDataEnd$star = richTextDataEnd.start) !== null && _richTextDataEnd$star !== void 0 ? _richTextDataEnd$star : richTextDataEnd.end; 45695 selectionChange({ 45696 start: { 45697 clientId: startClientId, 45698 attributeKey: richTextElementStart.dataset.wpBlockAttributeKey, 45699 offset: startOffset 45700 }, 45701 end: { 45702 clientId: endClientId, 45703 attributeKey: richTextElementEnd.dataset.wpBlockAttributeKey, 45704 offset: endOffset 45705 } 45706 }); 45707 } else { 45708 multiSelect(startClientId, endClientId); 45709 } 45710 } 45711 } 45712 ownerDocument.addEventListener('selectionchange', onSelectionChange); 45713 defaultView.addEventListener('mouseup', onSelectionChange); 45714 return () => { 45715 ownerDocument.removeEventListener('selectionchange', onSelectionChange); 45716 defaultView.removeEventListener('mouseup', onSelectionChange); 45717 }; 45718 }, [multiSelect, selectBlock, selectionChange, getBlockParents]); 45719 } 45720 45721 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-click-selection.js 45722 /** 45723 * WordPress dependencies 45724 */ 45725 45726 45727 45728 /** 45729 * Internal dependencies 45730 */ 45731 45732 45733 function useClickSelection() { 45734 const { 45735 selectBlock 45736 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45737 const { 45738 isSelectionEnabled, 45739 getBlockSelectionStart, 45740 hasMultiSelection 45741 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45742 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45743 function onMouseDown(event) { 45744 // The main button. 45745 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button 45746 if (!isSelectionEnabled() || event.button !== 0) { 45747 return; 45748 } 45749 const startClientId = getBlockSelectionStart(); 45750 const clickedClientId = getBlockClientId(event.target); 45751 if (event.shiftKey) { 45752 if (startClientId !== clickedClientId) { 45753 node.contentEditable = true; 45754 // Firefox doesn't automatically move focus. 45755 node.focus(); 45756 } 45757 } else if (hasMultiSelection()) { 45758 // Allow user to escape out of a multi-selection to a 45759 // singular selection of a block via click. This is handled 45760 // here since focus handling excludes blocks when there is 45761 // multiselection, as focus can be incurred by starting a 45762 // multiselection (focus moved to first block's multi- 45763 // controls). 45764 selectBlock(clickedClientId); 45765 } 45766 } 45767 node.addEventListener('mousedown', onMouseDown); 45768 return () => { 45769 node.removeEventListener('mousedown', onMouseDown); 45770 }; 45771 }, [selectBlock, isSelectionEnabled, getBlockSelectionStart, hasMultiSelection]); 45772 } 45773 45774 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-input.js 45775 /** 45776 * WordPress dependencies 45777 */ 45778 45779 45780 45781 45782 45783 /** 45784 * Internal dependencies 45785 */ 45786 45787 45788 /** 45789 * Handles input for selections across blocks. 45790 */ 45791 function useInput() { 45792 const { 45793 __unstableIsFullySelected, 45794 getSelectedBlockClientIds, 45795 getSelectedBlockClientId, 45796 __unstableIsSelectionMergeable, 45797 hasMultiSelection, 45798 getBlockName, 45799 canInsertBlockType, 45800 getBlockRootClientId, 45801 getSelectionStart, 45802 getSelectionEnd, 45803 getBlockAttributes 45804 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45805 const { 45806 replaceBlocks, 45807 __unstableSplitSelection, 45808 removeBlocks, 45809 __unstableDeleteSelection, 45810 __unstableExpandSelection, 45811 __unstableMarkAutomaticChange 45812 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 45813 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 45814 function onBeforeInput(event) { 45815 // If writing flow is editable, NEVER allow the browser to alter the 45816 // DOM. This will cause React errors (and the DOM should only be 45817 // altered in a controlled fashion). 45818 if (node.contentEditable === 'true') { 45819 event.preventDefault(); 45820 } 45821 } 45822 function onKeyDown(event) { 45823 if (event.defaultPrevented) { 45824 return; 45825 } 45826 if (!hasMultiSelection()) { 45827 if (event.keyCode === external_wp_keycodes_namespaceObject.ENTER) { 45828 if (event.shiftKey || __unstableIsFullySelected()) { 45829 return; 45830 } 45831 const clientId = getSelectedBlockClientId(); 45832 const blockName = getBlockName(clientId); 45833 const selectionStart = getSelectionStart(); 45834 const selectionEnd = getSelectionEnd(); 45835 if (selectionStart.attributeKey === selectionEnd.attributeKey) { 45836 const selectedAttributeValue = getBlockAttributes(clientId)[selectionStart.attributeKey]; 45837 const transforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from').filter(({ 45838 type 45839 }) => type === 'enter'); 45840 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(transforms, item => { 45841 return item.regExp.test(selectedAttributeValue); 45842 }); 45843 if (transformation) { 45844 replaceBlocks(clientId, transformation.transform({ 45845 content: selectedAttributeValue 45846 })); 45847 __unstableMarkAutomaticChange(); 45848 return; 45849 } 45850 } 45851 if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'splitting', false) && !event.__deprecatedOnSplit) { 45852 return; 45853 } 45854 45855 // Ensure template is not locked. 45856 if (canInsertBlockType(blockName, getBlockRootClientId(clientId))) { 45857 __unstableSplitSelection(); 45858 event.preventDefault(); 45859 } 45860 } 45861 return; 45862 } 45863 if (event.keyCode === external_wp_keycodes_namespaceObject.ENTER) { 45864 node.contentEditable = false; 45865 event.preventDefault(); 45866 if (__unstableIsFullySelected()) { 45867 replaceBlocks(getSelectedBlockClientIds(), (0,external_wp_blocks_namespaceObject.createBlock)((0,external_wp_blocks_namespaceObject.getDefaultBlockName)())); 45868 } else { 45869 __unstableSplitSelection(); 45870 } 45871 } else if (event.keyCode === external_wp_keycodes_namespaceObject.BACKSPACE || event.keyCode === external_wp_keycodes_namespaceObject.DELETE) { 45872 node.contentEditable = false; 45873 event.preventDefault(); 45874 if (__unstableIsFullySelected()) { 45875 removeBlocks(getSelectedBlockClientIds()); 45876 } else if (__unstableIsSelectionMergeable()) { 45877 __unstableDeleteSelection(event.keyCode === external_wp_keycodes_namespaceObject.DELETE); 45878 } else { 45879 __unstableExpandSelection(); 45880 } 45881 } else if ( 45882 // If key.length is longer than 1, it's a control key that doesn't 45883 // input anything. 45884 event.key.length === 1 && !(event.metaKey || event.ctrlKey)) { 45885 node.contentEditable = false; 45886 if (__unstableIsSelectionMergeable()) { 45887 __unstableDeleteSelection(event.keyCode === external_wp_keycodes_namespaceObject.DELETE); 45888 } else { 45889 event.preventDefault(); 45890 // Safari does not stop default behaviour with either 45891 // event.preventDefault() or node.contentEditable = false, so 45892 // remove the selection to stop browser manipulation. 45893 node.ownerDocument.defaultView.getSelection().removeAllRanges(); 45894 } 45895 } 45896 } 45897 function onCompositionStart(event) { 45898 if (!hasMultiSelection()) { 45899 return; 45900 } 45901 node.contentEditable = false; 45902 if (__unstableIsSelectionMergeable()) { 45903 __unstableDeleteSelection(); 45904 } else { 45905 event.preventDefault(); 45906 // Safari does not stop default behaviour with either 45907 // event.preventDefault() or node.contentEditable = false, so 45908 // remove the selection to stop browser manipulation. 45909 node.ownerDocument.defaultView.getSelection().removeAllRanges(); 45910 } 45911 } 45912 node.addEventListener('beforeinput', onBeforeInput); 45913 node.addEventListener('keydown', onKeyDown); 45914 node.addEventListener('compositionstart', onCompositionStart); 45915 return () => { 45916 node.removeEventListener('beforeinput', onBeforeInput); 45917 node.removeEventListener('keydown', onKeyDown); 45918 node.removeEventListener('compositionstart', onCompositionStart); 45919 }; 45920 }, []); 45921 } 45922 45923 ;// ./node_modules/@wordpress/block-editor/build-module/utils/use-notify-copy.js 45924 /** 45925 * WordPress dependencies 45926 */ 45927 45928 45929 45930 45931 45932 45933 /** 45934 * Internal dependencies 45935 */ 45936 45937 function useNotifyCopy() { 45938 const { 45939 getBlockName 45940 } = (0,external_wp_data_namespaceObject.useSelect)(store); 45941 const { 45942 getBlockType 45943 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 45944 const { 45945 createSuccessNotice 45946 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 45947 return (0,external_wp_element_namespaceObject.useCallback)((eventType, selectedBlockClientIds) => { 45948 let notice = ''; 45949 if (eventType === 'copyStyles') { 45950 notice = (0,external_wp_i18n_namespaceObject.__)('Styles copied to clipboard.'); 45951 } else if (selectedBlockClientIds.length === 1) { 45952 const clientId = selectedBlockClientIds[0]; 45953 const title = getBlockType(getBlockName(clientId))?.title; 45954 if (eventType === 'copy') { 45955 notice = (0,external_wp_i18n_namespaceObject.sprintf)( 45956 // Translators: Name of the block being copied, e.g. "Paragraph". 45957 (0,external_wp_i18n_namespaceObject.__)('Copied "%s" to clipboard.'), title); 45958 } else { 45959 notice = (0,external_wp_i18n_namespaceObject.sprintf)( 45960 // Translators: Name of the block being cut, e.g. "Paragraph". 45961 (0,external_wp_i18n_namespaceObject.__)('Moved "%s" to clipboard.'), title); 45962 } 45963 } else if (eventType === 'copy') { 45964 notice = (0,external_wp_i18n_namespaceObject.sprintf)( 45965 // Translators: %d: Number of blocks being copied. 45966 (0,external_wp_i18n_namespaceObject._n)('Copied %d block to clipboard.', 'Copied %d blocks to clipboard.', selectedBlockClientIds.length), selectedBlockClientIds.length); 45967 } else { 45968 notice = (0,external_wp_i18n_namespaceObject.sprintf)( 45969 // Translators: %d: Number of blocks being moved. 45970 (0,external_wp_i18n_namespaceObject._n)('Moved %d block to clipboard.', 'Moved %d blocks to clipboard.', selectedBlockClientIds.length), selectedBlockClientIds.length); 45971 } 45972 createSuccessNotice(notice, { 45973 type: 'snackbar' 45974 }); 45975 }, [createSuccessNotice, getBlockName, getBlockType]); 45976 } 45977 45978 ;// ./node_modules/@wordpress/block-editor/build-module/utils/pasting.js 45979 /** 45980 * WordPress dependencies 45981 */ 45982 45983 45984 /** 45985 * Normalizes a given string of HTML to remove the Windows-specific "Fragment" 45986 * comments and any preceding and trailing content. 45987 * 45988 * @param {string} html the html to be normalized 45989 * @return {string} the normalized html 45990 */ 45991 function removeWindowsFragments(html) { 45992 const startStr = '<!--StartFragment-->'; 45993 const startIdx = html.indexOf(startStr); 45994 if (startIdx > -1) { 45995 html = html.substring(startIdx + startStr.length); 45996 } else { 45997 // No point looking for EndFragment 45998 return html; 45999 } 46000 const endStr = '<!--EndFragment-->'; 46001 const endIdx = html.indexOf(endStr); 46002 if (endIdx > -1) { 46003 html = html.substring(0, endIdx); 46004 } 46005 return html; 46006 } 46007 46008 /** 46009 * Removes the charset meta tag inserted by Chromium. 46010 * See: 46011 * - https://github.com/WordPress/gutenberg/issues/33585 46012 * - https://bugs.chromium.org/p/chromium/issues/detail?id=1264616#c4 46013 * 46014 * @param {string} html the html to be stripped of the meta tag. 46015 * @return {string} the cleaned html 46016 */ 46017 function removeCharsetMetaTag(html) { 46018 const metaTag = `<meta charset='utf-8'>`; 46019 if (html.startsWith(metaTag)) { 46020 return html.slice(metaTag.length); 46021 } 46022 return html; 46023 } 46024 function getPasteEventData({ 46025 clipboardData 46026 }) { 46027 let plainText = ''; 46028 let html = ''; 46029 try { 46030 plainText = clipboardData.getData('text/plain'); 46031 html = clipboardData.getData('text/html'); 46032 } catch (error) { 46033 // Some browsers like UC Browser paste plain text by default and 46034 // don't support clipboardData at all, so allow default 46035 // behaviour. 46036 return; 46037 } 46038 46039 // Remove Windows-specific metadata appended within copied HTML text. 46040 html = removeWindowsFragments(html); 46041 46042 // Strip meta tag. 46043 html = removeCharsetMetaTag(html); 46044 const files = (0,external_wp_dom_namespaceObject.getFilesFromDataTransfer)(clipboardData); 46045 if (files.length && !shouldDismissPastedFiles(files, html)) { 46046 return { 46047 files 46048 }; 46049 } 46050 return { 46051 html, 46052 plainText, 46053 files: [] 46054 }; 46055 } 46056 46057 /** 46058 * Given a collection of DataTransfer files and HTML and plain text strings, 46059 * determine whether the files are to be dismissed in favor of the HTML. 46060 * 46061 * Certain office-type programs, like Microsoft Word or Apple Numbers, 46062 * will, upon copy, generate a screenshot of the content being copied and 46063 * attach it to the clipboard alongside the actual rich text that the user 46064 * sought to copy. In those cases, we should let Gutenberg handle the rich text 46065 * content and not the screenshot, since this allows Gutenberg to insert 46066 * meaningful blocks, like paragraphs, lists or even tables. 46067 * 46068 * @param {File[]} files File objects obtained from a paste event 46069 * @param {string} html HTML content obtained from a paste event 46070 * @return {boolean} True if the files should be dismissed 46071 */ 46072 function shouldDismissPastedFiles(files, html /*, plainText */) { 46073 // The question is only relevant when there is actual HTML content and when 46074 // there is exactly one image file. 46075 if (html && files?.length === 1 && files[0].type.indexOf('image/') === 0) { 46076 // A single <img> tag found in the HTML source suggests that the 46077 // content being pasted revolves around an image. Sometimes there are 46078 // other elements found, like <figure>, but we assume that the user's 46079 // intention is to paste the actual image file. 46080 const IMAGE_TAG = /<\s*img\b/gi; 46081 if (html.match(IMAGE_TAG)?.length !== 1) { 46082 return true; 46083 } 46084 46085 // Even when there is exactly one <img> tag in the HTML payload, we 46086 // choose to weed out local images, i.e. those whose source starts with 46087 // "file://". These payloads occur in specific configurations, such as 46088 // when copying an entire document from Microsoft Word, that contains 46089 // text and exactly one image, and pasting that content using Google 46090 // Chrome. 46091 const IMG_WITH_LOCAL_SRC = /<\s*img\b[^>]*\bsrc="file:\/\//i; 46092 if (html.match(IMG_WITH_LOCAL_SRC)) { 46093 return true; 46094 } 46095 } 46096 return false; 46097 } 46098 46099 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/utils.js 46100 /** 46101 * WordPress dependencies 46102 */ 46103 46104 46105 46106 /** 46107 * Internal dependencies 46108 */ 46109 46110 46111 const requiresWrapperOnCopy = Symbol('requiresWrapperOnCopy'); 46112 46113 /** 46114 * Sets the clipboard data for the provided blocks, with both HTML and plain 46115 * text representations. 46116 * 46117 * @param {ClipboardEvent} event Clipboard event. 46118 * @param {WPBlock[]} blocks Blocks to set as clipboard data. 46119 * @param {Object} registry The registry to select from. 46120 */ 46121 function setClipboardBlocks(event, blocks, registry) { 46122 let _blocks = blocks; 46123 const [firstBlock] = blocks; 46124 if (firstBlock) { 46125 const firstBlockType = registry.select(external_wp_blocks_namespaceObject.store).getBlockType(firstBlock.name); 46126 if (firstBlockType[requiresWrapperOnCopy]) { 46127 const { 46128 getBlockRootClientId, 46129 getBlockName, 46130 getBlockAttributes 46131 } = registry.select(store); 46132 const wrapperBlockClientId = getBlockRootClientId(firstBlock.clientId); 46133 const wrapperBlockName = getBlockName(wrapperBlockClientId); 46134 if (wrapperBlockName) { 46135 _blocks = (0,external_wp_blocks_namespaceObject.createBlock)(wrapperBlockName, getBlockAttributes(wrapperBlockClientId), _blocks); 46136 } 46137 } 46138 } 46139 const serialized = (0,external_wp_blocks_namespaceObject.serialize)(_blocks); 46140 event.clipboardData.setData('text/plain', toPlainText(serialized)); 46141 event.clipboardData.setData('text/html', serialized); 46142 } 46143 46144 /** 46145 * Returns the blocks to be pasted from the clipboard event. 46146 * 46147 * @param {ClipboardEvent} event The clipboard event. 46148 * @param {boolean} canUserUseUnfilteredHTML Whether the user can or can't post unfiltered HTML. 46149 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 46150 */ 46151 function getPasteBlocks(event, canUserUseUnfilteredHTML) { 46152 const { 46153 plainText, 46154 html, 46155 files 46156 } = getPasteEventData(event); 46157 let blocks = []; 46158 if (files.length) { 46159 const fromTransforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from'); 46160 blocks = files.reduce((accumulator, file) => { 46161 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(fromTransforms, transform => transform.type === 'files' && transform.isMatch([file])); 46162 if (transformation) { 46163 accumulator.push(transformation.transform([file])); 46164 } 46165 return accumulator; 46166 }, []).flat(); 46167 } else { 46168 blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 46169 HTML: html, 46170 plainText, 46171 mode: 'BLOCKS', 46172 canUserUseUnfilteredHTML 46173 }); 46174 } 46175 return blocks; 46176 } 46177 46178 /** 46179 * Given a string of HTML representing serialized blocks, returns the plain 46180 * text extracted after stripping the HTML of any tags and fixing line breaks. 46181 * 46182 * @param {string} html Serialized blocks. 46183 * @return {string} The plain-text content with any html removed. 46184 */ 46185 function toPlainText(html) { 46186 // Manually handle BR tags as line breaks prior to `stripHTML` call 46187 html = html.replace(/<br>/g, '\n'); 46188 const plainText = (0,external_wp_dom_namespaceObject.__unstableStripHTML)(html).trim(); 46189 46190 // Merge any consecutive line breaks 46191 return plainText.replace(/\n\n+/g, '\n\n'); 46192 } 46193 46194 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-clipboard-handler.js 46195 /** 46196 * WordPress dependencies 46197 */ 46198 46199 46200 46201 46202 46203 /** 46204 * Internal dependencies 46205 */ 46206 46207 46208 46209 46210 function useClipboardHandler() { 46211 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 46212 const { 46213 getBlocksByClientId, 46214 getSelectedBlockClientIds, 46215 hasMultiSelection, 46216 getSettings, 46217 getBlockName, 46218 __unstableIsFullySelected, 46219 __unstableIsSelectionCollapsed, 46220 __unstableIsSelectionMergeable, 46221 __unstableGetSelectedBlocksWithPartialSelection, 46222 canInsertBlockType, 46223 getBlockRootClientId 46224 } = (0,external_wp_data_namespaceObject.useSelect)(store); 46225 const { 46226 flashBlock, 46227 removeBlocks, 46228 replaceBlocks, 46229 __unstableDeleteSelection, 46230 __unstableExpandSelection, 46231 __unstableSplitSelection 46232 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 46233 const notifyCopy = useNotifyCopy(); 46234 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 46235 function handler(event) { 46236 if (event.defaultPrevented) { 46237 // This was likely already handled in rich-text/use-paste-handler.js. 46238 return; 46239 } 46240 const selectedBlockClientIds = getSelectedBlockClientIds(); 46241 if (selectedBlockClientIds.length === 0) { 46242 return; 46243 } 46244 46245 // Let native copy/paste behaviour take over in input fields. 46246 // But always handle multiple selected blocks. 46247 if (!hasMultiSelection()) { 46248 const { 46249 target 46250 } = event; 46251 const { 46252 ownerDocument 46253 } = target; 46254 // If copying, only consider actual text selection as selection. 46255 // Otherwise, any focus on an input field is considered. 46256 const hasSelection = event.type === 'copy' || event.type === 'cut' ? (0,external_wp_dom_namespaceObject.documentHasUncollapsedSelection)(ownerDocument) : (0,external_wp_dom_namespaceObject.documentHasSelection)(ownerDocument) && !ownerDocument.activeElement.isContentEditable; 46257 46258 // Let native copy behaviour take over in input fields. 46259 if (hasSelection) { 46260 return; 46261 } 46262 } 46263 const { 46264 activeElement 46265 } = event.target.ownerDocument; 46266 if (!node.contains(activeElement)) { 46267 return; 46268 } 46269 const isSelectionMergeable = __unstableIsSelectionMergeable(); 46270 const shouldHandleWholeBlocks = __unstableIsSelectionCollapsed() || __unstableIsFullySelected(); 46271 const expandSelectionIsNeeded = !shouldHandleWholeBlocks && !isSelectionMergeable; 46272 if (event.type === 'copy' || event.type === 'cut') { 46273 event.preventDefault(); 46274 if (selectedBlockClientIds.length === 1) { 46275 flashBlock(selectedBlockClientIds[0]); 46276 } 46277 // If we have a partial selection that is not mergeable, just 46278 // expand the selection to the whole blocks. 46279 if (expandSelectionIsNeeded) { 46280 __unstableExpandSelection(); 46281 } else { 46282 notifyCopy(event.type, selectedBlockClientIds); 46283 let blocks; 46284 // Check if we have partial selection. 46285 if (shouldHandleWholeBlocks) { 46286 blocks = getBlocksByClientId(selectedBlockClientIds); 46287 } else { 46288 const [head, tail] = __unstableGetSelectedBlocksWithPartialSelection(); 46289 const inBetweenBlocks = getBlocksByClientId(selectedBlockClientIds.slice(1, selectedBlockClientIds.length - 1)); 46290 blocks = [head, ...inBetweenBlocks, tail]; 46291 } 46292 setClipboardBlocks(event, blocks, registry); 46293 } 46294 } 46295 if (event.type === 'cut') { 46296 // We need to also check if at the start we needed to 46297 // expand the selection, as in this point we might have 46298 // programmatically fully selected the blocks above. 46299 if (shouldHandleWholeBlocks && !expandSelectionIsNeeded) { 46300 removeBlocks(selectedBlockClientIds); 46301 } else { 46302 event.target.ownerDocument.activeElement.contentEditable = false; 46303 __unstableDeleteSelection(); 46304 } 46305 } else if (event.type === 'paste') { 46306 const { 46307 __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML 46308 } = getSettings(); 46309 const isInternal = event.clipboardData.getData('rich-text') === 'true'; 46310 if (isInternal) { 46311 return; 46312 } 46313 const { 46314 plainText, 46315 html, 46316 files 46317 } = getPasteEventData(event); 46318 const isFullySelected = __unstableIsFullySelected(); 46319 let blocks = []; 46320 if (files.length) { 46321 const fromTransforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from'); 46322 blocks = files.reduce((accumulator, file) => { 46323 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(fromTransforms, transform => transform.type === 'files' && transform.isMatch([file])); 46324 if (transformation) { 46325 accumulator.push(transformation.transform([file])); 46326 } 46327 return accumulator; 46328 }, []).flat(); 46329 } else { 46330 blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 46331 HTML: html, 46332 plainText, 46333 mode: isFullySelected ? 'BLOCKS' : 'AUTO', 46334 canUserUseUnfilteredHTML 46335 }); 46336 } 46337 46338 // Inline paste: let rich text handle it. 46339 if (typeof blocks === 'string') { 46340 return; 46341 } 46342 if (isFullySelected) { 46343 replaceBlocks(selectedBlockClientIds, blocks, blocks.length - 1, -1); 46344 event.preventDefault(); 46345 return; 46346 } 46347 46348 // If a block doesn't support splitting, let rich text paste 46349 // inline. 46350 if (!hasMultiSelection() && !(0,external_wp_blocks_namespaceObject.hasBlockSupport)(getBlockName(selectedBlockClientIds[0]), 'splitting', false) && !event.__deprecatedOnSplit) { 46351 return; 46352 } 46353 const [firstSelectedClientId] = selectedBlockClientIds; 46354 const rootClientId = getBlockRootClientId(firstSelectedClientId); 46355 const newBlocks = []; 46356 for (const block of blocks) { 46357 if (canInsertBlockType(block.name, rootClientId)) { 46358 newBlocks.push(block); 46359 } else { 46360 // If a block cannot be inserted in a root block, try 46361 // converting it to that root block type and insert the 46362 // inner blocks. 46363 // Example: paragraphs cannot be inserted into a list, 46364 // so convert the paragraphs to a list for list items. 46365 const rootBlockName = getBlockName(rootClientId); 46366 const switchedBlocks = block.name !== rootBlockName ? (0,external_wp_blocks_namespaceObject.switchToBlockType)(block, rootBlockName) : [block]; 46367 if (!switchedBlocks) { 46368 return; 46369 } 46370 for (const switchedBlock of switchedBlocks) { 46371 for (const innerBlock of switchedBlock.innerBlocks) { 46372 newBlocks.push(innerBlock); 46373 } 46374 } 46375 } 46376 } 46377 __unstableSplitSelection(newBlocks); 46378 event.preventDefault(); 46379 } 46380 } 46381 node.ownerDocument.addEventListener('copy', handler); 46382 node.ownerDocument.addEventListener('cut', handler); 46383 node.ownerDocument.addEventListener('paste', handler); 46384 return () => { 46385 node.ownerDocument.removeEventListener('copy', handler); 46386 node.ownerDocument.removeEventListener('cut', handler); 46387 node.ownerDocument.removeEventListener('paste', handler); 46388 }; 46389 }, []); 46390 } 46391 46392 ;// ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/index.js 46393 /** 46394 * External dependencies 46395 */ 46396 46397 46398 /** 46399 * WordPress dependencies 46400 */ 46401 46402 46403 46404 46405 46406 /** 46407 * Internal dependencies 46408 */ 46409 46410 46411 46412 46413 46414 46415 46416 46417 46418 46419 46420 function useWritingFlow() { 46421 const [before, ref, after] = useTabNav(); 46422 const hasMultiSelection = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).hasMultiSelection(), []); 46423 return [before, (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, useClipboardHandler(), useInput(), useDragSelection(), useSelectionObserver(), useClickSelection(), useMultiSelection(), useSelectAll(), useArrowNav(), (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 46424 node.tabIndex = 0; 46425 node.dataset.hasMultiSelection = hasMultiSelection; 46426 if (!hasMultiSelection) { 46427 return () => { 46428 delete node.dataset.hasMultiSelection; 46429 }; 46430 } 46431 node.setAttribute('aria-label', (0,external_wp_i18n_namespaceObject.__)('Multiple selected blocks')); 46432 return () => { 46433 delete node.dataset.hasMultiSelection; 46434 node.removeAttribute('aria-label'); 46435 }; 46436 }, [hasMultiSelection])]), after]; 46437 } 46438 function WritingFlow({ 46439 children, 46440 ...props 46441 }, forwardedRef) { 46442 const [before, ref, after] = useWritingFlow(); 46443 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 46444 children: [before, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 46445 ...props, 46446 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, forwardedRef]), 46447 className: dist_clsx(props.className, 'block-editor-writing-flow'), 46448 children: children 46449 }), after] 46450 }); 46451 } 46452 46453 /** 46454 * Handles selection and navigation across blocks. This component should be 46455 * wrapped around BlockList. 46456 * 46457 * @param {Object} props Component properties. 46458 * @param {Element} props.children Children to be rendered. 46459 */ 46460 /* harmony default export */ const writing_flow = ((0,external_wp_element_namespaceObject.forwardRef)(WritingFlow)); 46461 46462 ;// ./node_modules/@wordpress/block-editor/build-module/components/iframe/get-compatibility-styles.js 46463 let compatibilityStyles = null; 46464 46465 /** 46466 * Returns a list of stylesheets that target the editor canvas. A stylesheet is 46467 * considered targeting the editor a canvas if it contains the 46468 * `editor-styles-wrapper`, `wp-block`, or `wp-block-*` class selectors. 46469 * 46470 * Ideally, this hook should be removed in the future and styles should be added 46471 * explicitly as editor styles. 46472 */ 46473 function getCompatibilityStyles() { 46474 if (compatibilityStyles) { 46475 return compatibilityStyles; 46476 } 46477 46478 // Only memoize the result once on load, since these stylesheets should not 46479 // change. 46480 compatibilityStyles = Array.from(document.styleSheets).reduce((accumulator, styleSheet) => { 46481 try { 46482 // May fail for external styles. 46483 // eslint-disable-next-line no-unused-expressions 46484 styleSheet.cssRules; 46485 } catch (e) { 46486 return accumulator; 46487 } 46488 const { 46489 ownerNode, 46490 cssRules 46491 } = styleSheet; 46492 46493 // Stylesheet is added by another stylesheet. See 46494 // https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet/ownerNode#notes. 46495 if (ownerNode === null) { 46496 return accumulator; 46497 } 46498 if (!cssRules) { 46499 return accumulator; 46500 } 46501 46502 // Don't try to add core WP styles. We are responsible for adding 46503 // them. This compatibility layer is only meant to add styles added 46504 // by plugins or themes. 46505 if (ownerNode.id.startsWith('wp-')) { 46506 return accumulator; 46507 } 46508 46509 // Don't try to add styles without ID. Styles enqueued via the WP dependency system will always have IDs. 46510 if (!ownerNode.id) { 46511 return accumulator; 46512 } 46513 function matchFromRules(_cssRules) { 46514 return Array.from(_cssRules).find(({ 46515 selectorText, 46516 conditionText, 46517 cssRules: __cssRules 46518 }) => { 46519 // If the rule is conditional then it will not have selector text. 46520 // Recurse into child CSS ruleset to determine selector eligibility. 46521 if (conditionText) { 46522 return matchFromRules(__cssRules); 46523 } 46524 return selectorText && (selectorText.includes('.editor-styles-wrapper') || selectorText.includes('.wp-block')); 46525 }); 46526 } 46527 if (matchFromRules(cssRules)) { 46528 const isInline = ownerNode.tagName === 'STYLE'; 46529 if (isInline) { 46530 // If the current target is inline, 46531 // it could be a dependency of an existing stylesheet. 46532 // Look for that dependency and add it BEFORE the current target. 46533 const mainStylesCssId = ownerNode.id.replace('-inline-css', '-css'); 46534 const mainStylesElement = document.getElementById(mainStylesCssId); 46535 if (mainStylesElement) { 46536 accumulator.push(mainStylesElement.cloneNode(true)); 46537 } 46538 } 46539 accumulator.push(ownerNode.cloneNode(true)); 46540 if (!isInline) { 46541 // If the current target is not inline, 46542 // we still look for inline styles that could be relevant for the current target. 46543 // If they exist, add them AFTER the current target. 46544 const inlineStylesCssId = ownerNode.id.replace('-css', '-inline-css'); 46545 const inlineStylesElement = document.getElementById(inlineStylesCssId); 46546 if (inlineStylesElement) { 46547 accumulator.push(inlineStylesElement.cloneNode(true)); 46548 } 46549 } 46550 } 46551 return accumulator; 46552 }, []); 46553 return compatibilityStyles; 46554 } 46555 46556 ;// ./node_modules/@wordpress/block-editor/build-module/components/iframe/use-scale-canvas.js 46557 /** 46558 * WordPress dependencies 46559 */ 46560 46561 46562 46563 /** 46564 * @typedef {Object} TransitionState 46565 * @property {number} scaleValue Scale of the canvas. 46566 * @property {number} frameSize Size of the frame/offset around the canvas. 46567 * @property {number} containerHeight containerHeight of the iframe. 46568 * @property {number} scrollTop ScrollTop of the iframe. 46569 * @property {number} scrollHeight ScrollHeight of the iframe. 46570 */ 46571 46572 /** 46573 * Calculate the scale of the canvas. 46574 * 46575 * @param {Object} options Object of options 46576 * @param {number} options.frameSize Size of the frame/offset around the canvas 46577 * @param {number} options.containerWidth Actual width of the canvas container 46578 * @param {number} options.maxContainerWidth Maximum width of the container to use for the scale calculation. This locks the canvas to a maximum width when zooming out. 46579 * @param {number} options.scaleContainerWidth Width the of the container wrapping the canvas container 46580 * @return {number} Scale value between 0 and/or equal to 1 46581 */ 46582 function calculateScale({ 46583 frameSize, 46584 containerWidth, 46585 maxContainerWidth, 46586 scaleContainerWidth 46587 }) { 46588 return (Math.min(containerWidth, maxContainerWidth) - frameSize * 2) / scaleContainerWidth; 46589 } 46590 46591 /** 46592 * Compute the next scrollHeight based on the transition states. 46593 * 46594 * @param {TransitionState} transitionFrom Starting point of the transition 46595 * @param {TransitionState} transitionTo Ending state of the transition 46596 * @return {number} Next scrollHeight based on scale and frame value changes. 46597 */ 46598 function computeScrollHeightNext(transitionFrom, transitionTo) { 46599 const { 46600 scaleValue: prevScale, 46601 scrollHeight: prevScrollHeight 46602 } = transitionFrom; 46603 const { 46604 frameSize, 46605 scaleValue 46606 } = transitionTo; 46607 return prevScrollHeight * (scaleValue / prevScale) + frameSize * 2; 46608 } 46609 46610 /** 46611 * Compute the next scrollTop position after scaling the iframe content. 46612 * 46613 * @param {TransitionState} transitionFrom Starting point of the transition 46614 * @param {TransitionState} transitionTo Ending state of the transition 46615 * @return {number} Next scrollTop position after scaling the iframe content. 46616 */ 46617 function computeScrollTopNext(transitionFrom, transitionTo) { 46618 const { 46619 containerHeight: prevContainerHeight, 46620 frameSize: prevFrameSize, 46621 scaleValue: prevScale, 46622 scrollTop: prevScrollTop 46623 } = transitionFrom; 46624 const { 46625 containerHeight, 46626 frameSize, 46627 scaleValue, 46628 scrollHeight 46629 } = transitionTo; 46630 // Step 0: Start with the current scrollTop. 46631 let scrollTopNext = prevScrollTop; 46632 // Step 1: Undo the effects of the previous scale and frame around the 46633 // midpoint of the visible area. 46634 scrollTopNext = (scrollTopNext + prevContainerHeight / 2 - prevFrameSize) / prevScale - prevContainerHeight / 2; 46635 46636 // Step 2: Apply the new scale and frame around the midpoint of the 46637 // visible area. 46638 scrollTopNext = (scrollTopNext + containerHeight / 2) * scaleValue + frameSize - containerHeight / 2; 46639 46640 // Step 3: Handle an edge case so that you scroll to the top of the 46641 // iframe if the top of the iframe content is visible in the container. 46642 // The same edge case for the bottom is skipped because changing content 46643 // makes calculating it impossible. 46644 scrollTopNext = prevScrollTop <= prevFrameSize ? 0 : scrollTopNext; 46645 46646 // This is the scrollTop value if you are scrolled to the bottom of the 46647 // iframe. We can't just let the browser handle it because we need to 46648 // animate the scaling. 46649 const maxScrollTop = scrollHeight - containerHeight; 46650 46651 // Step 4: Clamp the scrollTopNext between the minimum and maximum 46652 // possible scrollTop positions. Round the value to avoid subpixel 46653 // truncation by the browser which sometimes causes a 1px error. 46654 return Math.round(Math.min(Math.max(0, scrollTopNext), Math.max(0, maxScrollTop))); 46655 } 46656 46657 /** 46658 * Generate the keyframes to use for the zoom out animation. 46659 * 46660 * @param {TransitionState} transitionFrom Starting transition state. 46661 * @param {TransitionState} transitionTo Ending transition state. 46662 * @return {Object[]} An array of keyframes to use for the animation. 46663 */ 46664 function getAnimationKeyframes(transitionFrom, transitionTo) { 46665 const { 46666 scaleValue: prevScale, 46667 frameSize: prevFrameSize, 46668 scrollTop 46669 } = transitionFrom; 46670 const { 46671 scaleValue, 46672 frameSize, 46673 scrollTop: scrollTopNext 46674 } = transitionTo; 46675 return [{ 46676 translate: `0 0`, 46677 scale: prevScale, 46678 paddingTop: `$prevFrameSize / prevScale}px`, 46679 paddingBottom: `$prevFrameSize / prevScale}px` 46680 }, { 46681 translate: `0 $scrollTop - scrollTopNext}px`, 46682 scale: scaleValue, 46683 paddingTop: `$frameSize / scaleValue}px`, 46684 paddingBottom: `$frameSize / scaleValue}px` 46685 }]; 46686 } 46687 46688 /** 46689 * @typedef {Object} ScaleCanvasResult 46690 * @property {boolean} isZoomedOut A boolean indicating if the canvas is zoomed out. 46691 * @property {number} scaleContainerWidth The width of the container used to calculate the scale. 46692 * @property {Object} contentResizeListener A resize observer for the content. 46693 * @property {Object} containerResizeListener A resize observer for the container. 46694 */ 46695 46696 /** 46697 * Handles scaling the canvas for the zoom out mode and animating between 46698 * the states. 46699 * 46700 * @param {Object} options Object of options. 46701 * @param {number} options.frameSize Size of the frame around the content. 46702 * @param {Document} options.iframeDocument Document of the iframe. 46703 * @param {number} options.maxContainerWidth Max width of the canvas to use as the starting scale point. Defaults to 750. 46704 * @param {number|string} options.scale Scale of the canvas. Can be an decimal between 0 and 1, 1, or 'auto-scaled'. 46705 * @return {ScaleCanvasResult} Properties of the result. 46706 */ 46707 function useScaleCanvas({ 46708 frameSize, 46709 iframeDocument, 46710 maxContainerWidth = 750, 46711 scale 46712 }) { 46713 const [contentResizeListener, { 46714 height: contentHeight 46715 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 46716 const [containerResizeListener, { 46717 width: containerWidth, 46718 height: containerHeight 46719 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 46720 const initialContainerWidthRef = (0,external_wp_element_namespaceObject.useRef)(0); 46721 const isZoomedOut = scale !== 1; 46722 const prefersReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 46723 const isAutoScaled = scale === 'auto-scaled'; 46724 // Track if the animation should start when the useEffect runs. 46725 const startAnimationRef = (0,external_wp_element_namespaceObject.useRef)(false); 46726 // Track the animation so we know if we have an animation running, 46727 // and can cancel it, reverse it, call a finish event, etc. 46728 const animationRef = (0,external_wp_element_namespaceObject.useRef)(null); 46729 (0,external_wp_element_namespaceObject.useEffect)(() => { 46730 if (!isZoomedOut) { 46731 initialContainerWidthRef.current = containerWidth; 46732 } 46733 }, [containerWidth, isZoomedOut]); 46734 const scaleContainerWidth = Math.max(initialContainerWidthRef.current, containerWidth); 46735 const scaleValue = isAutoScaled ? calculateScale({ 46736 frameSize, 46737 containerWidth, 46738 maxContainerWidth, 46739 scaleContainerWidth 46740 }) : scale; 46741 46742 /** 46743 * The starting transition state for the zoom out animation. 46744 * @type {import('react').RefObject<TransitionState>} 46745 */ 46746 const transitionFromRef = (0,external_wp_element_namespaceObject.useRef)({ 46747 scaleValue, 46748 frameSize, 46749 containerHeight: 0, 46750 scrollTop: 0, 46751 scrollHeight: 0 46752 }); 46753 46754 /** 46755 * The ending transition state for the zoom out animation. 46756 * @type {import('react').RefObject<TransitionState>} 46757 */ 46758 const transitionToRef = (0,external_wp_element_namespaceObject.useRef)({ 46759 scaleValue, 46760 frameSize, 46761 containerHeight: 0, 46762 scrollTop: 0, 46763 scrollHeight: 0 46764 }); 46765 46766 /** 46767 * Start the zoom out animation. This sets the necessary CSS variables 46768 * for animating the canvas and returns the Animation object. 46769 * 46770 * @return {Animation} The animation object for the zoom out animation. 46771 */ 46772 const startZoomOutAnimation = (0,external_wp_element_namespaceObject.useCallback)(() => { 46773 const { 46774 scrollTop 46775 } = transitionFromRef.current; 46776 const { 46777 scrollTop: scrollTopNext 46778 } = transitionToRef.current; 46779 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-scroll-top', `$scrollTop}px`); 46780 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-scroll-top-next', `$scrollTopNext}px`); 46781 46782 // If the container has a scrolllbar, force a scrollbar to prevent the content from shifting while animating. 46783 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-overflow-behavior', transitionFromRef.current.scrollHeight === transitionFromRef.current.containerHeight ? 'auto' : 'scroll'); 46784 iframeDocument.documentElement.classList.add('zoom-out-animation'); 46785 return iframeDocument.documentElement.animate(getAnimationKeyframes(transitionFromRef.current, transitionToRef.current), { 46786 easing: 'cubic-bezier(0.46, 0.03, 0.52, 0.96)', 46787 duration: 400 46788 }); 46789 }, [iframeDocument]); 46790 46791 /** 46792 * Callback when the zoom out animation is finished. 46793 * - Cleans up animations refs. 46794 * - Adds final CSS vars for scale and frame size to preserve the state. 46795 * - Removes the 'zoom-out-animation' class (which has the fixed positioning). 46796 * - Sets the final scroll position after the canvas is no longer in fixed position. 46797 * - Removes CSS vars related to the animation. 46798 * - Sets the transitionFrom to the transitionTo state to be ready for the next animation. 46799 */ 46800 const finishZoomOutAnimation = (0,external_wp_element_namespaceObject.useCallback)(() => { 46801 startAnimationRef.current = false; 46802 animationRef.current = null; 46803 46804 // Add our final scale and frame size now that the animation is done. 46805 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-scale', transitionToRef.current.scaleValue); 46806 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-frame-size', `$transitionToRef.current.frameSize}px`); 46807 iframeDocument.documentElement.classList.remove('zoom-out-animation'); 46808 46809 // Set the final scroll position that was just animated to. 46810 // Disable reason: Eslint isn't smart enough to know that this is a 46811 // DOM element. https://github.com/facebook/react/issues/31483 46812 // eslint-disable-next-line react-compiler/react-compiler 46813 iframeDocument.documentElement.scrollTop = transitionToRef.current.scrollTop; 46814 iframeDocument.documentElement.style.removeProperty('--wp-block-editor-iframe-zoom-out-scroll-top'); 46815 iframeDocument.documentElement.style.removeProperty('--wp-block-editor-iframe-zoom-out-scroll-top-next'); 46816 iframeDocument.documentElement.style.removeProperty('--wp-block-editor-iframe-zoom-out-overflow-behavior'); 46817 46818 // Update previous values. 46819 transitionFromRef.current = transitionToRef.current; 46820 }, [iframeDocument]); 46821 const previousIsZoomedOut = (0,external_wp_element_namespaceObject.useRef)(false); 46822 46823 /** 46824 * Runs when zoom out mode is toggled, and sets the startAnimation flag 46825 * so the animation will start when the next useEffect runs. We _only_ 46826 * want to animate when the zoom out mode is toggled, not when the scale 46827 * changes due to the container resizing. 46828 */ 46829 (0,external_wp_element_namespaceObject.useEffect)(() => { 46830 const trigger = iframeDocument && previousIsZoomedOut.current !== isZoomedOut; 46831 previousIsZoomedOut.current = isZoomedOut; 46832 if (!trigger) { 46833 return; 46834 } 46835 startAnimationRef.current = true; 46836 if (!isZoomedOut) { 46837 return; 46838 } 46839 iframeDocument.documentElement.classList.add('is-zoomed-out'); 46840 return () => { 46841 iframeDocument.documentElement.classList.remove('is-zoomed-out'); 46842 }; 46843 }, [iframeDocument, isZoomedOut]); 46844 46845 /** 46846 * This handles: 46847 * 1. Setting the correct scale and vars of the canvas when zoomed out 46848 * 2. If zoom out mode has been toggled, runs the animation of zooming in/out 46849 */ 46850 (0,external_wp_element_namespaceObject.useEffect)(() => { 46851 if (!iframeDocument) { 46852 return; 46853 } 46854 46855 // We need to update the appropriate scale to exit from. If sidebars have been opened since setting the 46856 // original scale, we will snap to a much smaller scale due to the scale container immediately changing sizes when exiting. 46857 if (isAutoScaled && transitionFromRef.current.scaleValue !== 1) { 46858 // We use containerWidth as the divisor, as scaleContainerWidth will always match the containerWidth when 46859 // exiting. 46860 transitionFromRef.current.scaleValue = calculateScale({ 46861 frameSize: transitionFromRef.current.frameSize, 46862 containerWidth, 46863 maxContainerWidth, 46864 scaleContainerWidth: containerWidth 46865 }); 46866 } 46867 if (scaleValue < 1) { 46868 // If we are not going to animate the transition, set the scale and frame size directly. 46869 // If we are animating, these values will be set when the animation is finished. 46870 // Example: Opening sidebars that reduce the scale of the canvas, but we don't want to 46871 // animate the transition. 46872 if (!startAnimationRef.current) { 46873 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-scale', scaleValue); 46874 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-frame-size', `$frameSize}px`); 46875 } 46876 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-content-height', `$contentHeight}px`); 46877 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-inner-height', `$containerHeight}px`); 46878 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-container-width', `$containerWidth}px`); 46879 iframeDocument.documentElement.style.setProperty('--wp-block-editor-iframe-zoom-out-scale-container-width', `$scaleContainerWidth}px`); 46880 } 46881 46882 /** 46883 * Handle the zoom out animation: 46884 * 46885 * - Get the current scrollTop position. 46886 * - Calculate where the same scroll position is after scaling. 46887 * - Apply fixed positioning to the canvas with a transform offset 46888 * to keep the canvas centered. 46889 * - Animate the scale and padding to the new scale and frame size. 46890 * - After the animation is complete, remove the fixed positioning 46891 * and set the scroll position that keeps everything centered. 46892 */ 46893 if (startAnimationRef.current) { 46894 // Don't allow a new transition to start again unless it was started by the zoom out mode changing. 46895 startAnimationRef.current = false; 46896 46897 /** 46898 * If we already have an animation running, reverse it. 46899 */ 46900 if (animationRef.current) { 46901 animationRef.current.reverse(); 46902 // Swap the transition to/from refs so that we set the correct values when 46903 // finishZoomOutAnimation runs. 46904 const tempTransitionFrom = transitionFromRef.current; 46905 const tempTransitionTo = transitionToRef.current; 46906 transitionFromRef.current = tempTransitionTo; 46907 transitionToRef.current = tempTransitionFrom; 46908 } else { 46909 /** 46910 * Start a new zoom animation. 46911 */ 46912 46913 // We can't trust the set value from contentHeight, as it was measured 46914 // before the zoom out mode was changed. After zoom out mode is changed, 46915 // appenders may appear or disappear, so we need to get the height from 46916 // the iframe at this point when we're about to animate the zoom out. 46917 // The iframe scrollTop, scrollHeight, and clientHeight will all be 46918 // the most accurate. 46919 transitionFromRef.current.scrollTop = iframeDocument.documentElement.scrollTop; 46920 transitionFromRef.current.scrollHeight = iframeDocument.documentElement.scrollHeight; 46921 // Use containerHeight, as it's the previous container height before the zoom out animation starts. 46922 transitionFromRef.current.containerHeight = containerHeight; 46923 transitionToRef.current = { 46924 scaleValue, 46925 frameSize, 46926 containerHeight: iframeDocument.documentElement.clientHeight // use clientHeight to get the actual height of the new container after zoom state changes have rendered, as it will be the most up-to-date. 46927 }; 46928 transitionToRef.current.scrollHeight = computeScrollHeightNext(transitionFromRef.current, transitionToRef.current); 46929 transitionToRef.current.scrollTop = computeScrollTopNext(transitionFromRef.current, transitionToRef.current); 46930 animationRef.current = startZoomOutAnimation(); 46931 46932 // If the user prefers reduced motion, finish the animation immediately and set the final state. 46933 if (prefersReducedMotion) { 46934 finishZoomOutAnimation(); 46935 } else { 46936 animationRef.current.onfinish = finishZoomOutAnimation; 46937 } 46938 } 46939 } 46940 }, [startZoomOutAnimation, finishZoomOutAnimation, prefersReducedMotion, isAutoScaled, scaleValue, frameSize, iframeDocument, contentHeight, containerWidth, containerHeight, maxContainerWidth, scaleContainerWidth]); 46941 return { 46942 isZoomedOut, 46943 scaleContainerWidth, 46944 contentResizeListener, 46945 containerResizeListener 46946 }; 46947 } 46948 46949 ;// ./node_modules/@wordpress/block-editor/build-module/components/iframe/index.js 46950 /* wp:polyfill */ 46951 /** 46952 * External dependencies 46953 */ 46954 46955 46956 /** 46957 * WordPress dependencies 46958 */ 46959 46960 46961 46962 46963 46964 46965 /** 46966 * Internal dependencies 46967 */ 46968 46969 46970 46971 46972 46973 46974 function bubbleEvent(event, Constructor, frame) { 46975 const init = {}; 46976 for (const key in event) { 46977 init[key] = event[key]; 46978 } 46979 46980 // Check if the event is a MouseEvent generated within the iframe. 46981 // If so, adjust the coordinates to be relative to the position of 46982 // the iframe. This ensures that components such as Draggable 46983 // receive coordinates relative to the window, instead of relative 46984 // to the iframe. Without this, the Draggable event handler would 46985 // result in components "jumping" position as soon as the user 46986 // drags over the iframe. 46987 if (event instanceof frame.contentDocument.defaultView.MouseEvent) { 46988 const rect = frame.getBoundingClientRect(); 46989 init.clientX += rect.left; 46990 init.clientY += rect.top; 46991 } 46992 const newEvent = new Constructor(event.type, init); 46993 if (init.defaultPrevented) { 46994 newEvent.preventDefault(); 46995 } 46996 const cancelled = !frame.dispatchEvent(newEvent); 46997 if (cancelled) { 46998 event.preventDefault(); 46999 } 47000 } 47001 47002 /** 47003 * Bubbles some event types (keydown, keypress, and dragover) to parent document 47004 * document to ensure that the keyboard shortcuts and drag and drop work. 47005 * 47006 * Ideally, we should remove event bubbling in the future. Keyboard shortcuts 47007 * should be context dependent, e.g. actions on blocks like Cmd+A should not 47008 * work globally outside the block editor. 47009 * 47010 * @param {Document} iframeDocument Document to attach listeners to. 47011 */ 47012 function useBubbleEvents(iframeDocument) { 47013 return (0,external_wp_compose_namespaceObject.useRefEffect)(() => { 47014 const { 47015 defaultView 47016 } = iframeDocument; 47017 if (!defaultView) { 47018 return; 47019 } 47020 const { 47021 frameElement 47022 } = defaultView; 47023 const html = iframeDocument.documentElement; 47024 const eventTypes = ['dragover', 'mousemove']; 47025 const handlers = {}; 47026 for (const name of eventTypes) { 47027 handlers[name] = event => { 47028 const prototype = Object.getPrototypeOf(event); 47029 const constructorName = prototype.constructor.name; 47030 const Constructor = window[constructorName]; 47031 bubbleEvent(event, Constructor, frameElement); 47032 }; 47033 html.addEventListener(name, handlers[name]); 47034 } 47035 return () => { 47036 for (const name of eventTypes) { 47037 html.removeEventListener(name, handlers[name]); 47038 } 47039 }; 47040 }); 47041 } 47042 function Iframe({ 47043 contentRef, 47044 children, 47045 tabIndex = 0, 47046 scale = 1, 47047 frameSize = 0, 47048 readonly, 47049 forwardedRef: ref, 47050 title = (0,external_wp_i18n_namespaceObject.__)('Editor canvas'), 47051 ...props 47052 }) { 47053 const { 47054 resolvedAssets, 47055 isPreviewMode 47056 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 47057 const { 47058 getSettings 47059 } = select(store); 47060 const settings = getSettings(); 47061 return { 47062 resolvedAssets: settings.__unstableResolvedAssets, 47063 isPreviewMode: settings.isPreviewMode 47064 }; 47065 }, []); 47066 const { 47067 styles = '', 47068 scripts = '' 47069 } = resolvedAssets; 47070 /** @type {[Document, import('react').Dispatch<Document>]} */ 47071 const [iframeDocument, setIframeDocument] = (0,external_wp_element_namespaceObject.useState)(); 47072 const [bodyClasses, setBodyClasses] = (0,external_wp_element_namespaceObject.useState)([]); 47073 const clearerRef = useBlockSelectionClearer(); 47074 const [before, writingFlowRef, after] = useWritingFlow(); 47075 const setRef = (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 47076 node._load = () => { 47077 setIframeDocument(node.contentDocument); 47078 }; 47079 let iFrameDocument; 47080 // Prevent the default browser action for files dropped outside of dropzones. 47081 function preventFileDropDefault(event) { 47082 event.preventDefault(); 47083 } 47084 const { 47085 ownerDocument 47086 } = node; 47087 47088 // Ideally ALL classes that are added through get_body_class should 47089 // be added in the editor too, which we'll somehow have to get from 47090 // the server in the future (which will run the PHP filters). 47091 setBodyClasses(Array.from(ownerDocument.body.classList).filter(name => name.startsWith('admin-color-') || name.startsWith('post-type-') || name === 'wp-embed-responsive')); 47092 function onLoad() { 47093 const { 47094 contentDocument 47095 } = node; 47096 const { 47097 documentElement 47098 } = contentDocument; 47099 iFrameDocument = contentDocument; 47100 documentElement.classList.add('block-editor-iframe__html'); 47101 clearerRef(documentElement); 47102 contentDocument.dir = ownerDocument.dir; 47103 for (const compatStyle of getCompatibilityStyles()) { 47104 if (contentDocument.getElementById(compatStyle.id)) { 47105 continue; 47106 } 47107 contentDocument.head.appendChild(compatStyle.cloneNode(true)); 47108 if (!isPreviewMode) { 47109 // eslint-disable-next-line no-console 47110 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); 47111 } 47112 } 47113 iFrameDocument.addEventListener('dragover', preventFileDropDefault, false); 47114 iFrameDocument.addEventListener('drop', preventFileDropDefault, false); 47115 // Prevent clicks on links from navigating away. Note that links 47116 // inside `contenteditable` are already disabled by the browser, so 47117 // this is for links in blocks outside of `contenteditable`. 47118 iFrameDocument.addEventListener('click', event => { 47119 if (event.target.tagName === 'A') { 47120 event.preventDefault(); 47121 47122 // Appending a hash to the current URL will not reload the 47123 // page. This is useful for e.g. footnotes. 47124 const href = event.target.getAttribute('href'); 47125 if (href?.startsWith('#')) { 47126 iFrameDocument.defaultView.location.hash = href.slice(1); 47127 } 47128 } 47129 }); 47130 } 47131 node.addEventListener('load', onLoad); 47132 return () => { 47133 delete node._load; 47134 node.removeEventListener('load', onLoad); 47135 iFrameDocument?.removeEventListener('dragover', preventFileDropDefault); 47136 iFrameDocument?.removeEventListener('drop', preventFileDropDefault); 47137 }; 47138 }, []); 47139 const { 47140 contentResizeListener, 47141 containerResizeListener, 47142 isZoomedOut, 47143 scaleContainerWidth 47144 } = useScaleCanvas({ 47145 scale, 47146 frameSize: parseInt(frameSize), 47147 iframeDocument 47148 }); 47149 const disabledRef = (0,external_wp_compose_namespaceObject.useDisabled)({ 47150 isDisabled: !readonly 47151 }); 47152 const bodyRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([useBubbleEvents(iframeDocument), contentRef, clearerRef, writingFlowRef, disabledRef]); 47153 47154 // Correct doctype is required to enable rendering in standards 47155 // mode. Also preload the styles to avoid a flash of unstyled 47156 // content. 47157 const html = `<!doctype html> 47158 <html> 47159 <head> 47160 <meta charset="utf-8"> 47161 <base href="$window.location.origin}"> 47162 <script>window.frameElement._load()</script> 47163 <style> 47164 html{ 47165 height: auto !important; 47166 min-height: 100%; 47167 } 47168 /* Lowest specificity to not override global styles */ 47169 :where(body) { 47170 margin: 0; 47171 /* Default background color in case zoom out mode background 47172 colors the html element */ 47173 background-color: white; 47174 } 47175 </style> 47176 $styles} 47177 $scripts} 47178 </head> 47179 <body> 47180 <script>document.currentScript.parentElement.remove()</script> 47181 </body> 47182 </html>`; 47183 const [src, cleanup] = (0,external_wp_element_namespaceObject.useMemo)(() => { 47184 const _src = URL.createObjectURL(new window.Blob([html], { 47185 type: 'text/html' 47186 })); 47187 return [_src, () => URL.revokeObjectURL(_src)]; 47188 }, [html]); 47189 (0,external_wp_element_namespaceObject.useEffect)(() => cleanup, [cleanup]); 47190 47191 // Make sure to not render the before and after focusable div elements in view 47192 // mode. They're only needed to capture focus in edit mode. 47193 const shouldRenderFocusCaptureElements = tabIndex >= 0 && !isPreviewMode; 47194 const iframe = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 47195 children: [shouldRenderFocusCaptureElements && before, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("iframe", { 47196 ...props, 47197 style: { 47198 ...props.style, 47199 height: props.style?.height, 47200 border: 0 47201 }, 47202 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, setRef]), 47203 tabIndex: tabIndex 47204 // Correct doctype is required to enable rendering in standards 47205 // mode. Also preload the styles to avoid a flash of unstyled 47206 // content. 47207 , 47208 src: src, 47209 title: title, 47210 onKeyDown: event => { 47211 if (props.onKeyDown) { 47212 props.onKeyDown(event); 47213 } 47214 // If the event originates from inside the iframe, it means 47215 // it bubbled through the portal, but only with React 47216 // events. We need to to bubble native events as well, 47217 // though by doing so we also trigger another React event, 47218 // so we need to stop the propagation of this event to avoid 47219 // duplication. 47220 if (event.currentTarget.ownerDocument !== event.target.ownerDocument) { 47221 // We should only stop propagation of the React event, 47222 // the native event should further bubble inside the 47223 // iframe to the document and window. 47224 // Alternatively, we could consider redispatching the 47225 // native event in the iframe. 47226 const { 47227 stopPropagation 47228 } = event.nativeEvent; 47229 event.nativeEvent.stopPropagation = () => {}; 47230 event.stopPropagation(); 47231 event.nativeEvent.stopPropagation = stopPropagation; 47232 bubbleEvent(event, window.KeyboardEvent, event.currentTarget); 47233 } 47234 }, 47235 children: iframeDocument && (0,external_wp_element_namespaceObject.createPortal)( 47236 /*#__PURE__*/ 47237 // We want to prevent React events from bubbling through the iframe 47238 // we bubble these manually. 47239 /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ 47240 (0,external_ReactJSXRuntime_namespaceObject.jsxs)("body", { 47241 ref: bodyRef, 47242 className: dist_clsx('block-editor-iframe__body', 'editor-styles-wrapper', ...bodyClasses), 47243 children: [contentResizeListener, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 47244 document: iframeDocument, 47245 children: children 47246 })] 47247 }), iframeDocument.documentElement) 47248 }), shouldRenderFocusCaptureElements && after] 47249 }); 47250 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 47251 className: "block-editor-iframe__container", 47252 children: [containerResizeListener, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 47253 className: dist_clsx('block-editor-iframe__scale-container', isZoomedOut && 'is-zoomed-out'), 47254 style: { 47255 '--wp-block-editor-iframe-zoom-out-scale-container-width': isZoomedOut && `$scaleContainerWidth}px` 47256 }, 47257 children: iframe 47258 })] 47259 }); 47260 } 47261 function IframeIfReady(props, ref) { 47262 const isInitialised = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().__internalIsInitialized, []); 47263 47264 // We shouldn't render the iframe until the editor settings are initialised. 47265 // The initial settings are needed to get the styles for the srcDoc, which 47266 // cannot be changed after the iframe is mounted. srcDoc is used to to set 47267 // the initial iframe HTML, which is required to avoid a flash of unstyled 47268 // content. 47269 if (!isInitialised) { 47270 return null; 47271 } 47272 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Iframe, { 47273 ...props, 47274 forwardedRef: ref 47275 }); 47276 } 47277 /* harmony default export */ const iframe = ((0,external_wp_element_namespaceObject.forwardRef)(IframeIfReady)); 47278 47279 ;// ./node_modules/parsel-js/dist/parsel.js 47280 const TOKENS = { 47281 attribute: /\[\s*(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?(?<name>[-\w\P{ASCII}]+)\s*(?:(?<operator>\W?=)\s*(?<value>.+?)\s*(\s(?<caseSensitive>[iIsS]))?\s*)?\]/gu, 47282 id: /#(?<name>[-\w\P{ASCII}]+)/gu, 47283 class: /\.(?<name>[-\w\P{ASCII}]+)/gu, 47284 comma: /\s*,\s*/g, 47285 combinator: /\s*[\s>+~]\s*/g, 47286 'pseudo-element': /::(?<name>[-\w\P{ASCII}]+)(?:\((?<argument>¶*)\))?/gu, 47287 'pseudo-class': /:(?<name>[-\w\P{ASCII}]+)(?:\((?<argument>¶*)\))?/gu, 47288 universal: /(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?\*/gu, 47289 type: /(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?(?<name>[-\w\P{ASCII}]+)/gu, // this must be last 47290 }; 47291 const TRIM_TOKENS = new Set(['combinator', 'comma']); 47292 const RECURSIVE_PSEUDO_CLASSES = new Set([ 47293 'not', 47294 'is', 47295 'where', 47296 'has', 47297 'matches', 47298 '-moz-any', 47299 '-webkit-any', 47300 'nth-child', 47301 'nth-last-child', 47302 ]); 47303 const nthChildRegExp = /(?<index>[\dn+-]+)\s+of\s+(?<subtree>.+)/; 47304 const RECURSIVE_PSEUDO_CLASSES_ARGS = { 47305 'nth-child': nthChildRegExp, 47306 'nth-last-child': nthChildRegExp, 47307 }; 47308 const getArgumentPatternByType = (type) => { 47309 switch (type) { 47310 case 'pseudo-element': 47311 case 'pseudo-class': 47312 return new RegExp(TOKENS[type].source.replace('(?<argument>¶*)', '(?<argument>.*)'), 'gu'); 47313 default: 47314 return TOKENS[type]; 47315 } 47316 }; 47317 function gobbleParens(text, offset) { 47318 let nesting = 0; 47319 let result = ''; 47320 for (; offset < text.length; offset++) { 47321 const char = text[offset]; 47322 switch (char) { 47323 case '(': 47324 ++nesting; 47325 break; 47326 case ')': 47327 --nesting; 47328 break; 47329 } 47330 result += char; 47331 if (nesting === 0) { 47332 return result; 47333 } 47334 } 47335 return result; 47336 } 47337 function tokenizeBy(text, grammar = TOKENS) { 47338 if (!text) { 47339 return []; 47340 } 47341 const tokens = [text]; 47342 for (const [type, pattern] of Object.entries(grammar)) { 47343 for (let i = 0; i < tokens.length; i++) { 47344 const token = tokens[i]; 47345 if (typeof token !== 'string') { 47346 continue; 47347 } 47348 pattern.lastIndex = 0; 47349 const match = pattern.exec(token); 47350 if (!match) { 47351 continue; 47352 } 47353 const from = match.index - 1; 47354 const args = []; 47355 const content = match[0]; 47356 const before = token.slice(0, from + 1); 47357 if (before) { 47358 args.push(before); 47359 } 47360 args.push({ 47361 ...match.groups, 47362 type, 47363 content, 47364 }); 47365 const after = token.slice(from + content.length + 1); 47366 if (after) { 47367 args.push(after); 47368 } 47369 tokens.splice(i, 1, ...args); 47370 } 47371 } 47372 let offset = 0; 47373 for (const token of tokens) { 47374 switch (typeof token) { 47375 case 'string': 47376 throw new Error(`Unexpected sequence $token} found at index $offset}`); 47377 case 'object': 47378 offset += token.content.length; 47379 token.pos = [offset - token.content.length, offset]; 47380 if (TRIM_TOKENS.has(token.type)) { 47381 token.content = token.content.trim() || ' '; 47382 } 47383 break; 47384 } 47385 } 47386 return tokens; 47387 } 47388 const STRING_PATTERN = /(['"])([^\\\n]+?)\1/g; 47389 const ESCAPE_PATTERN = /\\./g; 47390 function parsel_tokenize(selector, grammar = TOKENS) { 47391 // Prevent leading/trailing whitespaces from being interpreted as combinators 47392 selector = selector.trim(); 47393 if (selector === '') { 47394 return []; 47395 } 47396 const replacements = []; 47397 // Replace escapes with placeholders. 47398 selector = selector.replace(ESCAPE_PATTERN, (value, offset) => { 47399 replacements.push({ value, offset }); 47400 return '\uE000'.repeat(value.length); 47401 }); 47402 // Replace strings with placeholders. 47403 selector = selector.replace(STRING_PATTERN, (value, quote, content, offset) => { 47404 replacements.push({ value, offset }); 47405 return `$quote}${'\uE001'.repeat(content.length)}$quote}`; 47406 }); 47407 // Replace parentheses with placeholders. 47408 { 47409 let pos = 0; 47410 let offset; 47411 while ((offset = selector.indexOf('(', pos)) > -1) { 47412 const value = gobbleParens(selector, offset); 47413 replacements.push({ value, offset }); 47414 selector = `$selector.substring(0, offset)}(${'¶'.repeat(value.length - 2)})$selector.substring(offset + value.length)}`; 47415 pos = offset + value.length; 47416 } 47417 } 47418 // Now we have no nested structures and we can parse with regexes 47419 const tokens = tokenizeBy(selector, grammar); 47420 // Replace placeholders in reverse order. 47421 const changedTokens = new Set(); 47422 for (const replacement of replacements.reverse()) { 47423 for (const token of tokens) { 47424 const { offset, value } = replacement; 47425 if (!(token.pos[0] <= offset && 47426 offset + value.length <= token.pos[1])) { 47427 continue; 47428 } 47429 const { content } = token; 47430 const tokenOffset = offset - token.pos[0]; 47431 token.content = 47432 content.slice(0, tokenOffset) + 47433 value + 47434 content.slice(tokenOffset + value.length); 47435 if (token.content !== content) { 47436 changedTokens.add(token); 47437 } 47438 } 47439 } 47440 // Update changed tokens. 47441 for (const token of changedTokens) { 47442 const pattern = getArgumentPatternByType(token.type); 47443 if (!pattern) { 47444 throw new Error(`Unknown token type: $token.type}`); 47445 } 47446 pattern.lastIndex = 0; 47447 const match = pattern.exec(token.content); 47448 if (!match) { 47449 throw new Error(`Unable to parse content for $token.type}: $token.content}`); 47450 } 47451 Object.assign(token, match.groups); 47452 } 47453 return tokens; 47454 } 47455 /** 47456 * Convert a flat list of tokens into a tree of complex & compound selectors 47457 */ 47458 function nestTokens(tokens, { list = true } = {}) { 47459 if (list && tokens.find((t) => t.type === 'comma')) { 47460 const selectors = []; 47461 const temp = []; 47462 for (let i = 0; i < tokens.length; i++) { 47463 if (tokens[i].type === 'comma') { 47464 if (temp.length === 0) { 47465 throw new Error('Incorrect comma at ' + i); 47466 } 47467 selectors.push(nestTokens(temp, { list: false })); 47468 temp.length = 0; 47469 } 47470 else { 47471 temp.push(tokens[i]); 47472 } 47473 } 47474 if (temp.length === 0) { 47475 throw new Error('Trailing comma'); 47476 } 47477 else { 47478 selectors.push(nestTokens(temp, { list: false })); 47479 } 47480 return { type: 'list', list: selectors }; 47481 } 47482 for (let i = tokens.length - 1; i >= 0; i--) { 47483 let token = tokens[i]; 47484 if (token.type === 'combinator') { 47485 let left = tokens.slice(0, i); 47486 let right = tokens.slice(i + 1); 47487 return { 47488 type: 'complex', 47489 combinator: token.content, 47490 left: nestTokens(left), 47491 right: nestTokens(right), 47492 }; 47493 } 47494 } 47495 switch (tokens.length) { 47496 case 0: 47497 throw new Error('Could not build AST.'); 47498 case 1: 47499 // If we're here, there are no combinators, so it's just a list. 47500 return tokens[0]; 47501 default: 47502 return { 47503 type: 'compound', 47504 list: [...tokens], // clone to avoid pointers messing up the AST 47505 }; 47506 } 47507 } 47508 /** 47509 * Traverse an AST in depth-first order 47510 */ 47511 function* flatten(node, 47512 /** 47513 * @internal 47514 */ 47515 parent) { 47516 switch (node.type) { 47517 case 'list': 47518 for (let child of node.list) { 47519 yield* flatten(child, node); 47520 } 47521 break; 47522 case 'complex': 47523 yield* flatten(node.left, node); 47524 yield* flatten(node.right, node); 47525 break; 47526 case 'compound': 47527 yield* node.list.map((token) => [token, node]); 47528 break; 47529 default: 47530 yield [node, parent]; 47531 } 47532 } 47533 /** 47534 * Traverse an AST (or part thereof), in depth-first order 47535 */ 47536 function walk(node, visit, 47537 /** 47538 * @internal 47539 */ 47540 parent) { 47541 if (!node) { 47542 return; 47543 } 47544 for (const [token, ast] of flatten(node, parent)) { 47545 visit(token, ast); 47546 } 47547 } 47548 /** 47549 * Parse a CSS selector 47550 * 47551 * @param selector - The selector to parse 47552 * @param options.recursive - Whether to parse the arguments of pseudo-classes like :is(), :has() etc. Defaults to true. 47553 * @param options.list - Whether this can be a selector list (A, B, C etc). Defaults to true. 47554 */ 47555 function parse(selector, { recursive = true, list = true } = {}) { 47556 const tokens = parsel_tokenize(selector); 47557 if (!tokens) { 47558 return; 47559 } 47560 const ast = nestTokens(tokens, { list }); 47561 if (!recursive) { 47562 return ast; 47563 } 47564 for (const [token] of flatten(ast)) { 47565 if (token.type !== 'pseudo-class' || !token.argument) { 47566 continue; 47567 } 47568 if (!RECURSIVE_PSEUDO_CLASSES.has(token.name)) { 47569 continue; 47570 } 47571 let argument = token.argument; 47572 const childArg = RECURSIVE_PSEUDO_CLASSES_ARGS[token.name]; 47573 if (childArg) { 47574 const match = childArg.exec(argument); 47575 if (!match) { 47576 continue; 47577 } 47578 Object.assign(token, match.groups); 47579 argument = match.groups['subtree']; 47580 } 47581 if (!argument) { 47582 continue; 47583 } 47584 Object.assign(token, { 47585 subtree: parse(argument, { 47586 recursive: true, 47587 list: true, 47588 }), 47589 }); 47590 } 47591 return ast; 47592 } 47593 /** 47594 * Converts the given list or (sub)tree to a string. 47595 */ 47596 function parsel_stringify(listOrNode) { 47597 let tokens; 47598 if (Array.isArray(listOrNode)) { 47599 tokens = listOrNode; 47600 } 47601 else { 47602 tokens = [...flatten(listOrNode)].map(([token]) => token); 47603 } 47604 return tokens.map(token => token.content).join(''); 47605 } 47606 /** 47607 * To convert the specificity array to a number 47608 */ 47609 function specificityToNumber(specificity, base) { 47610 base = base || Math.max(...specificity) + 1; 47611 return (specificity[0] * (base << 1) + specificity[1] * base + specificity[2]); 47612 } 47613 /** 47614 * Calculate specificity of a selector. 47615 * 47616 * If the selector is a list, the max specificity is returned. 47617 */ 47618 function specificity(selector) { 47619 let ast = selector; 47620 if (typeof ast === 'string') { 47621 ast = parse(ast, { recursive: true }); 47622 } 47623 if (!ast) { 47624 return []; 47625 } 47626 if (ast.type === 'list' && 'list' in ast) { 47627 let base = 10; 47628 const specificities = ast.list.map((ast) => { 47629 const sp = specificity(ast); 47630 base = Math.max(base, ...specificity(ast)); 47631 return sp; 47632 }); 47633 const numbers = specificities.map((ast) => specificityToNumber(ast, base)); 47634 return specificities[numbers.indexOf(Math.max(...numbers))]; 47635 } 47636 const ret = [0, 0, 0]; 47637 for (const [token] of flatten(ast)) { 47638 switch (token.type) { 47639 case 'id': 47640 ret[0]++; 47641 break; 47642 case 'class': 47643 case 'attribute': 47644 ret[1]++; 47645 break; 47646 case 'pseudo-element': 47647 case 'type': 47648 ret[2]++; 47649 break; 47650 case 'pseudo-class': 47651 if (token.name === 'where') { 47652 break; 47653 } 47654 if (!RECURSIVE_PSEUDO_CLASSES.has(token.name) || 47655 !token.subtree) { 47656 ret[1]++; 47657 break; 47658 } 47659 const sub = specificity(token.subtree); 47660 sub.forEach((s, i) => (ret[i] += s)); 47661 // :nth-child() & :nth-last-child() add (0, 1, 0) to the specificity of their most complex selector 47662 if (token.name === 'nth-child' || 47663 token.name === 'nth-last-child') { 47664 ret[1]++; 47665 } 47666 } 47667 } 47668 return ret; 47669 } 47670 47671 47672 47673 // EXTERNAL MODULE: ./node_modules/postcss/lib/processor.js 47674 var processor = __webpack_require__(9656); 47675 var processor_default = /*#__PURE__*/__webpack_require__.n(processor); 47676 // EXTERNAL MODULE: ./node_modules/postcss/lib/css-syntax-error.js 47677 var css_syntax_error = __webpack_require__(356); 47678 var css_syntax_error_default = /*#__PURE__*/__webpack_require__.n(css_syntax_error); 47679 // EXTERNAL MODULE: ./node_modules/postcss-prefix-selector/index.js 47680 var postcss_prefix_selector = __webpack_require__(1443); 47681 var postcss_prefix_selector_default = /*#__PURE__*/__webpack_require__.n(postcss_prefix_selector); 47682 // EXTERNAL MODULE: ./node_modules/postcss-urlrebase/index.js 47683 var postcss_urlrebase = __webpack_require__(5404); 47684 var postcss_urlrebase_default = /*#__PURE__*/__webpack_require__.n(postcss_urlrebase); 47685 ;// ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/index.js 47686 /** 47687 * External dependencies 47688 */ 47689 47690 47691 47692 47693 47694 const cacheByWrapperSelector = new Map(); 47695 const ROOT_SELECTOR_TOKENS = [{ 47696 type: 'type', 47697 content: 'body' 47698 }, { 47699 type: 'type', 47700 content: 'html' 47701 }, { 47702 type: 'pseudo-class', 47703 content: ':root' 47704 }, { 47705 type: 'pseudo-class', 47706 content: ':where(body)' 47707 }, { 47708 type: 'pseudo-class', 47709 content: ':where(:root)' 47710 }, { 47711 type: 'pseudo-class', 47712 content: ':where(html)' 47713 }]; 47714 47715 /** 47716 * Prefixes root selectors in a way that ensures consistent specificity. 47717 * This requires special handling, since prefixing a classname before 47718 * html, body, or :root will generally result in an invalid selector. 47719 * 47720 * Some libraries will simply replace the root selector with the prefix 47721 * instead, but this results in inconsistent specificity. 47722 * 47723 * This function instead inserts the prefix after the root tags but before 47724 * any other part of the selector. This results in consistent specificity: 47725 * - If a `:where()` selector is used for the prefix, all selectors output 47726 * by `transformStyles` will have no specificity increase. 47727 * - If a classname, id, or something else is used as the prefix, all selectors 47728 * will have the same specificity bump when transformed. 47729 * 47730 * @param {string} prefix The prefix. 47731 * @param {string} selector The selector. 47732 * 47733 * @return {string} The prefixed root selector. 47734 */ 47735 function prefixRootSelector(prefix, selector) { 47736 // Use a tokenizer, since regular expressions are unreliable. 47737 const tokenized = parsel_tokenize(selector); 47738 47739 // Find the last token that contains a root selector by walking back 47740 // through the tokens. 47741 const lastRootIndex = tokenized.findLastIndex(({ 47742 content, 47743 type 47744 }) => { 47745 return ROOT_SELECTOR_TOKENS.some(rootSelector => content === rootSelector.content && type === rootSelector.type); 47746 }); 47747 47748 // Walk forwards to find the combinator after the last root. 47749 // This is where the root ends and the rest of the selector begins, 47750 // and the index to insert before. 47751 // Doing it this way takes into account that a root selector like 47752 // 'body' may have additional id/class/pseudo-class/attribute-selector 47753 // parts chained to it, which is difficult to quantify using a regex. 47754 let insertionPoint = -1; 47755 for (let i = lastRootIndex + 1; i < tokenized.length; i++) { 47756 if (tokenized[i].type === 'combinator') { 47757 insertionPoint = i; 47758 break; 47759 } 47760 } 47761 47762 // Tokenize and insert the prefix with a ' ' combinator before it. 47763 const tokenizedPrefix = parsel_tokenize(prefix); 47764 tokenized.splice( 47765 // Insert at the insertion point, or the end. 47766 insertionPoint === -1 ? tokenized.length : insertionPoint, 0, { 47767 type: 'combinator', 47768 content: ' ' 47769 }, ...tokenizedPrefix); 47770 return parsel_stringify(tokenized); 47771 } 47772 function transformStyle({ 47773 css, 47774 ignoredSelectors = [], 47775 baseURL 47776 }, wrapperSelector = '', transformOptions) { 47777 // When there is no wrapper selector and no base URL, there is no need 47778 // to transform the CSS. This is most cases because in the default 47779 // iframed editor, no wrapping is needed, and not many styles 47780 // provide a base URL. 47781 if (!wrapperSelector && !baseURL) { 47782 return css; 47783 } 47784 try { 47785 var _transformOptions$ign; 47786 const excludedSelectors = [...ignoredSelectors, ...((_transformOptions$ign = transformOptions?.ignoredSelectors) !== null && _transformOptions$ign !== void 0 ? _transformOptions$ign : []), wrapperSelector]; 47787 return new (processor_default())([wrapperSelector && postcss_prefix_selector_default()({ 47788 prefix: wrapperSelector, 47789 transform(prefix, selector, prefixedSelector) { 47790 // For backwards compatibility, don't use the `exclude` option 47791 // of postcss-prefix-selector, instead handle it here to match 47792 // the behavior of the old library (postcss-prefix-wrap) that 47793 // `transformStyle` previously used. 47794 if (excludedSelectors.some(excludedSelector => excludedSelector instanceof RegExp ? selector.match(excludedSelector) : selector.includes(excludedSelector))) { 47795 return selector; 47796 } 47797 const hasRootSelector = ROOT_SELECTOR_TOKENS.some(rootSelector => selector.startsWith(rootSelector.content)); 47798 47799 // Reorganize root selectors such that the root part comes before the prefix, 47800 // but the prefix still comes before the remaining part of the selector. 47801 if (hasRootSelector) { 47802 return prefixRootSelector(prefix, selector); 47803 } 47804 return prefixedSelector; 47805 } 47806 }), baseURL && postcss_urlrebase_default()({ 47807 rootUrl: baseURL 47808 })].filter(Boolean)).process(css, {}).css; // use sync PostCSS API 47809 } catch (error) { 47810 if (error instanceof (css_syntax_error_default())) { 47811 // eslint-disable-next-line no-console 47812 console.warn('wp.blockEditor.transformStyles Failed to transform CSS.', error.message + '\n' + error.showSourceCode(false)); 47813 } else { 47814 // eslint-disable-next-line no-console 47815 console.warn('wp.blockEditor.transformStyles Failed to transform CSS.', error); 47816 } 47817 return null; 47818 } 47819 } 47820 47821 /** 47822 * @typedef {Object} EditorStyle 47823 * @property {string} css the CSS block(s), as a single string. 47824 * @property {?string} baseURL the base URL to be used as the reference when rewriting urls. 47825 * @property {?string[]} ignoredSelectors the selectors not to wrap. 47826 */ 47827 47828 /** 47829 * @typedef {Object} TransformOptions 47830 * @property {?string[]} ignoredSelectors the selectors not to wrap. 47831 */ 47832 47833 /** 47834 * Applies a series of CSS rule transforms to wrap selectors inside a given class and/or rewrite URLs depending on the parameters passed. 47835 * 47836 * @param {EditorStyle[]} styles CSS rules. 47837 * @param {string} wrapperSelector Wrapper selector. 47838 * @param {TransformOptions} transformOptions Additional options for style transformation. 47839 * @return {Array} converted rules. 47840 */ 47841 const transform_styles_transformStyles = (styles, wrapperSelector = '', transformOptions) => { 47842 let cache = cacheByWrapperSelector.get(wrapperSelector); 47843 if (!cache) { 47844 cache = new WeakMap(); 47845 cacheByWrapperSelector.set(wrapperSelector, cache); 47846 } 47847 return styles.map(style => { 47848 let css = cache.get(style); 47849 if (!css) { 47850 css = transformStyle(style, wrapperSelector, transformOptions); 47851 cache.set(style, css); 47852 } 47853 return css; 47854 }); 47855 }; 47856 /* harmony default export */ const transform_styles = (transform_styles_transformStyles); 47857 47858 ;// ./node_modules/@wordpress/block-editor/build-module/components/editor-styles/index.js 47859 /** 47860 * External dependencies 47861 */ 47862 47863 47864 47865 47866 /** 47867 * WordPress dependencies 47868 */ 47869 47870 47871 47872 47873 /** 47874 * Internal dependencies 47875 */ 47876 47877 47878 47879 47880 k([names, a11y]); 47881 function useDarkThemeBodyClassName(styles, scope) { 47882 return (0,external_wp_element_namespaceObject.useCallback)(node => { 47883 if (!node) { 47884 return; 47885 } 47886 const { 47887 ownerDocument 47888 } = node; 47889 const { 47890 defaultView, 47891 body 47892 } = ownerDocument; 47893 const canvas = scope ? ownerDocument.querySelector(scope) : body; 47894 let backgroundColor; 47895 if (!canvas) { 47896 // The real .editor-styles-wrapper element might not exist in the 47897 // DOM, so calculate the background color by creating a fake 47898 // wrapper. 47899 const tempCanvas = ownerDocument.createElement('div'); 47900 tempCanvas.classList.add('editor-styles-wrapper'); 47901 body.appendChild(tempCanvas); 47902 backgroundColor = defaultView?.getComputedStyle(tempCanvas, null).getPropertyValue('background-color'); 47903 body.removeChild(tempCanvas); 47904 } else { 47905 backgroundColor = defaultView?.getComputedStyle(canvas, null).getPropertyValue('background-color'); 47906 } 47907 const colordBackgroundColor = w(backgroundColor); 47908 // If background is transparent, it should be treated as light color. 47909 if (colordBackgroundColor.luminance() > 0.5 || colordBackgroundColor.alpha() === 0) { 47910 body.classList.remove('is-dark-theme'); 47911 } else { 47912 body.classList.add('is-dark-theme'); 47913 } 47914 }, [styles, scope]); 47915 } 47916 function EditorStyles({ 47917 styles, 47918 scope, 47919 transformOptions 47920 }) { 47921 const overrides = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getStyleOverrides(), []); 47922 const [transformedStyles, transformedSvgs] = (0,external_wp_element_namespaceObject.useMemo)(() => { 47923 const _styles = Object.values(styles !== null && styles !== void 0 ? styles : []); 47924 for (const [id, override] of overrides) { 47925 const index = _styles.findIndex(({ 47926 id: _id 47927 }) => id === _id); 47928 const overrideWithId = { 47929 ...override, 47930 id 47931 }; 47932 if (index === -1) { 47933 _styles.push(overrideWithId); 47934 } else { 47935 _styles[index] = overrideWithId; 47936 } 47937 } 47938 return [transform_styles(_styles.filter(style => style?.css), scope, transformOptions), _styles.filter(style => style.__unstableType === 'svgs').map(style => style.assets).join('')]; 47939 }, [styles, overrides, scope, transformOptions]); 47940 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 47941 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("style", { 47942 ref: useDarkThemeBodyClassName(transformedStyles, scope) 47943 }), transformedStyles.map((css, index) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("style", { 47944 children: css 47945 }, index)), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SVG, { 47946 xmlns: "http://www.w3.org/2000/svg", 47947 viewBox: "0 0 0 0", 47948 width: "0", 47949 height: "0", 47950 role: "none", 47951 style: { 47952 visibility: 'hidden', 47953 position: 'absolute', 47954 left: '-9999px', 47955 overflow: 'hidden' 47956 }, 47957 dangerouslySetInnerHTML: { 47958 __html: transformedSvgs 47959 } 47960 })] 47961 }); 47962 } 47963 /* harmony default export */ const editor_styles = ((0,external_wp_element_namespaceObject.memo)(EditorStyles)); 47964 47965 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-preview/auto.js 47966 /** 47967 * WordPress dependencies 47968 */ 47969 47970 47971 47972 47973 47974 /** 47975 * Internal dependencies 47976 */ 47977 47978 47979 47980 47981 47982 // This is used to avoid rendering the block list if the sizes change. 47983 47984 const MemoizedBlockList = (0,external_wp_element_namespaceObject.memo)(BlockList); 47985 const MAX_HEIGHT = 2000; 47986 const EMPTY_ADDITIONAL_STYLES = []; 47987 function ScaledBlockPreview({ 47988 viewportWidth, 47989 containerWidth, 47990 minHeight, 47991 additionalStyles = EMPTY_ADDITIONAL_STYLES 47992 }) { 47993 if (!viewportWidth) { 47994 viewportWidth = containerWidth; 47995 } 47996 const [contentResizeListener, { 47997 height: contentHeight 47998 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 47999 const { 48000 styles 48001 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 48002 const settings = select(store).getSettings(); 48003 return { 48004 styles: settings.styles 48005 }; 48006 }, []); 48007 48008 // Avoid scrollbars for pattern previews. 48009 const editorStyles = (0,external_wp_element_namespaceObject.useMemo)(() => { 48010 if (styles) { 48011 return [...styles, { 48012 css: 'body{height:auto;overflow:hidden;border:none;padding:0;}', 48013 __unstableType: 'presets' 48014 }, ...additionalStyles]; 48015 } 48016 return styles; 48017 }, [styles, additionalStyles]); 48018 const scale = containerWidth / viewportWidth; 48019 const aspectRatio = contentHeight ? containerWidth / (contentHeight * scale) : 0; 48020 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Disabled, { 48021 className: "block-editor-block-preview__content", 48022 style: { 48023 transform: `scale($scale})`, 48024 // Using width + aspect-ratio instead of height here triggers browsers' native 48025 // handling of scrollbar's visibility. It prevents the flickering issue seen 48026 // in https://github.com/WordPress/gutenberg/issues/52027. 48027 // See https://github.com/WordPress/gutenberg/pull/52921 for more info. 48028 aspectRatio, 48029 maxHeight: contentHeight > MAX_HEIGHT ? MAX_HEIGHT * scale : undefined, 48030 minHeight 48031 }, 48032 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(iframe, { 48033 contentRef: (0,external_wp_compose_namespaceObject.useRefEffect)(bodyElement => { 48034 const { 48035 ownerDocument: { 48036 documentElement 48037 } 48038 } = bodyElement; 48039 documentElement.classList.add('block-editor-block-preview__content-iframe'); 48040 documentElement.style.position = 'absolute'; 48041 documentElement.style.width = '100%'; 48042 48043 // Necessary for contentResizeListener to work. 48044 bodyElement.style.boxSizing = 'border-box'; 48045 bodyElement.style.position = 'absolute'; 48046 bodyElement.style.width = '100%'; 48047 }, []), 48048 "aria-hidden": true, 48049 tabIndex: -1, 48050 style: { 48051 position: 'absolute', 48052 width: viewportWidth, 48053 height: contentHeight, 48054 pointerEvents: 'none', 48055 // This is a catch-all max-height for patterns. 48056 // See: https://github.com/WordPress/gutenberg/pull/38175. 48057 maxHeight: MAX_HEIGHT, 48058 minHeight: scale !== 0 && scale < 1 && minHeight ? minHeight / scale : minHeight 48059 }, 48060 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editor_styles, { 48061 styles: editorStyles 48062 }), contentResizeListener, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MemoizedBlockList, { 48063 renderAppender: false 48064 })] 48065 }) 48066 }); 48067 } 48068 function AutoBlockPreview(props) { 48069 const [containerResizeListener, { 48070 width: containerWidth 48071 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 48072 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 48073 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48074 style: { 48075 position: 'relative', 48076 width: '100%', 48077 height: 0 48078 }, 48079 children: containerResizeListener 48080 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48081 className: "block-editor-block-preview__container", 48082 children: !!containerWidth && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ScaledBlockPreview, { 48083 ...props, 48084 containerWidth: containerWidth 48085 }) 48086 })] 48087 }); 48088 } 48089 48090 ;// external ["wp","priorityQueue"] 48091 const external_wp_priorityQueue_namespaceObject = window["wp"]["priorityQueue"]; 48092 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-preview/async.js 48093 /** 48094 * WordPress dependencies 48095 */ 48096 48097 48098 const blockPreviewQueue = (0,external_wp_priorityQueue_namespaceObject.createQueue)(); 48099 48100 /** 48101 * Renders a component at the next idle time. 48102 * @param {*} props 48103 */ 48104 function Async({ 48105 children, 48106 placeholder 48107 }) { 48108 const [shouldRender, setShouldRender] = (0,external_wp_element_namespaceObject.useState)(false); 48109 48110 // In the future, we could try to use startTransition here, but currently 48111 // react will batch all transitions, which means all previews will be 48112 // rendered at the same time. 48113 // https://react.dev/reference/react/startTransition#caveats 48114 // > If there are multiple ongoing Transitions, React currently batches them 48115 // > together. This is a limitation that will likely be removed in a future 48116 // > release. 48117 48118 (0,external_wp_element_namespaceObject.useEffect)(() => { 48119 const context = {}; 48120 blockPreviewQueue.add(context, () => { 48121 // Synchronously run all renders so it consumes timeRemaining. 48122 // See https://github.com/WordPress/gutenberg/pull/48238 48123 (0,external_wp_element_namespaceObject.flushSync)(() => { 48124 setShouldRender(true); 48125 }); 48126 }); 48127 return () => { 48128 blockPreviewQueue.cancel(context); 48129 }; 48130 }, []); 48131 if (!shouldRender) { 48132 return placeholder; 48133 } 48134 return children; 48135 } 48136 48137 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-preview/index.js 48138 /** 48139 * External dependencies 48140 */ 48141 48142 48143 /** 48144 * WordPress dependencies 48145 */ 48146 48147 48148 48149 48150 48151 /** 48152 * Internal dependencies 48153 */ 48154 48155 48156 48157 48158 48159 48160 48161 const block_preview_EMPTY_ADDITIONAL_STYLES = []; 48162 function BlockPreview({ 48163 blocks, 48164 viewportWidth = 1200, 48165 minHeight, 48166 additionalStyles = block_preview_EMPTY_ADDITIONAL_STYLES, 48167 // Deprecated props: 48168 __experimentalMinHeight, 48169 __experimentalPadding 48170 }) { 48171 if (__experimentalMinHeight) { 48172 minHeight = __experimentalMinHeight; 48173 external_wp_deprecated_default()('The __experimentalMinHeight prop', { 48174 since: '6.2', 48175 version: '6.4', 48176 alternative: 'minHeight' 48177 }); 48178 } 48179 if (__experimentalPadding) { 48180 additionalStyles = [...additionalStyles, { 48181 css: `body { padding: $__experimentalPadding}px; }` 48182 }]; 48183 external_wp_deprecated_default()('The __experimentalPadding prop of BlockPreview', { 48184 since: '6.2', 48185 version: '6.4', 48186 alternative: 'additionalStyles' 48187 }); 48188 } 48189 const originalSettings = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings(), []); 48190 const settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 48191 ...originalSettings, 48192 focusMode: false, 48193 // Disable "Spotlight mode". 48194 isPreviewMode: true 48195 }), [originalSettings]); 48196 const renderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => Array.isArray(blocks) ? blocks : [blocks], [blocks]); 48197 if (!blocks || blocks.length === 0) { 48198 return null; 48199 } 48200 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ExperimentalBlockEditorProvider, { 48201 value: renderedBlocks, 48202 settings: settings, 48203 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AutoBlockPreview, { 48204 viewportWidth: viewportWidth, 48205 minHeight: minHeight, 48206 additionalStyles: additionalStyles 48207 }) 48208 }); 48209 } 48210 const MemoizedBlockPreview = (0,external_wp_element_namespaceObject.memo)(BlockPreview); 48211 MemoizedBlockPreview.Async = Async; 48212 48213 /** 48214 * BlockPreview renders a preview of a block or array of blocks. 48215 * 48216 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-preview/README.md 48217 * 48218 * @param {Object} preview options for how the preview should be shown 48219 * @param {Array|Object} preview.blocks A block instance (object) or an array of blocks to be previewed. 48220 * @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. 48221 * 48222 * @return {Component} The component to be rendered. 48223 */ 48224 /* harmony default export */ const block_preview = (MemoizedBlockPreview); 48225 48226 /** 48227 * This hook is used to lightly mark an element as a block preview wrapper 48228 * element. Call this hook and pass the returned props to the element to mark as 48229 * a block preview wrapper, automatically rendering inner blocks as children. If 48230 * you define a ref for the element, it is important to pass the ref to this 48231 * hook, which the hook in turn will pass to the component through the props it 48232 * returns. Optionally, you can also pass any other props through this hook, and 48233 * they will be merged and returned. 48234 * 48235 * @param {Object} options Preview options. 48236 * @param {WPBlock[]} options.blocks Block objects. 48237 * @param {Object} options.props Optional. Props to pass to the element. Must contain 48238 * the ref if one is defined. 48239 * @param {Object} options.layout Layout settings to be used in the preview. 48240 */ 48241 function useBlockPreview({ 48242 blocks, 48243 props = {}, 48244 layout 48245 }) { 48246 const originalSettings = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings(), []); 48247 const settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 48248 ...originalSettings, 48249 styles: undefined, 48250 // Clear styles included by the parent settings, as they are already output by the parent's EditorStyles. 48251 focusMode: false, 48252 // Disable "Spotlight mode". 48253 isPreviewMode: true 48254 }), [originalSettings]); 48255 const disabledRef = (0,external_wp_compose_namespaceObject.useDisabled)(); 48256 const ref = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, disabledRef]); 48257 const renderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => Array.isArray(blocks) ? blocks : [blocks], [blocks]); 48258 const children = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(ExperimentalBlockEditorProvider, { 48259 value: renderedBlocks, 48260 settings: settings, 48261 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editor_styles, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockListItems, { 48262 renderAppender: false, 48263 layout: layout 48264 })] 48265 }); 48266 return { 48267 ...props, 48268 ref, 48269 className: dist_clsx(props.className, 'block-editor-block-preview__live-content', 'components-disabled'), 48270 children: blocks?.length ? children : null 48271 }; 48272 } 48273 48274 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/preview-panel.js 48275 /** 48276 * WordPress dependencies 48277 */ 48278 48279 48280 48281 48282 /** 48283 * Internal dependencies 48284 */ 48285 48286 48287 48288 function InserterPreviewPanel({ 48289 item 48290 }) { 48291 var _example$viewportWidt; 48292 const { 48293 name, 48294 title, 48295 icon, 48296 description, 48297 initialAttributes, 48298 example 48299 } = item; 48300 const isReusable = (0,external_wp_blocks_namespaceObject.isReusableBlock)(item); 48301 const blocks = (0,external_wp_element_namespaceObject.useMemo)(() => { 48302 if (!example) { 48303 return (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes); 48304 } 48305 return (0,external_wp_blocks_namespaceObject.getBlockFromExample)(name, { 48306 attributes: { 48307 ...example.attributes, 48308 ...initialAttributes 48309 }, 48310 innerBlocks: example.innerBlocks 48311 }); 48312 }, [name, example, initialAttributes]); 48313 // Same as height of BlockPreviewPanel. 48314 const previewHeight = 144; 48315 const sidebarWidth = 280; 48316 const viewportWidth = (_example$viewportWidt = example?.viewportWidth) !== null && _example$viewportWidt !== void 0 ? _example$viewportWidt : 500; 48317 const scale = sidebarWidth / viewportWidth; 48318 const minHeight = scale !== 0 && scale < 1 && previewHeight ? previewHeight / scale : previewHeight; 48319 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 48320 className: "block-editor-inserter__preview-container", 48321 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48322 className: "block-editor-inserter__preview", 48323 children: isReusable || example ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48324 className: "block-editor-inserter__preview-content", 48325 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview, { 48326 blocks: blocks, 48327 viewportWidth: viewportWidth, 48328 minHeight: previewHeight, 48329 additionalStyles: 48330 //We want this CSS to be in sync with the one in BlockPreviewPanel. 48331 [{ 48332 css: ` 48333 body { 48334 padding: 24px; 48335 min-height:$Math.round(minHeight)}px; 48336 display:flex; 48337 align-items:center; 48338 } 48339 .is-root-container { width: 100%; } 48340 ` 48341 }] 48342 }) 48343 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48344 className: "block-editor-inserter__preview-content-missing", 48345 children: (0,external_wp_i18n_namespaceObject.__)('No preview available.') 48346 }) 48347 }), !isReusable && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_card, { 48348 title: title, 48349 icon: icon, 48350 description: description 48351 })] 48352 }); 48353 } 48354 /* harmony default export */ const preview_panel = (InserterPreviewPanel); 48355 48356 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/item.js 48357 /** 48358 * WordPress dependencies 48359 */ 48360 48361 48362 48363 function InserterListboxItem({ 48364 isFirst, 48365 as: Component, 48366 children, 48367 ...props 48368 }, ref) { 48369 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite.Item, { 48370 ref: ref, 48371 role: "option" 48372 // Use the Composite.Item `accessibleWhenDisabled` prop 48373 // over Button's `isFocusable`. The latter was shown to 48374 // cause an issue with tab order in the inserter list. 48375 , 48376 accessibleWhenDisabled: true, 48377 ...props, 48378 render: htmlProps => { 48379 const propsWithTabIndex = { 48380 ...htmlProps, 48381 tabIndex: isFirst ? 0 : htmlProps.tabIndex 48382 }; 48383 if (Component) { 48384 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Component, { 48385 ...propsWithTabIndex, 48386 children: children 48387 }); 48388 } 48389 if (typeof children === 'function') { 48390 return children(propsWithTabIndex); 48391 } 48392 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 48393 __next40pxDefaultSize: true, 48394 ...propsWithTabIndex, 48395 children: children 48396 }); 48397 } 48398 }); 48399 } 48400 /* harmony default export */ const inserter_listbox_item = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxItem)); 48401 48402 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-draggable-blocks/index.js 48403 /** 48404 * WordPress dependencies 48405 */ 48406 48407 48408 48409 48410 48411 /** 48412 * Internal dependencies 48413 */ 48414 48415 48416 48417 48418 48419 const InserterDraggableBlocks = ({ 48420 isEnabled, 48421 blocks, 48422 icon, 48423 children, 48424 pattern 48425 }) => { 48426 const blockTypeIcon = (0,external_wp_data_namespaceObject.useSelect)(select => { 48427 const { 48428 getBlockType 48429 } = select(external_wp_blocks_namespaceObject.store); 48430 return blocks.length === 1 && getBlockType(blocks[0].name)?.icon; 48431 }, [blocks]); 48432 const { 48433 startDragging, 48434 stopDragging 48435 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 48436 const patternBlock = (0,external_wp_element_namespaceObject.useMemo)(() => { 48437 return pattern?.type === INSERTER_PATTERN_TYPES.user && pattern?.syncStatus !== 'unsynced' ? [(0,external_wp_blocks_namespaceObject.createBlock)('core/block', { 48438 ref: pattern.id 48439 })] : undefined; 48440 }, [pattern?.type, pattern?.syncStatus, pattern?.id]); 48441 if (!isEnabled) { 48442 return children({ 48443 draggable: false, 48444 onDragStart: undefined, 48445 onDragEnd: undefined 48446 }); 48447 } 48448 const draggableBlocks = patternBlock !== null && patternBlock !== void 0 ? patternBlock : blocks; 48449 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Draggable, { 48450 __experimentalTransferDataType: "wp-blocks", 48451 transferData: { 48452 type: 'inserter', 48453 blocks: draggableBlocks 48454 }, 48455 onDragStart: event => { 48456 startDragging(); 48457 for (const block of draggableBlocks) { 48458 const type = `wp-block:$block.name}`; 48459 // This will fill in the dataTransfer.types array so that 48460 // the drop zone can check if the draggable is eligible. 48461 // Unfortuantely, on drag start, we don't have access to the 48462 // actual data, only the data keys/types. 48463 event.dataTransfer.items.add('', type); 48464 } 48465 }, 48466 onDragEnd: () => { 48467 stopDragging(); 48468 }, 48469 __experimentalDragComponent: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockDraggableChip, { 48470 count: blocks.length, 48471 icon: icon || !pattern && blockTypeIcon, 48472 isPattern: !!pattern 48473 }), 48474 children: ({ 48475 onDraggableStart, 48476 onDraggableEnd 48477 }) => { 48478 return children({ 48479 draggable: true, 48480 onDragStart: onDraggableStart, 48481 onDragEnd: onDraggableEnd 48482 }); 48483 } 48484 }); 48485 }; 48486 /* harmony default export */ const inserter_draggable_blocks = (InserterDraggableBlocks); 48487 48488 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-list-item/index.js 48489 /** 48490 * External dependencies 48491 */ 48492 48493 48494 /** 48495 * WordPress dependencies 48496 */ 48497 48498 48499 48500 48501 48502 /** 48503 * Internal dependencies 48504 */ 48505 48506 48507 48508 48509 function InserterListItem({ 48510 className, 48511 isFirst, 48512 item, 48513 onSelect, 48514 onHover, 48515 isDraggable, 48516 ...props 48517 }) { 48518 const isDraggingRef = (0,external_wp_element_namespaceObject.useRef)(false); 48519 const itemIconStyle = item.icon ? { 48520 backgroundColor: item.icon.background, 48521 color: item.icon.foreground 48522 } : {}; 48523 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]); 48524 const isSynced = (0,external_wp_blocks_namespaceObject.isReusableBlock)(item) && item.syncStatus !== 'unsynced' || (0,external_wp_blocks_namespaceObject.isTemplatePart)(item); 48525 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_draggable_blocks, { 48526 isEnabled: isDraggable && !item.isDisabled, 48527 blocks: blocks, 48528 icon: item.icon, 48529 children: ({ 48530 draggable, 48531 onDragStart, 48532 onDragEnd 48533 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48534 className: dist_clsx('block-editor-block-types-list__list-item', { 48535 'is-synced': isSynced 48536 }), 48537 draggable: draggable, 48538 onDragStart: event => { 48539 isDraggingRef.current = true; 48540 if (onDragStart) { 48541 onHover(null); 48542 onDragStart(event); 48543 } 48544 }, 48545 onDragEnd: event => { 48546 isDraggingRef.current = false; 48547 if (onDragEnd) { 48548 onDragEnd(event); 48549 } 48550 }, 48551 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(inserter_listbox_item, { 48552 isFirst: isFirst, 48553 className: dist_clsx('block-editor-block-types-list__item', className), 48554 disabled: item.isDisabled, 48555 onClick: event => { 48556 event.preventDefault(); 48557 onSelect(item, (0,external_wp_keycodes_namespaceObject.isAppleOS)() ? event.metaKey : event.ctrlKey); 48558 onHover(null); 48559 }, 48560 onKeyDown: event => { 48561 const { 48562 keyCode 48563 } = event; 48564 if (keyCode === external_wp_keycodes_namespaceObject.ENTER) { 48565 event.preventDefault(); 48566 onSelect(item, (0,external_wp_keycodes_namespaceObject.isAppleOS)() ? event.metaKey : event.ctrlKey); 48567 onHover(null); 48568 } 48569 }, 48570 onMouseEnter: () => { 48571 if (isDraggingRef.current) { 48572 return; 48573 } 48574 onHover(item); 48575 }, 48576 onMouseLeave: () => onHover(null), 48577 ...props, 48578 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 48579 className: "block-editor-block-types-list__item-icon", 48580 style: itemIconStyle, 48581 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 48582 icon: item.icon, 48583 showColors: true 48584 }) 48585 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 48586 className: "block-editor-block-types-list__item-title", 48587 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 48588 numberOfLines: 3, 48589 children: item.title 48590 }) 48591 })] 48592 }) 48593 }) 48594 }); 48595 } 48596 /* harmony default export */ const inserter_list_item = ((0,external_wp_element_namespaceObject.memo)(InserterListItem)); 48597 48598 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/group.js 48599 /** 48600 * WordPress dependencies 48601 */ 48602 48603 48604 48605 48606 function InserterListboxGroup(props, ref) { 48607 const [shouldSpeak, setShouldSpeak] = (0,external_wp_element_namespaceObject.useState)(false); 48608 (0,external_wp_element_namespaceObject.useEffect)(() => { 48609 if (shouldSpeak) { 48610 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Use left and right arrow keys to move through blocks')); 48611 } 48612 }, [shouldSpeak]); 48613 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48614 ref: ref, 48615 role: "listbox", 48616 "aria-orientation": "horizontal", 48617 onFocus: () => { 48618 setShouldSpeak(true); 48619 }, 48620 onBlur: event => { 48621 const focusingOutsideGroup = !event.currentTarget.contains(event.relatedTarget); 48622 if (focusingOutsideGroup) { 48623 setShouldSpeak(false); 48624 } 48625 }, 48626 ...props 48627 }); 48628 } 48629 /* harmony default export */ const group = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxGroup)); 48630 48631 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/row.js 48632 /** 48633 * WordPress dependencies 48634 */ 48635 48636 48637 48638 function InserterListboxRow(props, ref) { 48639 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite.Group, { 48640 role: "presentation", 48641 ref: ref, 48642 ...props 48643 }); 48644 } 48645 /* harmony default export */ const inserter_listbox_row = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxRow)); 48646 48647 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-types-list/index.js 48648 /** 48649 * WordPress dependencies 48650 */ 48651 48652 48653 48654 /** 48655 * Internal dependencies 48656 */ 48657 48658 48659 48660 function chunk(array, size) { 48661 const chunks = []; 48662 for (let i = 0, j = array.length; i < j; i += size) { 48663 chunks.push(array.slice(i, i + size)); 48664 } 48665 return chunks; 48666 } 48667 function BlockTypesList({ 48668 items = [], 48669 onSelect, 48670 onHover = () => {}, 48671 children, 48672 label, 48673 isDraggable = true 48674 }) { 48675 const className = 'block-editor-block-types-list'; 48676 const listId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockTypesList, className); 48677 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(group, { 48678 className: className, 48679 "aria-label": label, 48680 children: [chunk(items, 3).map((row, i) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_listbox_row, { 48681 children: row.map((item, j) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_list_item, { 48682 item: item, 48683 className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(item.id), 48684 onSelect: onSelect, 48685 onHover: onHover, 48686 isDraggable: isDraggable && !item.isDisabled, 48687 isFirst: i === 0 && j === 0, 48688 rowId: `$listId}-$i}` 48689 }, item.id)) 48690 }, i)), children] 48691 }); 48692 } 48693 /* harmony default export */ const block_types_list = (BlockTypesList); 48694 48695 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/panel.js 48696 /** 48697 * WordPress dependencies 48698 */ 48699 48700 48701 function InserterPanel({ 48702 title, 48703 icon, 48704 children 48705 }) { 48706 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 48707 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 48708 className: "block-editor-inserter__panel-header", 48709 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("h2", { 48710 className: "block-editor-inserter__panel-title", 48711 children: title 48712 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 48713 icon: icon 48714 })] 48715 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48716 className: "block-editor-inserter__panel-content", 48717 children: children 48718 })] 48719 }); 48720 } 48721 /* harmony default export */ const panel = (InserterPanel); 48722 48723 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-block-types-state.js 48724 /** 48725 * WordPress dependencies 48726 */ 48727 48728 48729 48730 48731 48732 48733 /** 48734 * Internal dependencies 48735 */ 48736 48737 48738 48739 48740 /** 48741 * Retrieves the block types inserter state. 48742 * 48743 * @param {string=} rootClientId Insertion's root client ID. 48744 * @param {Function} onInsert function called when inserter a list of blocks. 48745 * @param {boolean} isQuick 48746 * @return {Array} Returns the block types state. (block types, categories, collections, onSelect handler) 48747 */ 48748 const useBlockTypesState = (rootClientId, onInsert, isQuick) => { 48749 const options = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 48750 [isFiltered]: !!isQuick 48751 }), [isQuick]); 48752 const [items] = (0,external_wp_data_namespaceObject.useSelect)(select => [select(store).getInserterItems(rootClientId, options)], [rootClientId, options]); 48753 const { 48754 getClosestAllowedInsertionPoint 48755 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 48756 const { 48757 createErrorNotice 48758 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 48759 const [categories, collections] = (0,external_wp_data_namespaceObject.useSelect)(select => { 48760 const { 48761 getCategories, 48762 getCollections 48763 } = select(external_wp_blocks_namespaceObject.store); 48764 return [getCategories(), getCollections()]; 48765 }, []); 48766 const onSelectItem = (0,external_wp_element_namespaceObject.useCallback)(({ 48767 name, 48768 initialAttributes, 48769 innerBlocks, 48770 syncStatus, 48771 content 48772 }, shouldFocusBlock) => { 48773 const destinationClientId = getClosestAllowedInsertionPoint(name, rootClientId); 48774 if (destinationClientId === null) { 48775 var _getBlockType$title; 48776 const title = (_getBlockType$title = (0,external_wp_blocks_namespaceObject.getBlockType)(name)?.title) !== null && _getBlockType$title !== void 0 ? _getBlockType$title : name; 48777 createErrorNotice((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: block pattern title. */ 48778 (0,external_wp_i18n_namespaceObject.__)('Block "%s" can\'t be inserted.'), title), { 48779 type: 'snackbar', 48780 id: 'inserter-notice' 48781 }); 48782 return; 48783 } 48784 const insertedBlock = syncStatus === 'unsynced' ? (0,external_wp_blocks_namespaceObject.parse)(content, { 48785 __unstableSkipMigrationLogs: true 48786 }) : (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(innerBlocks)); 48787 onInsert(insertedBlock, undefined, shouldFocusBlock, destinationClientId); 48788 }, [getClosestAllowedInsertionPoint, rootClientId, onInsert, createErrorNotice]); 48789 return [items, categories, collections, onSelectItem]; 48790 }; 48791 /* harmony default export */ const use_block_types_state = (useBlockTypesState); 48792 48793 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/index.js 48794 /** 48795 * WordPress dependencies 48796 */ 48797 48798 48799 /** 48800 * Internal dependencies 48801 */ 48802 48803 48804 48805 48806 function InserterListbox({ 48807 children 48808 }) { 48809 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite, { 48810 focusShift: true, 48811 focusWrap: "horizontal", 48812 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, {}), 48813 children: children 48814 }); 48815 } 48816 /* harmony default export */ const inserter_listbox = (InserterListbox); 48817 48818 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/no-results.js 48819 /** 48820 * WordPress dependencies 48821 */ 48822 48823 48824 function InserterNoResults() { 48825 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 48826 className: "block-editor-inserter__no-results", 48827 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 48828 children: (0,external_wp_i18n_namespaceObject.__)('No results found.') 48829 }) 48830 }); 48831 } 48832 /* harmony default export */ const no_results = (InserterNoResults); 48833 48834 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-types-tab.js 48835 /** 48836 * WordPress dependencies 48837 */ 48838 48839 48840 48841 48842 /** 48843 * Internal dependencies 48844 */ 48845 48846 48847 48848 48849 48850 48851 48852 const getBlockNamespace = item => item.name.split('/')[0]; 48853 const MAX_SUGGESTED_ITEMS = 6; 48854 48855 /** 48856 * Shared reference to an empty array for cases where it is important to avoid 48857 * returning a new array reference on every invocation and rerendering the component. 48858 * 48859 * @type {Array} 48860 */ 48861 const block_types_tab_EMPTY_ARRAY = []; 48862 function BlockTypesTabPanel({ 48863 items, 48864 collections, 48865 categories, 48866 onSelectItem, 48867 onHover, 48868 showMostUsedBlocks, 48869 className 48870 }) { 48871 const suggestedItems = (0,external_wp_element_namespaceObject.useMemo)(() => { 48872 return orderBy(items, 'frecency', 'desc').slice(0, MAX_SUGGESTED_ITEMS); 48873 }, [items]); 48874 const uncategorizedItems = (0,external_wp_element_namespaceObject.useMemo)(() => { 48875 return items.filter(item => !item.category); 48876 }, [items]); 48877 const itemsPerCollection = (0,external_wp_element_namespaceObject.useMemo)(() => { 48878 // Create a new Object to avoid mutating collection. 48879 const result = { 48880 ...collections 48881 }; 48882 Object.keys(collections).forEach(namespace => { 48883 result[namespace] = items.filter(item => getBlockNamespace(item) === namespace); 48884 if (result[namespace].length === 0) { 48885 delete result[namespace]; 48886 } 48887 }); 48888 return result; 48889 }, [items, collections]); 48890 48891 // Hide block preview on unmount. 48892 (0,external_wp_element_namespaceObject.useEffect)(() => () => onHover(null), []); 48893 48894 /** 48895 * The inserter contains a big number of blocks and opening it is a costful operation. 48896 * The rendering is the most costful part of it, in order to improve the responsiveness 48897 * of the "opening" action, these lazy lists allow us to render the inserter category per category, 48898 * once all the categories are rendered, we start rendering the collections and the uncategorized block types. 48899 */ 48900 const currentlyRenderedCategories = (0,external_wp_compose_namespaceObject.useAsyncList)(categories); 48901 const didRenderAllCategories = categories.length === currentlyRenderedCategories.length; 48902 48903 // Async List requires an array. 48904 const collectionEntries = (0,external_wp_element_namespaceObject.useMemo)(() => { 48905 return Object.entries(collections); 48906 }, [collections]); 48907 const currentlyRenderedCollections = (0,external_wp_compose_namespaceObject.useAsyncList)(didRenderAllCategories ? collectionEntries : block_types_tab_EMPTY_ARRAY); 48908 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 48909 className: className, 48910 children: [showMostUsedBlocks && 48911 // Only show the most used blocks if the total amount of block 48912 // is larger than 1 row, otherwise it is not so useful. 48913 items.length > 3 && !!suggestedItems.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, { 48914 title: (0,external_wp_i18n_namespaceObject._x)('Most used', 'blocks'), 48915 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_types_list, { 48916 items: suggestedItems, 48917 onSelect: onSelectItem, 48918 onHover: onHover, 48919 label: (0,external_wp_i18n_namespaceObject._x)('Most used', 'blocks') 48920 }) 48921 }), currentlyRenderedCategories.map(category => { 48922 const categoryItems = items.filter(item => item.category === category.slug); 48923 if (!categoryItems || !categoryItems.length) { 48924 return null; 48925 } 48926 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, { 48927 title: category.title, 48928 icon: category.icon, 48929 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_types_list, { 48930 items: categoryItems, 48931 onSelect: onSelectItem, 48932 onHover: onHover, 48933 label: category.title 48934 }) 48935 }, category.slug); 48936 }), didRenderAllCategories && uncategorizedItems.length > 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, { 48937 className: "block-editor-inserter__uncategorized-blocks-panel", 48938 title: (0,external_wp_i18n_namespaceObject.__)('Uncategorized'), 48939 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_types_list, { 48940 items: uncategorizedItems, 48941 onSelect: onSelectItem, 48942 onHover: onHover, 48943 label: (0,external_wp_i18n_namespaceObject.__)('Uncategorized') 48944 }) 48945 }), currentlyRenderedCollections.map(([namespace, collection]) => { 48946 const collectionItems = itemsPerCollection[namespace]; 48947 if (!collectionItems || !collectionItems.length) { 48948 return null; 48949 } 48950 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, { 48951 title: collection.title, 48952 icon: collection.icon, 48953 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_types_list, { 48954 items: collectionItems, 48955 onSelect: onSelectItem, 48956 onHover: onHover, 48957 label: collection.title 48958 }) 48959 }, namespace); 48960 })] 48961 }); 48962 } 48963 function BlockTypesTab({ 48964 rootClientId, 48965 onInsert, 48966 onHover, 48967 showMostUsedBlocks 48968 }, ref) { 48969 const [items, categories, collections, onSelectItem] = use_block_types_state(rootClientId, onInsert); 48970 if (!items.length) { 48971 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(no_results, {}); 48972 } 48973 const itemsForCurrentRoot = []; 48974 const itemsRemaining = []; 48975 for (const item of items) { 48976 // Skip reusable blocks, they moved to the patterns tab. 48977 if (item.category === 'reusable') { 48978 continue; 48979 } 48980 if (item.isAllowedInCurrentRoot) { 48981 itemsForCurrentRoot.push(item); 48982 } else { 48983 itemsRemaining.push(item); 48984 } 48985 } 48986 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_listbox, { 48987 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 48988 ref: ref, 48989 children: [!!itemsForCurrentRoot.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 48990 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTypesTabPanel, { 48991 items: itemsForCurrentRoot, 48992 categories: categories, 48993 collections: collections, 48994 onSelectItem: onSelectItem, 48995 onHover: onHover, 48996 showMostUsedBlocks: showMostUsedBlocks, 48997 className: "block-editor-inserter__insertable-blocks-at-selection" 48998 }) 48999 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTypesTabPanel, { 49000 items: itemsRemaining, 49001 categories: categories, 49002 collections: collections, 49003 onSelectItem: onSelectItem, 49004 onHover: onHover, 49005 showMostUsedBlocks: showMostUsedBlocks, 49006 className: "block-editor-inserter__all-blocks" 49007 })] 49008 }) 49009 }); 49010 } 49011 /* harmony default export */ const block_types_tab = ((0,external_wp_element_namespaceObject.forwardRef)(BlockTypesTab)); 49012 49013 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js 49014 /** 49015 * WordPress dependencies 49016 */ 49017 49018 49019 49020 function PatternCategoriesList({ 49021 selectedCategory, 49022 patternCategories, 49023 onClickCategory 49024 }) { 49025 const baseClassName = 'block-editor-block-patterns-explorer__sidebar'; 49026 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49027 className: `$baseClassName}__categories-list`, 49028 children: patternCategories.map(({ 49029 name, 49030 label 49031 }) => { 49032 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 49033 __next40pxDefaultSize: true, 49034 label: label, 49035 className: `$baseClassName}__categories-list__item`, 49036 isPressed: selectedCategory === name, 49037 onClick: () => { 49038 onClickCategory(name); 49039 }, 49040 children: label 49041 }, name); 49042 }) 49043 }); 49044 } 49045 function PatternsExplorerSearch({ 49046 searchValue, 49047 setSearchValue 49048 }) { 49049 const baseClassName = 'block-editor-block-patterns-explorer__search'; 49050 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49051 className: baseClassName, 49052 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SearchControl, { 49053 __nextHasNoMarginBottom: true, 49054 onChange: setSearchValue, 49055 value: searchValue, 49056 label: (0,external_wp_i18n_namespaceObject.__)('Search'), 49057 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search') 49058 }) 49059 }); 49060 } 49061 function PatternExplorerSidebar({ 49062 selectedCategory, 49063 patternCategories, 49064 onClickCategory, 49065 searchValue, 49066 setSearchValue 49067 }) { 49068 const baseClassName = 'block-editor-block-patterns-explorer__sidebar'; 49069 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 49070 className: baseClassName, 49071 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternsExplorerSearch, { 49072 searchValue: searchValue, 49073 setSearchValue: setSearchValue 49074 }), !searchValue && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternCategoriesList, { 49075 selectedCategory: selectedCategory, 49076 patternCategories: patternCategories, 49077 onClickCategory: onClickCategory 49078 })] 49079 }); 49080 } 49081 /* harmony default export */ const pattern_explorer_sidebar = (PatternExplorerSidebar); 49082 49083 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-patterns-paging/index.js 49084 /** 49085 * WordPress dependencies 49086 */ 49087 49088 49089 49090 function Pagination({ 49091 currentPage, 49092 numPages, 49093 changePage, 49094 totalItems 49095 }) { 49096 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 49097 className: "block-editor-patterns__grid-pagination-wrapper", 49098 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 49099 variant: "muted", 49100 children: (0,external_wp_i18n_namespaceObject.sprintf)( 49101 // translators: %s: Total number of patterns. 49102 (0,external_wp_i18n_namespaceObject._n)('%s item', '%s items', totalItems), totalItems) 49103 }), numPages > 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 49104 expanded: false, 49105 spacing: 3, 49106 justify: "flex-start", 49107 className: "block-editor-patterns__grid-pagination", 49108 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 49109 expanded: false, 49110 spacing: 1, 49111 className: "block-editor-patterns__grid-pagination-previous", 49112 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 49113 variant: "tertiary", 49114 onClick: () => changePage(1), 49115 disabled: currentPage === 1, 49116 "aria-label": (0,external_wp_i18n_namespaceObject.__)('First page'), 49117 size: "compact", 49118 accessibleWhenDisabled: true, 49119 className: "block-editor-patterns__grid-pagination-button", 49120 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 49121 children: "\xAB" 49122 }) 49123 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 49124 variant: "tertiary", 49125 onClick: () => changePage(currentPage - 1), 49126 disabled: currentPage === 1, 49127 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Previous page'), 49128 size: "compact", 49129 accessibleWhenDisabled: true, 49130 className: "block-editor-patterns__grid-pagination-button", 49131 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 49132 children: "\u2039" 49133 }) 49134 })] 49135 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 49136 variant: "muted", 49137 children: (0,external_wp_i18n_namespaceObject.sprintf)( 49138 // translators: 1: Current page number. 2: Total number of pages. 49139 (0,external_wp_i18n_namespaceObject._x)('%1$s of %2$s', 'paging'), currentPage, numPages) 49140 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 49141 expanded: false, 49142 spacing: 1, 49143 className: "block-editor-patterns__grid-pagination-next", 49144 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 49145 variant: "tertiary", 49146 onClick: () => changePage(currentPage + 1), 49147 disabled: currentPage === numPages, 49148 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Next page'), 49149 size: "compact", 49150 accessibleWhenDisabled: true, 49151 className: "block-editor-patterns__grid-pagination-button", 49152 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 49153 children: "\u203A" 49154 }) 49155 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 49156 variant: "tertiary", 49157 onClick: () => changePage(numPages), 49158 disabled: currentPage === numPages, 49159 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Last page'), 49160 size: "compact", 49161 accessibleWhenDisabled: true, 49162 className: "block-editor-patterns__grid-pagination-button", 49163 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 49164 children: "\xBB" 49165 }) 49166 })] 49167 })] 49168 })] 49169 }); 49170 } 49171 49172 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-patterns-list/index.js 49173 /** 49174 * External dependencies 49175 */ 49176 49177 49178 /** 49179 * WordPress dependencies 49180 */ 49181 49182 49183 49184 49185 49186 49187 49188 /** 49189 * Internal dependencies 49190 */ 49191 49192 49193 49194 49195 49196 const WithToolTip = ({ 49197 showTooltip, 49198 title, 49199 children 49200 }) => { 49201 if (showTooltip) { 49202 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tooltip, { 49203 text: title, 49204 children: children 49205 }); 49206 } 49207 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 49208 children: children 49209 }); 49210 }; 49211 function BlockPattern({ 49212 id, 49213 isDraggable, 49214 pattern, 49215 onClick, 49216 onHover, 49217 showTitlesAsTooltip, 49218 category, 49219 isSelected 49220 }) { 49221 const [isDragging, setIsDragging] = (0,external_wp_element_namespaceObject.useState)(false); 49222 const { 49223 blocks, 49224 viewportWidth 49225 } = pattern; 49226 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockPattern); 49227 const descriptionId = `block-editor-block-patterns-list__item-description-$instanceId}`; 49228 const isUserPattern = pattern.type === INSERTER_PATTERN_TYPES.user; 49229 49230 // When we have a selected category and the pattern is draggable, we need to update the 49231 // pattern's categories in metadata to only contain the selected category, and pass this to 49232 // InserterDraggableBlocks component. We do that because we use this information for pattern 49233 // shuffling and it makes more sense to show only the ones from the initially selected category during insertion. 49234 const patternBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => { 49235 if (!category || !isDraggable) { 49236 return blocks; 49237 } 49238 return (blocks !== null && blocks !== void 0 ? blocks : []).map(block => { 49239 const clonedBlock = (0,external_wp_blocks_namespaceObject.cloneBlock)(block); 49240 if (clonedBlock.attributes.metadata?.categories?.includes(category)) { 49241 clonedBlock.attributes.metadata.categories = [category]; 49242 } 49243 return clonedBlock; 49244 }); 49245 }, [blocks, isDraggable, category]); 49246 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_draggable_blocks, { 49247 isEnabled: isDraggable, 49248 blocks: patternBlocks, 49249 pattern: pattern, 49250 children: ({ 49251 draggable, 49252 onDragStart, 49253 onDragEnd 49254 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49255 className: "block-editor-block-patterns-list__list-item", 49256 draggable: draggable, 49257 onDragStart: event => { 49258 setIsDragging(true); 49259 if (onDragStart) { 49260 onHover?.(null); 49261 onDragStart(event); 49262 } 49263 }, 49264 onDragEnd: event => { 49265 setIsDragging(false); 49266 if (onDragEnd) { 49267 onDragEnd(event); 49268 } 49269 }, 49270 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WithToolTip, { 49271 showTooltip: showTitlesAsTooltip && !isUserPattern, 49272 title: pattern.title, 49273 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Composite.Item, { 49274 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49275 role: "option", 49276 "aria-label": pattern.title, 49277 "aria-describedby": pattern.description ? descriptionId : undefined, 49278 className: dist_clsx('block-editor-block-patterns-list__item', { 49279 'block-editor-block-patterns-list__list-item-synced': pattern.type === INSERTER_PATTERN_TYPES.user && !pattern.syncStatus, 49280 'is-selected': isSelected 49281 }) 49282 }), 49283 id: id, 49284 onClick: () => { 49285 onClick(pattern, blocks); 49286 onHover?.(null); 49287 }, 49288 onMouseEnter: () => { 49289 if (isDragging) { 49290 return; 49291 } 49292 onHover?.(pattern); 49293 }, 49294 onMouseLeave: () => onHover?.(null), 49295 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview.Async, { 49296 placeholder: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockPatternPlaceholder, {}), 49297 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview, { 49298 blocks: blocks, 49299 viewportWidth: viewportWidth 49300 }) 49301 }), (!showTitlesAsTooltip || isUserPattern) && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 49302 className: "block-editor-patterns__pattern-details", 49303 spacing: 2, 49304 children: [isUserPattern && !pattern.syncStatus && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49305 className: "block-editor-patterns__pattern-icon-wrapper", 49306 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 49307 className: "block-editor-patterns__pattern-icon", 49308 icon: library_symbol 49309 }) 49310 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49311 className: "block-editor-block-patterns-list__item-title", 49312 children: pattern.title 49313 })] 49314 }), !!pattern.description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 49315 id: descriptionId, 49316 children: pattern.description 49317 })] 49318 }) 49319 }) 49320 }) 49321 }); 49322 } 49323 function BlockPatternPlaceholder() { 49324 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 49325 className: "block-editor-block-patterns-list__item is-placeholder" 49326 }); 49327 } 49328 function BlockPatternsList({ 49329 isDraggable, 49330 blockPatterns, 49331 onHover, 49332 onClickPattern, 49333 orientation, 49334 label = (0,external_wp_i18n_namespaceObject.__)('Block patterns'), 49335 category, 49336 showTitlesAsTooltip, 49337 pagingProps 49338 }, ref) { 49339 const [activeCompositeId, setActiveCompositeId] = (0,external_wp_element_namespaceObject.useState)(undefined); 49340 const [activePattern, setActivePattern] = (0,external_wp_element_namespaceObject.useState)(null); // State to track active pattern 49341 49342 (0,external_wp_element_namespaceObject.useEffect)(() => { 49343 // Reset the active composite item whenever the available patterns change, 49344 // to make sure that Composite widget can receive focus correctly when its 49345 // composite items change. The first composite item will receive focus. 49346 const firstCompositeItemId = blockPatterns[0]?.name; 49347 setActiveCompositeId(firstCompositeItemId); 49348 }, [blockPatterns]); 49349 const handleClickPattern = (pattern, blocks) => { 49350 setActivePattern(pattern.name); 49351 onClickPattern(pattern, blocks); 49352 }; 49353 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Composite, { 49354 orientation: orientation, 49355 activeId: activeCompositeId, 49356 setActiveId: setActiveCompositeId, 49357 role: "listbox", 49358 className: "block-editor-block-patterns-list", 49359 "aria-label": label, 49360 ref: ref, 49361 children: [blockPatterns.map(pattern => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockPattern, { 49362 id: pattern.name, 49363 pattern: pattern, 49364 onClick: handleClickPattern, 49365 onHover: onHover, 49366 isDraggable: isDraggable, 49367 showTitlesAsTooltip: showTitlesAsTooltip, 49368 category: category, 49369 isSelected: !!activePattern && activePattern === pattern.name 49370 }, pattern.name)), pagingProps && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Pagination, { 49371 ...pagingProps 49372 })] 49373 }); 49374 } 49375 /* harmony default export */ const block_patterns_list = ((0,external_wp_element_namespaceObject.forwardRef)(BlockPatternsList)); 49376 49377 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-insertion-point.js 49378 /** 49379 * WordPress dependencies 49380 */ 49381 49382 49383 49384 49385 49386 49387 /** 49388 * Internal dependencies 49389 */ 49390 49391 49392 function getIndex({ 49393 destinationRootClientId, 49394 destinationIndex, 49395 rootClientId, 49396 registry 49397 }) { 49398 if (rootClientId === destinationRootClientId) { 49399 return destinationIndex; 49400 } 49401 const parents = ['', ...registry.select(store).getBlockParents(destinationRootClientId), destinationRootClientId]; 49402 const parentIndex = parents.indexOf(rootClientId); 49403 if (parentIndex !== -1) { 49404 return registry.select(store).getBlockIndex(parents[parentIndex + 1]) + 1; 49405 } 49406 return registry.select(store).getBlockOrder(rootClientId).length; 49407 } 49408 49409 /** 49410 * @typedef WPInserterConfig 49411 * 49412 * @property {string=} rootClientId If set, insertion will be into the 49413 * block with this ID. 49414 * @property {number=} insertionIndex If set, insertion will be into this 49415 * explicit position. 49416 * @property {string=} clientId If set, insertion will be after the 49417 * block with this ID. 49418 * @property {boolean=} isAppender Whether the inserter is an appender 49419 * or not. 49420 * @property {Function=} onSelect Called after insertion. 49421 */ 49422 49423 /** 49424 * Returns the insertion point state given the inserter config. 49425 * 49426 * @param {WPInserterConfig} config Inserter Config. 49427 * @return {Array} Insertion Point State (rootClientID, onInsertBlocks and onToggle). 49428 */ 49429 function useInsertionPoint({ 49430 rootClientId = '', 49431 insertionIndex, 49432 clientId, 49433 isAppender, 49434 onSelect, 49435 shouldFocusBlock = true, 49436 selectBlockOnInsert = true 49437 }) { 49438 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 49439 const { 49440 getSelectedBlock, 49441 getClosestAllowedInsertionPoint, 49442 isBlockInsertionPointVisible 49443 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 49444 const { 49445 destinationRootClientId, 49446 destinationIndex 49447 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 49448 const { 49449 getSelectedBlockClientId, 49450 getBlockRootClientId, 49451 getBlockIndex, 49452 getBlockOrder, 49453 getInsertionPoint 49454 } = unlock(select(store)); 49455 const selectedBlockClientId = getSelectedBlockClientId(); 49456 let _destinationRootClientId = rootClientId; 49457 let _destinationIndex; 49458 const insertionPoint = getInsertionPoint(); 49459 if (insertionIndex !== undefined) { 49460 // Insert into a specific index. 49461 _destinationIndex = insertionIndex; 49462 } else if (insertionPoint && insertionPoint.hasOwnProperty('index')) { 49463 _destinationRootClientId = insertionPoint?.rootClientId ? insertionPoint.rootClientId : rootClientId; 49464 _destinationIndex = insertionPoint.index; 49465 } else if (clientId) { 49466 // Insert after a specific client ID. 49467 _destinationIndex = getBlockIndex(clientId); 49468 } else if (!isAppender && selectedBlockClientId) { 49469 _destinationRootClientId = getBlockRootClientId(selectedBlockClientId); 49470 _destinationIndex = getBlockIndex(selectedBlockClientId) + 1; 49471 } else { 49472 // Insert at the end of the list. 49473 _destinationIndex = getBlockOrder(_destinationRootClientId).length; 49474 } 49475 return { 49476 destinationRootClientId: _destinationRootClientId, 49477 destinationIndex: _destinationIndex 49478 }; 49479 }, [rootClientId, insertionIndex, clientId, isAppender]); 49480 const { 49481 replaceBlocks, 49482 insertBlocks, 49483 showInsertionPoint, 49484 hideInsertionPoint, 49485 setLastFocus 49486 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 49487 const onInsertBlocks = (0,external_wp_element_namespaceObject.useCallback)((blocks, meta, shouldForceFocusBlock = false, _rootClientId) => { 49488 // When we are trying to move focus or select a new block on insert, we also 49489 // need to clear the last focus to avoid the focus being set to the wrong block 49490 // when tabbing back into the canvas if the block was added from outside the 49491 // editor canvas. 49492 if (shouldForceFocusBlock || shouldFocusBlock || selectBlockOnInsert) { 49493 setLastFocus(null); 49494 } 49495 const selectedBlock = getSelectedBlock(); 49496 if (!isAppender && selectedBlock && (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(selectedBlock)) { 49497 replaceBlocks(selectedBlock.clientId, blocks, null, shouldFocusBlock || shouldForceFocusBlock ? 0 : null, meta); 49498 } else { 49499 insertBlocks(blocks, isAppender || _rootClientId === undefined ? destinationIndex : getIndex({ 49500 destinationRootClientId, 49501 destinationIndex, 49502 rootClientId: _rootClientId, 49503 registry 49504 }), isAppender || _rootClientId === undefined ? destinationRootClientId : _rootClientId, selectBlockOnInsert, shouldFocusBlock || shouldForceFocusBlock ? 0 : null, meta); 49505 } 49506 const blockLength = Array.isArray(blocks) ? blocks.length : 1; 49507 const message = (0,external_wp_i18n_namespaceObject.sprintf)( 49508 // translators: %d: the name of the block that has been added 49509 (0,external_wp_i18n_namespaceObject._n)('%d block added.', '%d blocks added.', blockLength), blockLength); 49510 (0,external_wp_a11y_namespaceObject.speak)(message); 49511 if (onSelect) { 49512 onSelect(blocks); 49513 } 49514 }, [isAppender, getSelectedBlock, replaceBlocks, insertBlocks, destinationRootClientId, destinationIndex, onSelect, shouldFocusBlock, selectBlockOnInsert]); 49515 const onToggleInsertionPoint = (0,external_wp_element_namespaceObject.useCallback)(item => { 49516 if (item && !isBlockInsertionPointVisible()) { 49517 const allowedDestinationRootClientId = getClosestAllowedInsertionPoint(item.name, destinationRootClientId); 49518 if (allowedDestinationRootClientId !== null) { 49519 showInsertionPoint(allowedDestinationRootClientId, getIndex({ 49520 destinationRootClientId, 49521 destinationIndex, 49522 rootClientId: allowedDestinationRootClientId, 49523 registry 49524 })); 49525 } 49526 } else { 49527 hideInsertionPoint(); 49528 } 49529 }, [getClosestAllowedInsertionPoint, isBlockInsertionPointVisible, showInsertionPoint, hideInsertionPoint, destinationRootClientId, destinationIndex]); 49530 return [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint]; 49531 } 49532 /* harmony default export */ const use_insertion_point = (useInsertionPoint); 49533 49534 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-patterns-state.js 49535 /** 49536 * WordPress dependencies 49537 */ 49538 49539 49540 49541 49542 49543 49544 /** 49545 * Internal dependencies 49546 */ 49547 49548 49549 49550 49551 49552 /** 49553 * Retrieves the block patterns inserter state. 49554 * 49555 * @param {Function} onInsert function called when inserter a list of blocks. 49556 * @param {string=} rootClientId Insertion's root client ID. 49557 * @param {string} selectedCategory The selected pattern category. 49558 * @param {boolean} isQuick For the quick inserter render only allowed patterns. 49559 * 49560 * @return {Array} Returns the patterns state. (patterns, categories, onSelect handler) 49561 */ 49562 const usePatternsState = (onInsert, rootClientId, selectedCategory, isQuick) => { 49563 const options = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 49564 [isFiltered]: !!isQuick 49565 }), [isQuick]); 49566 const { 49567 patternCategories, 49568 patterns, 49569 userPatternCategories 49570 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 49571 const { 49572 getSettings, 49573 __experimentalGetAllowedPatterns 49574 } = unlock(select(store)); 49575 const { 49576 __experimentalUserPatternCategories, 49577 __experimentalBlockPatternCategories 49578 } = getSettings(); 49579 return { 49580 patterns: __experimentalGetAllowedPatterns(rootClientId, options), 49581 userPatternCategories: __experimentalUserPatternCategories, 49582 patternCategories: __experimentalBlockPatternCategories 49583 }; 49584 }, [rootClientId, options]); 49585 const { 49586 getClosestAllowedInsertionPointForPattern 49587 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 49588 const allCategories = (0,external_wp_element_namespaceObject.useMemo)(() => { 49589 const categories = [...patternCategories]; 49590 userPatternCategories?.forEach(userCategory => { 49591 if (!categories.find(existingCategory => existingCategory.name === userCategory.name)) { 49592 categories.push(userCategory); 49593 } 49594 }); 49595 return categories; 49596 }, [patternCategories, userPatternCategories]); 49597 const { 49598 createSuccessNotice 49599 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 49600 const onClickPattern = (0,external_wp_element_namespaceObject.useCallback)((pattern, blocks) => { 49601 const destinationRootClientId = isQuick ? rootClientId : getClosestAllowedInsertionPointForPattern(pattern, rootClientId); 49602 if (destinationRootClientId === null) { 49603 return; 49604 } 49605 const patternBlocks = pattern.type === INSERTER_PATTERN_TYPES.user && pattern.syncStatus !== 'unsynced' ? [(0,external_wp_blocks_namespaceObject.createBlock)('core/block', { 49606 ref: pattern.id 49607 })] : blocks; 49608 onInsert((patternBlocks !== null && patternBlocks !== void 0 ? patternBlocks : []).map(block => { 49609 const clonedBlock = (0,external_wp_blocks_namespaceObject.cloneBlock)(block); 49610 if (clonedBlock.attributes.metadata?.categories?.includes(selectedCategory)) { 49611 clonedBlock.attributes.metadata.categories = [selectedCategory]; 49612 } 49613 return clonedBlock; 49614 }), pattern.name, false, destinationRootClientId); 49615 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: block pattern title. */ 49616 (0,external_wp_i18n_namespaceObject.__)('Block pattern "%s" inserted.'), pattern.title), { 49617 type: 'snackbar', 49618 id: 'inserter-notice' 49619 }); 49620 }, [createSuccessNotice, onInsert, selectedCategory, rootClientId, getClosestAllowedInsertionPointForPattern, isQuick]); 49621 return [patterns, allCategories, onClickPattern]; 49622 }; 49623 /* harmony default export */ const use_patterns_state = (usePatternsState); 49624 49625 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js 49626 var remove_accents = __webpack_require__(9681); 49627 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 49628 ;// ./node_modules/lower-case/dist.es2015/index.js 49629 /** 49630 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 49631 */ 49632 var SUPPORTED_LOCALE = { 49633 tr: { 49634 regexp: /\u0130|\u0049|\u0049\u0307/g, 49635 map: { 49636 İ: "\u0069", 49637 I: "\u0131", 49638 İ: "\u0069", 49639 }, 49640 }, 49641 az: { 49642 regexp: /\u0130/g, 49643 map: { 49644 İ: "\u0069", 49645 I: "\u0131", 49646 İ: "\u0069", 49647 }, 49648 }, 49649 lt: { 49650 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 49651 map: { 49652 I: "\u0069\u0307", 49653 J: "\u006A\u0307", 49654 Į: "\u012F\u0307", 49655 Ì: "\u0069\u0307\u0300", 49656 Í: "\u0069\u0307\u0301", 49657 Ĩ: "\u0069\u0307\u0303", 49658 }, 49659 }, 49660 }; 49661 /** 49662 * Localized lower case. 49663 */ 49664 function localeLowerCase(str, locale) { 49665 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 49666 if (lang) 49667 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 49668 return lowerCase(str); 49669 } 49670 /** 49671 * Lower case as a function. 49672 */ 49673 function lowerCase(str) { 49674 return str.toLowerCase(); 49675 } 49676 49677 ;// ./node_modules/no-case/dist.es2015/index.js 49678 49679 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 49680 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 49681 // Remove all non-word characters. 49682 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 49683 /** 49684 * Normalize the string into something other libraries can manipulate easier. 49685 */ 49686 function noCase(input, options) { 49687 if (options === void 0) { options = {}; } 49688 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; 49689 var result = dist_es2015_replace(dist_es2015_replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 49690 var start = 0; 49691 var end = result.length; 49692 // Trim the delimiter from around the output string. 49693 while (result.charAt(start) === "\0") 49694 start++; 49695 while (result.charAt(end - 1) === "\0") 49696 end--; 49697 // Transform each token independently. 49698 return result.slice(start, end).split("\0").map(transform).join(delimiter); 49699 } 49700 /** 49701 * Replace `re` in the input string with the replacement value. 49702 */ 49703 function dist_es2015_replace(input, re, value) { 49704 if (re instanceof RegExp) 49705 return input.replace(re, value); 49706 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 49707 } 49708 49709 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/search-items.js 49710 /** 49711 * External dependencies 49712 */ 49713 49714 49715 49716 // Default search helpers. 49717 const defaultGetName = item => item.name || ''; 49718 const defaultGetTitle = item => item.title; 49719 const defaultGetDescription = item => item.description || ''; 49720 const defaultGetKeywords = item => item.keywords || []; 49721 const defaultGetCategory = item => item.category; 49722 const defaultGetCollection = () => null; 49723 49724 // Normalization regexes 49725 const splitRegexp = [/([\p{Ll}\p{Lo}\p{N}])([\p{Lu}\p{Lt}])/gu, 49726 // One lowercase or digit, followed by one uppercase. 49727 /([\p{Lu}\p{Lt}])([\p{Lu}\p{Lt}][\p{Ll}\p{Lo}])/gu // One uppercase followed by one uppercase and one lowercase. 49728 ]; 49729 const stripRegexp = /(\p{C}|\p{P}|\p{S})+/giu; // Anything that's not a punctuation, symbol or control/format character. 49730 49731 // Normalization cache 49732 const extractedWords = new Map(); 49733 const normalizedStrings = new Map(); 49734 49735 /** 49736 * Extracts words from an input string. 49737 * 49738 * @param {string} input The input string. 49739 * 49740 * @return {Array} Words, extracted from the input string. 49741 */ 49742 function extractWords(input = '') { 49743 if (extractedWords.has(input)) { 49744 return extractedWords.get(input); 49745 } 49746 const result = noCase(input, { 49747 splitRegexp, 49748 stripRegexp 49749 }).split(' ').filter(Boolean); 49750 extractedWords.set(input, result); 49751 return result; 49752 } 49753 49754 /** 49755 * Sanitizes the search input string. 49756 * 49757 * @param {string} input The search input to normalize. 49758 * 49759 * @return {string} The normalized search input. 49760 */ 49761 function normalizeString(input = '') { 49762 if (normalizedStrings.has(input)) { 49763 return normalizedStrings.get(input); 49764 } 49765 49766 // Disregard diacritics. 49767 // Input: "média" 49768 let result = remove_accents_default()(input); 49769 49770 // Accommodate leading slash, matching autocomplete expectations. 49771 // Input: "/media" 49772 result = result.replace(/^\//, ''); 49773 49774 // Lowercase. 49775 // Input: "MEDIA" 49776 result = result.toLowerCase(); 49777 normalizedStrings.set(input, result); 49778 return result; 49779 } 49780 49781 /** 49782 * Converts the search term into a list of normalized terms. 49783 * 49784 * @param {string} input The search term to normalize. 49785 * 49786 * @return {string[]} The normalized list of search terms. 49787 */ 49788 const getNormalizedSearchTerms = (input = '') => { 49789 return extractWords(normalizeString(input)); 49790 }; 49791 const removeMatchingTerms = (unmatchedTerms, unprocessedTerms) => { 49792 return unmatchedTerms.filter(term => !getNormalizedSearchTerms(unprocessedTerms).some(unprocessedTerm => unprocessedTerm.includes(term))); 49793 }; 49794 const searchBlockItems = (items, categories, collections, searchInput) => { 49795 const normalizedSearchTerms = getNormalizedSearchTerms(searchInput); 49796 if (normalizedSearchTerms.length === 0) { 49797 return items; 49798 } 49799 const config = { 49800 getCategory: item => categories.find(({ 49801 slug 49802 }) => slug === item.category)?.title, 49803 getCollection: item => collections[item.name.split('/')[0]]?.title 49804 }; 49805 return searchItems(items, searchInput, config); 49806 }; 49807 49808 /** 49809 * Filters an item list given a search term. 49810 * 49811 * @param {Array} items Item list 49812 * @param {string} searchInput Search input. 49813 * @param {Object} config Search Config. 49814 * 49815 * @return {Array} Filtered item list. 49816 */ 49817 const searchItems = (items = [], searchInput = '', config = {}) => { 49818 const normalizedSearchTerms = getNormalizedSearchTerms(searchInput); 49819 if (normalizedSearchTerms.length === 0) { 49820 return items; 49821 } 49822 const rankedItems = items.map(item => { 49823 return [item, getItemSearchRank(item, searchInput, config)]; 49824 }).filter(([, rank]) => rank > 0); 49825 rankedItems.sort(([, rank1], [, rank2]) => rank2 - rank1); 49826 return rankedItems.map(([item]) => item); 49827 }; 49828 49829 /** 49830 * Get the search rank for a given item and a specific search term. 49831 * The better the match, the higher the rank. 49832 * If the rank equals 0, it should be excluded from the results. 49833 * 49834 * @param {Object} item Item to filter. 49835 * @param {string} searchTerm Search term. 49836 * @param {Object} config Search Config. 49837 * 49838 * @return {number} Search Rank. 49839 */ 49840 function getItemSearchRank(item, searchTerm, config = {}) { 49841 const { 49842 getName = defaultGetName, 49843 getTitle = defaultGetTitle, 49844 getDescription = defaultGetDescription, 49845 getKeywords = defaultGetKeywords, 49846 getCategory = defaultGetCategory, 49847 getCollection = defaultGetCollection 49848 } = config; 49849 const name = getName(item); 49850 const title = getTitle(item); 49851 const description = getDescription(item); 49852 const keywords = getKeywords(item); 49853 const category = getCategory(item); 49854 const collection = getCollection(item); 49855 const normalizedSearchInput = normalizeString(searchTerm); 49856 const normalizedTitle = normalizeString(title); 49857 let rank = 0; 49858 49859 // Prefers exact matches 49860 // Then prefers if the beginning of the title matches the search term 49861 // name, keywords, categories, collection, variations match come later. 49862 if (normalizedSearchInput === normalizedTitle) { 49863 rank += 30; 49864 } else if (normalizedTitle.startsWith(normalizedSearchInput)) { 49865 rank += 20; 49866 } else { 49867 const terms = [name, title, description, ...keywords, category, collection].join(' '); 49868 const normalizedSearchTerms = extractWords(normalizedSearchInput); 49869 const unmatchedTerms = removeMatchingTerms(normalizedSearchTerms, terms); 49870 if (unmatchedTerms.length === 0) { 49871 rank += 10; 49872 } 49873 } 49874 49875 // Give a better rank to "core" namespaced items. 49876 if (rank !== 0 && name.startsWith('core/')) { 49877 const isCoreBlockVariation = name !== item.id; 49878 // Give a bit better rank to "core" blocks over "core" block variations. 49879 rank += isCoreBlockVariation ? 1 : 2; 49880 } 49881 return rank; 49882 } 49883 49884 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-patterns-paging.js 49885 /** 49886 * WordPress dependencies 49887 */ 49888 49889 49890 49891 const PAGE_SIZE = 20; 49892 49893 /** 49894 * Supplies values needed to page the patterns list client side. 49895 * 49896 * @param {Array} currentCategoryPatterns An array of the current patterns to display. 49897 * @param {string} currentCategory The currently selected category. 49898 * @param {Object} scrollContainerRef Ref of container to to find scroll container for when moving between pages. 49899 * @param {string} currentFilter The currently search filter. 49900 * 49901 * @return {Object} Returns the relevant paging values. (totalItems, categoryPatternsList, numPages, changePage, currentPage) 49902 */ 49903 function usePatternsPaging(currentCategoryPatterns, currentCategory, scrollContainerRef, currentFilter = '') { 49904 const [currentPage, setCurrentPage] = (0,external_wp_element_namespaceObject.useState)(1); 49905 const previousCategory = (0,external_wp_compose_namespaceObject.usePrevious)(currentCategory); 49906 const previousFilter = (0,external_wp_compose_namespaceObject.usePrevious)(currentFilter); 49907 if ((previousCategory !== currentCategory || previousFilter !== currentFilter) && currentPage !== 1) { 49908 setCurrentPage(1); 49909 } 49910 const totalItems = currentCategoryPatterns.length; 49911 const pageIndex = currentPage - 1; 49912 const categoryPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => { 49913 return currentCategoryPatterns.slice(pageIndex * PAGE_SIZE, pageIndex * PAGE_SIZE + PAGE_SIZE); 49914 }, [pageIndex, currentCategoryPatterns]); 49915 const numPages = Math.ceil(currentCategoryPatterns.length / PAGE_SIZE); 49916 const changePage = page => { 49917 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(scrollContainerRef?.current); 49918 scrollContainer?.scrollTo(0, 0); 49919 setCurrentPage(page); 49920 }; 49921 (0,external_wp_element_namespaceObject.useEffect)(function scrollToTopOnCategoryChange() { 49922 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(scrollContainerRef?.current); 49923 scrollContainer?.scrollTo(0, 0); 49924 }, [currentCategory, scrollContainerRef]); 49925 return { 49926 totalItems, 49927 categoryPatterns, 49928 numPages, 49929 changePage, 49930 currentPage 49931 }; 49932 } 49933 49934 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/pattern-list.js 49935 /** 49936 * WordPress dependencies 49937 */ 49938 49939 49940 49941 49942 49943 49944 /** 49945 * Internal dependencies 49946 */ 49947 49948 49949 49950 49951 49952 49953 49954 49955 49956 function PatternsListHeader({ 49957 filterValue, 49958 filteredBlockPatternsLength 49959 }) { 49960 if (!filterValue) { 49961 return null; 49962 } 49963 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalHeading, { 49964 level: 2, 49965 lineHeight: "48px", 49966 className: "block-editor-block-patterns-explorer__search-results-count", 49967 children: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of patterns. */ 49968 (0,external_wp_i18n_namespaceObject._n)('%d pattern found', '%d patterns found', filteredBlockPatternsLength), filteredBlockPatternsLength) 49969 }); 49970 } 49971 function PatternList({ 49972 searchValue, 49973 selectedCategory, 49974 patternCategories, 49975 rootClientId, 49976 onModalClose 49977 }) { 49978 const container = (0,external_wp_element_namespaceObject.useRef)(); 49979 const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500); 49980 const [destinationRootClientId, onInsertBlocks] = use_insertion_point({ 49981 rootClientId, 49982 shouldFocusBlock: true 49983 }); 49984 const [patterns,, onClickPattern] = use_patterns_state(onInsertBlocks, destinationRootClientId, selectedCategory); 49985 const registeredPatternCategories = (0,external_wp_element_namespaceObject.useMemo)(() => patternCategories.map(patternCategory => patternCategory.name), [patternCategories]); 49986 const filteredBlockPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => { 49987 const filteredPatterns = patterns.filter(pattern => { 49988 if (selectedCategory === allPatternsCategory.name) { 49989 return true; 49990 } 49991 if (selectedCategory === myPatternsCategory.name && pattern.type === INSERTER_PATTERN_TYPES.user) { 49992 return true; 49993 } 49994 if (selectedCategory === starterPatternsCategory.name && pattern.blockTypes?.includes('core/post-content')) { 49995 return true; 49996 } 49997 if (selectedCategory === 'uncategorized') { 49998 var _pattern$categories$s; 49999 const hasKnownCategory = (_pattern$categories$s = pattern.categories?.some(category => registeredPatternCategories.includes(category))) !== null && _pattern$categories$s !== void 0 ? _pattern$categories$s : false; 50000 return !pattern.categories?.length || !hasKnownCategory; 50001 } 50002 return pattern.categories?.includes(selectedCategory); 50003 }); 50004 if (!searchValue) { 50005 return filteredPatterns; 50006 } 50007 return searchItems(filteredPatterns, searchValue); 50008 }, [searchValue, patterns, selectedCategory, registeredPatternCategories]); 50009 50010 // Announce search results on change. 50011 (0,external_wp_element_namespaceObject.useEffect)(() => { 50012 if (!searchValue) { 50013 return; 50014 } 50015 const count = filteredBlockPatterns.length; 50016 const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of results. */ 50017 (0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count); 50018 debouncedSpeak(resultsFoundMessage); 50019 }, [searchValue, debouncedSpeak, filteredBlockPatterns.length]); 50020 const pagingProps = usePatternsPaging(filteredBlockPatterns, selectedCategory, container); 50021 50022 // Reset page when search value changes. 50023 const [previousSearchValue, setPreviousSearchValue] = (0,external_wp_element_namespaceObject.useState)(searchValue); 50024 if (searchValue !== previousSearchValue) { 50025 setPreviousSearchValue(searchValue); 50026 pagingProps.changePage(1); 50027 } 50028 const hasItems = !!filteredBlockPatterns?.length; 50029 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 50030 className: "block-editor-block-patterns-explorer__list", 50031 ref: container, 50032 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternsListHeader, { 50033 filterValue: searchValue, 50034 filteredBlockPatternsLength: filteredBlockPatterns.length 50035 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_listbox, { 50036 children: hasItems && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50037 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_patterns_list, { 50038 blockPatterns: pagingProps.categoryPatterns, 50039 onClickPattern: (pattern, blocks) => { 50040 onClickPattern(pattern, blocks); 50041 onModalClose(); 50042 }, 50043 isDraggable: false 50044 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Pagination, { 50045 ...pagingProps 50046 })] 50047 }) 50048 })] 50049 }); 50050 } 50051 /* harmony default export */ const pattern_list = (PatternList); 50052 50053 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/use-pattern-categories.js 50054 /** 50055 * WordPress dependencies 50056 */ 50057 50058 50059 50060 50061 /** 50062 * Internal dependencies 50063 */ 50064 50065 50066 function hasRegisteredCategory(pattern, allCategories) { 50067 if (!pattern.categories || !pattern.categories.length) { 50068 return false; 50069 } 50070 return pattern.categories.some(cat => allCategories.some(category => category.name === cat)); 50071 } 50072 function usePatternCategories(rootClientId, sourceFilter = 'all') { 50073 const [patterns, allCategories] = use_patterns_state(undefined, rootClientId); 50074 const filteredPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => sourceFilter === 'all' ? patterns : patterns.filter(pattern => !isPatternFiltered(pattern, sourceFilter)), [sourceFilter, patterns]); 50075 50076 // Remove any empty categories. 50077 const populatedCategories = (0,external_wp_element_namespaceObject.useMemo)(() => { 50078 const categories = allCategories.filter(category => filteredPatterns.some(pattern => pattern.categories?.includes(category.name))).sort((a, b) => a.label.localeCompare(b.label)); 50079 if (filteredPatterns.some(pattern => !hasRegisteredCategory(pattern, allCategories)) && !categories.find(category => category.name === 'uncategorized')) { 50080 categories.push({ 50081 name: 'uncategorized', 50082 label: (0,external_wp_i18n_namespaceObject._x)('Uncategorized') 50083 }); 50084 } 50085 if (filteredPatterns.some(pattern => pattern.blockTypes?.includes('core/post-content'))) { 50086 categories.unshift(starterPatternsCategory); 50087 } 50088 if (filteredPatterns.some(pattern => pattern.type === INSERTER_PATTERN_TYPES.user)) { 50089 categories.unshift(myPatternsCategory); 50090 } 50091 if (filteredPatterns.length > 0) { 50092 categories.unshift({ 50093 name: allPatternsCategory.name, 50094 label: allPatternsCategory.label 50095 }); 50096 } 50097 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of categories . */ 50098 (0,external_wp_i18n_namespaceObject._n)('%d category button displayed.', '%d category buttons displayed.', categories.length), categories.length)); 50099 return categories; 50100 }, [allCategories, filteredPatterns]); 50101 return populatedCategories; 50102 } 50103 50104 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/index.js 50105 /** 50106 * WordPress dependencies 50107 */ 50108 50109 50110 50111 50112 /** 50113 * Internal dependencies 50114 */ 50115 50116 50117 50118 50119 function PatternsExplorer({ 50120 initialCategory, 50121 rootClientId, 50122 onModalClose 50123 }) { 50124 const [searchValue, setSearchValue] = (0,external_wp_element_namespaceObject.useState)(''); 50125 const [selectedCategory, setSelectedCategory] = (0,external_wp_element_namespaceObject.useState)(initialCategory?.name); 50126 const patternCategories = usePatternCategories(rootClientId); 50127 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 50128 className: "block-editor-block-patterns-explorer", 50129 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(pattern_explorer_sidebar, { 50130 selectedCategory: selectedCategory, 50131 patternCategories: patternCategories, 50132 onClickCategory: setSelectedCategory, 50133 searchValue: searchValue, 50134 setSearchValue: setSearchValue 50135 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(pattern_list, { 50136 searchValue: searchValue, 50137 selectedCategory: selectedCategory, 50138 patternCategories: patternCategories, 50139 rootClientId: rootClientId, 50140 onModalClose: onModalClose 50141 })] 50142 }); 50143 } 50144 function PatternsExplorerModal({ 50145 onModalClose, 50146 ...restProps 50147 }) { 50148 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Modal, { 50149 title: (0,external_wp_i18n_namespaceObject.__)('Patterns'), 50150 onRequestClose: onModalClose, 50151 isFullScreen: true, 50152 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternsExplorer, { 50153 onModalClose: onModalClose, 50154 ...restProps 50155 }) 50156 }); 50157 } 50158 /* harmony default export */ const block_patterns_explorer = (PatternsExplorerModal); 50159 50160 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/mobile-tab-navigation.js 50161 /** 50162 * WordPress dependencies 50163 */ 50164 50165 50166 50167 50168 function ScreenHeader({ 50169 title 50170 }) { 50171 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalVStack, { 50172 spacing: 0, 50173 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalView, { 50174 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalSpacer, { 50175 marginBottom: 0, 50176 paddingX: 4, 50177 paddingY: 3, 50178 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 50179 spacing: 2, 50180 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Navigator.BackButton, { 50181 style: 50182 // TODO: This style override is also used in ToolsPanelHeader. 50183 // It should be supported out-of-the-box by Button. 50184 { 50185 minWidth: 24, 50186 padding: 0 50187 }, 50188 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left, 50189 size: "small", 50190 label: (0,external_wp_i18n_namespaceObject.__)('Back') 50191 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalSpacer, { 50192 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalHeading, { 50193 level: 5, 50194 children: title 50195 }) 50196 })] 50197 }) 50198 }) 50199 }) 50200 }); 50201 } 50202 function MobileTabNavigation({ 50203 categories, 50204 children 50205 }) { 50206 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Navigator, { 50207 initialPath: "/", 50208 className: "block-editor-inserter__mobile-tab-navigation", 50209 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Navigator.Screen, { 50210 path: "/", 50211 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalItemGroup, { 50212 children: categories.map(category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Navigator.Button, { 50213 path: `/category/$category.name}`, 50214 as: external_wp_components_namespaceObject.__experimentalItem, 50215 isAction: true, 50216 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 50217 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexBlock, { 50218 children: category.label 50219 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 50220 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right 50221 })] 50222 }) 50223 }, category.name)) 50224 }) 50225 }), categories.map(category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Navigator.Screen, { 50226 path: `/category/$category.name}`, 50227 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ScreenHeader, { 50228 title: (0,external_wp_i18n_namespaceObject.__)('Back') 50229 }), children(category)] 50230 }, category.name))] 50231 }); 50232 } 50233 50234 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/patterns-filter.js 50235 /** 50236 * WordPress dependencies 50237 */ 50238 50239 50240 50241 50242 50243 /** 50244 * Internal dependencies 50245 */ 50246 50247 50248 const getShouldDisableSyncFilter = sourceFilter => sourceFilter !== 'all' && sourceFilter !== 'user'; 50249 const getShouldHideSourcesFilter = category => { 50250 return category.name === myPatternsCategory.name; 50251 }; 50252 const PATTERN_SOURCE_MENU_OPTIONS = [{ 50253 value: 'all', 50254 label: (0,external_wp_i18n_namespaceObject._x)('All', 'patterns') 50255 }, { 50256 value: INSERTER_PATTERN_TYPES.directory, 50257 label: (0,external_wp_i18n_namespaceObject.__)('Pattern Directory') 50258 }, { 50259 value: INSERTER_PATTERN_TYPES.theme, 50260 label: (0,external_wp_i18n_namespaceObject.__)('Theme & Plugins') 50261 }, { 50262 value: INSERTER_PATTERN_TYPES.user, 50263 label: (0,external_wp_i18n_namespaceObject.__)('User') 50264 }]; 50265 function PatternsFilter({ 50266 setPatternSyncFilter, 50267 setPatternSourceFilter, 50268 patternSyncFilter, 50269 patternSourceFilter, 50270 scrollContainerRef, 50271 category 50272 }) { 50273 // If the category is `myPatterns` then we need to set the source filter to `user`, but 50274 // we do this by deriving from props rather than calling setPatternSourceFilter otherwise 50275 // the user may be confused when switching to another category if the haven't explicitly set 50276 // this filter themselves. 50277 const currentPatternSourceFilter = category.name === myPatternsCategory.name ? INSERTER_PATTERN_TYPES.user : patternSourceFilter; 50278 50279 // We need to disable the sync filter option if the source filter is not 'all' or 'user' 50280 // otherwise applying them will just result in no patterns being shown. 50281 const shouldDisableSyncFilter = getShouldDisableSyncFilter(currentPatternSourceFilter); 50282 50283 // We also hide the directory and theme source filter if the category is `myPatterns` 50284 // otherwise there will only be one option available. 50285 const shouldHideSourcesFilter = getShouldHideSourcesFilter(category); 50286 const patternSyncMenuOptions = (0,external_wp_element_namespaceObject.useMemo)(() => [{ 50287 value: 'all', 50288 label: (0,external_wp_i18n_namespaceObject._x)('All', 'patterns') 50289 }, { 50290 value: INSERTER_SYNC_TYPES.full, 50291 label: (0,external_wp_i18n_namespaceObject._x)('Synced', 'patterns'), 50292 disabled: shouldDisableSyncFilter 50293 }, { 50294 value: INSERTER_SYNC_TYPES.unsynced, 50295 label: (0,external_wp_i18n_namespaceObject._x)('Not synced', 'patterns'), 50296 disabled: shouldDisableSyncFilter 50297 }], [shouldDisableSyncFilter]); 50298 function handleSetSourceFilterChange(newSourceFilter) { 50299 setPatternSourceFilter(newSourceFilter); 50300 if (getShouldDisableSyncFilter(newSourceFilter)) { 50301 setPatternSyncFilter('all'); 50302 } 50303 } 50304 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50305 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 50306 popoverProps: { 50307 placement: 'right-end' 50308 }, 50309 label: (0,external_wp_i18n_namespaceObject.__)('Filter patterns'), 50310 toggleProps: { 50311 size: 'compact' 50312 }, 50313 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 50314 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SVG, { 50315 width: "24", 50316 height: "24", 50317 viewBox: "0 0 24 24", 50318 fill: "none", 50319 xmlns: "http://www.w3.org/2000/svg", 50320 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Path, { 50321 d: "M10 17.5H14V16H10V17.5ZM6 6V7.5H18V6H6ZM8 12.5H16V11H8V12.5Z", 50322 fill: "currentColor" 50323 }) 50324 }) 50325 }), 50326 children: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50327 children: [!shouldHideSourcesFilter && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 50328 label: (0,external_wp_i18n_namespaceObject.__)('Source'), 50329 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItemsChoice, { 50330 choices: PATTERN_SOURCE_MENU_OPTIONS, 50331 onSelect: value => { 50332 handleSetSourceFilterChange(value); 50333 scrollContainerRef.current?.scrollTo(0, 0); 50334 }, 50335 value: currentPatternSourceFilter 50336 }) 50337 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 50338 label: (0,external_wp_i18n_namespaceObject.__)('Type'), 50339 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItemsChoice, { 50340 choices: patternSyncMenuOptions, 50341 onSelect: value => { 50342 setPatternSyncFilter(value); 50343 scrollContainerRef.current?.scrollTo(0, 0); 50344 }, 50345 value: patternSyncFilter 50346 }) 50347 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 50348 className: "block-editor-inserter__patterns-filter-help", 50349 children: (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.'), { 50350 Link: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ExternalLink, { 50351 href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/patterns/') 50352 }) 50353 }) 50354 })] 50355 }) 50356 }) 50357 }); 50358 } 50359 50360 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/pattern-category-previews.js 50361 /** 50362 * WordPress dependencies 50363 */ 50364 50365 50366 50367 50368 /** 50369 * Internal dependencies 50370 */ 50371 50372 50373 50374 50375 50376 50377 50378 const pattern_category_previews_noop = () => {}; 50379 function PatternCategoryPreviews({ 50380 rootClientId, 50381 onInsert, 50382 onHover = pattern_category_previews_noop, 50383 category, 50384 showTitlesAsTooltip 50385 }) { 50386 const [allPatterns,, onClickPattern] = use_patterns_state(onInsert, rootClientId, category?.name); 50387 const [patternSyncFilter, setPatternSyncFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 50388 const [patternSourceFilter, setPatternSourceFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 50389 const availableCategories = usePatternCategories(rootClientId, patternSourceFilter); 50390 const scrollContainerRef = (0,external_wp_element_namespaceObject.useRef)(); 50391 const currentCategoryPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => allPatterns.filter(pattern => { 50392 if (isPatternFiltered(pattern, patternSourceFilter, patternSyncFilter)) { 50393 return false; 50394 } 50395 if (category.name === allPatternsCategory.name) { 50396 return true; 50397 } 50398 if (category.name === myPatternsCategory.name && pattern.type === INSERTER_PATTERN_TYPES.user) { 50399 return true; 50400 } 50401 if (category.name === starterPatternsCategory.name && pattern.blockTypes?.includes('core/post-content')) { 50402 return true; 50403 } 50404 if (category.name === 'uncategorized') { 50405 // The uncategorized category should show all the patterns without any category... 50406 if (!pattern.categories) { 50407 return true; 50408 } 50409 50410 // ...or with no available category. 50411 return !pattern.categories.some(catName => availableCategories.some(c => c.name === catName)); 50412 } 50413 return pattern.categories?.includes(category.name); 50414 }), [allPatterns, availableCategories, category.name, patternSourceFilter, patternSyncFilter]); 50415 const pagingProps = usePatternsPaging(currentCategoryPatterns, category, scrollContainerRef); 50416 const { 50417 changePage 50418 } = pagingProps; 50419 50420 // Hide block pattern preview on unmount. 50421 (0,external_wp_element_namespaceObject.useEffect)(() => () => onHover(null), []); 50422 const onSetPatternSyncFilter = (0,external_wp_element_namespaceObject.useCallback)(value => { 50423 setPatternSyncFilter(value); 50424 changePage(1); 50425 }, [setPatternSyncFilter, changePage]); 50426 const onSetPatternSourceFilter = (0,external_wp_element_namespaceObject.useCallback)(value => { 50427 setPatternSourceFilter(value); 50428 changePage(1); 50429 }, [setPatternSourceFilter, changePage]); 50430 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50431 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 50432 spacing: 2, 50433 className: "block-editor-inserter__patterns-category-panel-header", 50434 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 50435 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexBlock, { 50436 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalHeading, { 50437 className: "block-editor-inserter__patterns-category-panel-title", 50438 size: 13, 50439 level: 4, 50440 as: "div", 50441 children: category.label 50442 }) 50443 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternsFilter, { 50444 patternSyncFilter: patternSyncFilter, 50445 patternSourceFilter: patternSourceFilter, 50446 setPatternSyncFilter: onSetPatternSyncFilter, 50447 setPatternSourceFilter: onSetPatternSourceFilter, 50448 scrollContainerRef: scrollContainerRef, 50449 category: category 50450 })] 50451 }), !currentCategoryPatterns.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 50452 variant: "muted", 50453 className: "block-editor-inserter__patterns-category-no-results", 50454 children: (0,external_wp_i18n_namespaceObject.__)('No results found') 50455 })] 50456 }), currentCategoryPatterns.length > 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50457 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 50458 size: "12", 50459 as: "p", 50460 className: "block-editor-inserter__help-text", 50461 children: (0,external_wp_i18n_namespaceObject.__)('Drag and drop patterns into the canvas.') 50462 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_patterns_list, { 50463 ref: scrollContainerRef, 50464 blockPatterns: pagingProps.categoryPatterns, 50465 onClickPattern: onClickPattern, 50466 onHover: onHover, 50467 label: category.label, 50468 orientation: "vertical", 50469 category: category.name, 50470 isDraggable: true, 50471 showTitlesAsTooltip: showTitlesAsTooltip, 50472 patternFilter: patternSourceFilter, 50473 pagingProps: pagingProps 50474 })] 50475 })] 50476 }); 50477 } 50478 50479 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/category-tabs/index.js 50480 /** 50481 * WordPress dependencies 50482 */ 50483 50484 50485 50486 50487 /** 50488 * Internal dependencies 50489 */ 50490 50491 50492 const { 50493 Tabs: category_tabs_Tabs 50494 } = unlock(external_wp_components_namespaceObject.privateApis); 50495 function CategoryTabs({ 50496 categories, 50497 selectedCategory, 50498 onSelectCategory, 50499 children 50500 }) { 50501 // Copied from InterfaceSkeleton. 50502 const ANIMATION_DURATION = 0.25; 50503 const disableMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)(); 50504 const defaultTransition = { 50505 type: 'tween', 50506 duration: disableMotion ? 0 : ANIMATION_DURATION, 50507 ease: [0.6, 0, 0.4, 1] 50508 }; 50509 const previousSelectedCategory = (0,external_wp_compose_namespaceObject.usePrevious)(selectedCategory); 50510 const selectedTabId = selectedCategory ? selectedCategory.name : null; 50511 const [activeTabId, setActiveId] = (0,external_wp_element_namespaceObject.useState)(); 50512 const firstTabId = categories?.[0]?.name; 50513 50514 // If there is no active tab, make the first tab the active tab, so that 50515 // when focus is moved to the tablist, the first tab will be focused 50516 // despite not being selected 50517 if (selectedTabId === null && !activeTabId && firstTabId) { 50518 setActiveId(firstTabId); 50519 } 50520 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(category_tabs_Tabs, { 50521 selectOnMove: false, 50522 selectedTabId: selectedTabId, 50523 orientation: "vertical", 50524 onSelect: categoryId => { 50525 // Pass the full category object 50526 onSelectCategory(categories.find(category => category.name === categoryId)); 50527 }, 50528 activeTabId: activeTabId, 50529 onActiveTabIdChange: setActiveId, 50530 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(category_tabs_Tabs.TabList, { 50531 className: "block-editor-inserter__category-tablist", 50532 children: categories.map(category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(category_tabs_Tabs.Tab, { 50533 tabId: category.name, 50534 "aria-current": category === selectedCategory ? 'true' : undefined, 50535 children: category.label 50536 }, category.name)) 50537 }), categories.map(category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(category_tabs_Tabs.TabPanel, { 50538 tabId: category.name, 50539 focusable: false, 50540 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 50541 className: "block-editor-inserter__category-panel", 50542 initial: !previousSelectedCategory ? 'closed' : 'open', 50543 animate: "open", 50544 variants: { 50545 open: { 50546 transform: 'translateX( 0 )', 50547 transitionEnd: { 50548 zIndex: '1' 50549 } 50550 }, 50551 closed: { 50552 transform: 'translateX( -100% )', 50553 zIndex: '-1' 50554 } 50555 }, 50556 transition: defaultTransition, 50557 children: children 50558 }) 50559 }, category.name))] 50560 }); 50561 } 50562 /* harmony default export */ const category_tabs = (CategoryTabs); 50563 50564 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab/index.js 50565 /** 50566 * WordPress dependencies 50567 */ 50568 50569 50570 50571 50572 50573 /** 50574 * Internal dependencies 50575 */ 50576 50577 50578 50579 50580 50581 50582 50583 function BlockPatternsTab({ 50584 onSelectCategory, 50585 selectedCategory, 50586 onInsert, 50587 rootClientId, 50588 children 50589 }) { 50590 const [showPatternsExplorer, setShowPatternsExplorer] = (0,external_wp_element_namespaceObject.useState)(false); 50591 const categories = usePatternCategories(rootClientId); 50592 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 50593 if (!categories.length) { 50594 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(no_results, {}); 50595 } 50596 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50597 children: [!isMobile && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 50598 className: "block-editor-inserter__block-patterns-tabs-container", 50599 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(category_tabs, { 50600 categories: categories, 50601 selectedCategory: selectedCategory, 50602 onSelectCategory: onSelectCategory, 50603 children: children 50604 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 50605 __next40pxDefaultSize: true, 50606 className: "block-editor-inserter__patterns-explore-button", 50607 onClick: () => setShowPatternsExplorer(true), 50608 variant: "secondary", 50609 children: (0,external_wp_i18n_namespaceObject.__)('Explore all patterns') 50610 })] 50611 }), isMobile && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MobileTabNavigation, { 50612 categories: categories, 50613 children: category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 50614 className: "block-editor-inserter__category-panel", 50615 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternCategoryPreviews, { 50616 onInsert: onInsert, 50617 rootClientId: rootClientId, 50618 category: category 50619 }, category.name) 50620 }) 50621 }), showPatternsExplorer && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_patterns_explorer, { 50622 initialCategory: selectedCategory || categories[0], 50623 patternCategories: categories, 50624 onModalClose: () => setShowPatternsExplorer(false), 50625 rootClientId: rootClientId 50626 })] 50627 }); 50628 } 50629 /* harmony default export */ const block_patterns_tab = (BlockPatternsTab); 50630 50631 ;// ./node_modules/@wordpress/icons/build-module/library/external.js 50632 /** 50633 * WordPress dependencies 50634 */ 50635 50636 50637 const external = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 50638 xmlns: "http://www.w3.org/2000/svg", 50639 viewBox: "0 0 24 24", 50640 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 50641 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" 50642 }) 50643 }); 50644 /* harmony default export */ const library_external = (external); 50645 50646 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/utils.js 50647 /** 50648 * WordPress dependencies 50649 */ 50650 50651 50652 const mediaTypeTag = { 50653 image: 'img', 50654 video: 'video', 50655 audio: 'audio' 50656 }; 50657 50658 /** @typedef {import('./hooks').InserterMediaItem} InserterMediaItem */ 50659 50660 /** 50661 * Creates a block and a preview element from a media object. 50662 * 50663 * @param {InserterMediaItem} media The media object to create the block from. 50664 * @param {('image'|'audio'|'video')} mediaType The media type to create the block for. 50665 * @return {[WPBlock, JSX.Element]} An array containing the block and the preview element. 50666 */ 50667 function getBlockAndPreviewFromMedia(media, mediaType) { 50668 // Add the common attributes between the different media types. 50669 const attributes = { 50670 id: media.id || undefined, 50671 caption: media.caption || undefined 50672 }; 50673 const mediaSrc = media.url; 50674 const alt = media.alt || undefined; 50675 if (mediaType === 'image') { 50676 attributes.url = mediaSrc; 50677 attributes.alt = alt; 50678 } else if (['video', 'audio'].includes(mediaType)) { 50679 attributes.src = mediaSrc; 50680 } 50681 const PreviewTag = mediaTypeTag[mediaType]; 50682 const preview = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreviewTag, { 50683 src: media.previewUrl || mediaSrc, 50684 alt: alt, 50685 controls: mediaType === 'audio' ? true : undefined, 50686 inert: "true", 50687 onError: ({ 50688 currentTarget 50689 }) => { 50690 // Fall back to the media source if the preview cannot be loaded. 50691 if (currentTarget.src === media.previewUrl) { 50692 currentTarget.src = mediaSrc; 50693 } 50694 } 50695 }); 50696 return [(0,external_wp_blocks_namespaceObject.createBlock)(`core/$mediaType}`, attributes), preview]; 50697 } 50698 50699 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-preview.js 50700 /** 50701 * External dependencies 50702 */ 50703 50704 50705 /** 50706 * WordPress dependencies 50707 */ 50708 50709 50710 50711 50712 50713 50714 50715 50716 50717 50718 /** 50719 * Internal dependencies 50720 */ 50721 50722 50723 50724 50725 const ALLOWED_MEDIA_TYPES = ['image']; 50726 const MAXIMUM_TITLE_LENGTH = 25; 50727 const MEDIA_OPTIONS_POPOVER_PROPS = { 50728 position: 'bottom left', 50729 className: 'block-editor-inserter__media-list__item-preview-options__popover' 50730 }; 50731 function MediaPreviewOptions({ 50732 category, 50733 media 50734 }) { 50735 if (!category.getReportUrl) { 50736 return null; 50737 } 50738 const reportUrl = category.getReportUrl(media); 50739 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 50740 className: "block-editor-inserter__media-list__item-preview-options", 50741 label: (0,external_wp_i18n_namespaceObject.__)('Options'), 50742 popoverProps: MEDIA_OPTIONS_POPOVER_PROPS, 50743 icon: more_vertical, 50744 children: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 50745 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 50746 onClick: () => window.open(reportUrl, '_blank').focus(), 50747 icon: library_external, 50748 children: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: The media type to report e.g: "image", "video", "audio" */ 50749 (0,external_wp_i18n_namespaceObject.__)('Report %s'), category.mediaType) 50750 }) 50751 }) 50752 }); 50753 } 50754 function InsertExternalImageModal({ 50755 onClose, 50756 onSubmit 50757 }) { 50758 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Modal, { 50759 title: (0,external_wp_i18n_namespaceObject.__)('Insert external image'), 50760 onRequestClose: onClose, 50761 className: "block-editor-inserter-media-tab-media-preview-inserter-external-image-modal", 50762 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 50763 spacing: 3, 50764 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 50765 children: (0,external_wp_i18n_namespaceObject.__)('This image cannot be uploaded to your Media Library, but it can still be inserted as an external image.') 50766 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 50767 children: (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.') 50768 })] 50769 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 50770 className: "block-editor-block-lock-modal__actions", 50771 justify: "flex-end", 50772 expanded: false, 50773 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 50774 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 50775 __next40pxDefaultSize: true, 50776 variant: "tertiary", 50777 onClick: onClose, 50778 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 50779 }) 50780 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 50781 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 50782 __next40pxDefaultSize: true, 50783 variant: "primary", 50784 onClick: onSubmit, 50785 children: (0,external_wp_i18n_namespaceObject.__)('Insert') 50786 }) 50787 })] 50788 })] 50789 }); 50790 } 50791 function MediaPreview({ 50792 media, 50793 onClick, 50794 category 50795 }) { 50796 const [showExternalUploadModal, setShowExternalUploadModal] = (0,external_wp_element_namespaceObject.useState)(false); 50797 const [isHovered, setIsHovered] = (0,external_wp_element_namespaceObject.useState)(false); 50798 const [isInserting, setIsInserting] = (0,external_wp_element_namespaceObject.useState)(false); 50799 const [block, preview] = (0,external_wp_element_namespaceObject.useMemo)(() => getBlockAndPreviewFromMedia(media, category.mediaType), [media, category.mediaType]); 50800 const { 50801 createErrorNotice, 50802 createSuccessNotice 50803 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 50804 const { 50805 getSettings, 50806 getBlock 50807 } = (0,external_wp_data_namespaceObject.useSelect)(store); 50808 const { 50809 updateBlockAttributes 50810 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 50811 const onMediaInsert = (0,external_wp_element_namespaceObject.useCallback)(previewBlock => { 50812 // Prevent multiple uploads when we're in the process of inserting. 50813 if (isInserting) { 50814 return; 50815 } 50816 const settings = getSettings(); 50817 const clonedBlock = (0,external_wp_blocks_namespaceObject.cloneBlock)(previewBlock); 50818 const { 50819 id, 50820 url, 50821 caption 50822 } = clonedBlock.attributes; 50823 50824 // User has no permission to upload media. 50825 if (!id && !settings.mediaUpload) { 50826 setShowExternalUploadModal(true); 50827 return; 50828 } 50829 50830 // Media item already exists in library, so just insert it. 50831 if (!!id) { 50832 onClick(clonedBlock); 50833 return; 50834 } 50835 setIsInserting(true); 50836 // Media item does not exist in library, so try to upload it. 50837 // Fist fetch the image data. This may fail if the image host 50838 // doesn't allow CORS with the domain. 50839 // If this happens, we insert the image block using the external 50840 // URL and let the user know about the possible implications. 50841 window.fetch(url).then(response => response.blob()).then(blob => { 50842 const fileName = (0,external_wp_url_namespaceObject.getFilename)(url) || 'image.jpg'; 50843 const file = new File([blob], fileName, { 50844 type: blob.type 50845 }); 50846 settings.mediaUpload({ 50847 filesList: [file], 50848 additionalData: { 50849 caption 50850 }, 50851 onFileChange([img]) { 50852 if ((0,external_wp_blob_namespaceObject.isBlobURL)(img.url)) { 50853 return; 50854 } 50855 if (!getBlock(clonedBlock.clientId)) { 50856 // Ensure the block is only inserted once. 50857 onClick({ 50858 ...clonedBlock, 50859 attributes: { 50860 ...clonedBlock.attributes, 50861 id: img.id, 50862 url: img.url 50863 } 50864 }); 50865 createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Image uploaded and inserted.'), { 50866 type: 'snackbar', 50867 id: 'inserter-notice' 50868 }); 50869 } else { 50870 // For subsequent calls, update the existing block. 50871 updateBlockAttributes(clonedBlock.clientId, { 50872 ...clonedBlock.attributes, 50873 id: img.id, 50874 url: img.url 50875 }); 50876 } 50877 setIsInserting(false); 50878 }, 50879 allowedTypes: ALLOWED_MEDIA_TYPES, 50880 onError(message) { 50881 createErrorNotice(message, { 50882 type: 'snackbar', 50883 id: 'inserter-notice' 50884 }); 50885 setIsInserting(false); 50886 } 50887 }); 50888 }).catch(() => { 50889 setShowExternalUploadModal(true); 50890 setIsInserting(false); 50891 }); 50892 }, [isInserting, getSettings, onClick, createSuccessNotice, updateBlockAttributes, createErrorNotice, getBlock]); 50893 const title = typeof media.title === 'string' ? media.title : media.title?.rendered || (0,external_wp_i18n_namespaceObject.__)('no title'); 50894 let truncatedTitle; 50895 if (title.length > MAXIMUM_TITLE_LENGTH) { 50896 const omission = '...'; 50897 truncatedTitle = title.slice(0, MAXIMUM_TITLE_LENGTH - omission.length) + omission; 50898 } 50899 const onMouseEnter = (0,external_wp_element_namespaceObject.useCallback)(() => setIsHovered(true), []); 50900 const onMouseLeave = (0,external_wp_element_namespaceObject.useCallback)(() => setIsHovered(false), []); 50901 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 50902 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_draggable_blocks, { 50903 isEnabled: true, 50904 blocks: [block], 50905 children: ({ 50906 draggable, 50907 onDragStart, 50908 onDragEnd 50909 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 50910 className: dist_clsx('block-editor-inserter__media-list__list-item', { 50911 'is-hovered': isHovered 50912 }), 50913 draggable: draggable, 50914 onDragStart: onDragStart, 50915 onDragEnd: onDragEnd, 50916 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 50917 onMouseEnter: onMouseEnter, 50918 onMouseLeave: onMouseLeave, 50919 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tooltip, { 50920 text: truncatedTitle || title, 50921 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite.Item, { 50922 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 50923 "aria-label": title, 50924 role: "option", 50925 className: "block-editor-inserter__media-list__item" 50926 }), 50927 onClick: () => onMediaInsert(block), 50928 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 50929 className: "block-editor-inserter__media-list__item-preview", 50930 children: [preview, isInserting && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 50931 className: "block-editor-inserter__media-list__item-preview-spinner", 50932 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Spinner, {}) 50933 })] 50934 }) 50935 }) 50936 }), !isInserting && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MediaPreviewOptions, { 50937 category: category, 50938 media: media 50939 })] 50940 }) 50941 }) 50942 }), showExternalUploadModal && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InsertExternalImageModal, { 50943 onClose: () => setShowExternalUploadModal(false), 50944 onSubmit: () => { 50945 onClick((0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 50946 createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Image inserted.'), { 50947 type: 'snackbar', 50948 id: 'inserter-notice' 50949 }); 50950 setShowExternalUploadModal(false); 50951 } 50952 })] 50953 }); 50954 } 50955 50956 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-list.js 50957 /** 50958 * WordPress dependencies 50959 */ 50960 50961 50962 50963 /** 50964 * Internal dependencies 50965 */ 50966 50967 50968 function MediaList({ 50969 mediaList, 50970 category, 50971 onClick, 50972 label = (0,external_wp_i18n_namespaceObject.__)('Media List') 50973 }) { 50974 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite, { 50975 role: "listbox", 50976 className: "block-editor-inserter__media-list", 50977 "aria-label": label, 50978 children: mediaList.map((media, index) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MediaPreview, { 50979 media: media, 50980 category: category, 50981 onClick: onClick 50982 }, media.id || media.sourceId || index)) 50983 }); 50984 } 50985 /* harmony default export */ const media_list = (MediaList); 50986 50987 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/hooks.js 50988 /** 50989 * WordPress dependencies 50990 */ 50991 50992 50993 50994 /** 50995 * Internal dependencies 50996 */ 50997 50998 50999 51000 /** @typedef {import('../../../store/actions').InserterMediaRequest} InserterMediaRequest */ 51001 /** @typedef {import('../../../store/actions').InserterMediaItem} InserterMediaItem */ 51002 51003 /** 51004 * Fetches media items based on the provided category. 51005 * Each media category is responsible for providing a `fetch` function. 51006 * 51007 * @param {Object} category The media category to fetch results for. 51008 * @param {InserterMediaRequest} query The query args to use for the request. 51009 * @return {InserterMediaItem[]} The media results. 51010 */ 51011 function useMediaResults(category, query = {}) { 51012 const [mediaList, setMediaList] = (0,external_wp_element_namespaceObject.useState)(); 51013 const [isLoading, setIsLoading] = (0,external_wp_element_namespaceObject.useState)(false); 51014 // We need to keep track of the last request made because 51015 // multiple request can be fired without knowing the order 51016 // of resolution, and we need to ensure we are showing 51017 // the results of the last request. 51018 // In the future we could use AbortController to cancel previous 51019 // requests, but we don't for now as it involves adding support 51020 // for this to `core-data` package. 51021 const lastRequestRef = (0,external_wp_element_namespaceObject.useRef)(); 51022 (0,external_wp_element_namespaceObject.useEffect)(() => { 51023 (async () => { 51024 const key = JSON.stringify({ 51025 category: category.name, 51026 ...query 51027 }); 51028 lastRequestRef.current = key; 51029 setIsLoading(true); 51030 setMediaList([]); // Empty the previous results. 51031 const _media = await category.fetch?.(query); 51032 if (key === lastRequestRef.current) { 51033 setMediaList(_media); 51034 setIsLoading(false); 51035 } 51036 })(); 51037 }, [category.name, ...Object.values(query)]); 51038 return { 51039 mediaList, 51040 isLoading 51041 }; 51042 } 51043 function useMediaCategories(rootClientId) { 51044 const [categories, setCategories] = (0,external_wp_element_namespaceObject.useState)([]); 51045 const inserterMediaCategories = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getInserterMediaCategories(), []); 51046 const { 51047 canInsertImage, 51048 canInsertVideo, 51049 canInsertAudio 51050 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 51051 const { 51052 canInsertBlockType 51053 } = select(store); 51054 return { 51055 canInsertImage: canInsertBlockType('core/image', rootClientId), 51056 canInsertVideo: canInsertBlockType('core/video', rootClientId), 51057 canInsertAudio: canInsertBlockType('core/audio', rootClientId) 51058 }; 51059 }, [rootClientId]); 51060 (0,external_wp_element_namespaceObject.useEffect)(() => { 51061 (async () => { 51062 const _categories = []; 51063 // If `inserterMediaCategories` is not defined in 51064 // block editor settings, do not show any media categories. 51065 if (!inserterMediaCategories) { 51066 return; 51067 } 51068 // Loop through categories to check if they have at least one media item. 51069 const categoriesHaveMedia = new Map(await Promise.all(inserterMediaCategories.map(async category => { 51070 // Some sources are external and we don't need to make a request. 51071 if (category.isExternalResource) { 51072 return [category.name, true]; 51073 } 51074 let results = []; 51075 try { 51076 results = await category.fetch({ 51077 per_page: 1 51078 }); 51079 } catch (e) { 51080 // If the request fails, we shallow the error and just don't show 51081 // the category, in order to not break the media tab. 51082 } 51083 return [category.name, !!results.length]; 51084 }))); 51085 // We need to filter out categories that don't have any media items or 51086 // whose corresponding block type is not allowed to be inserted, based 51087 // on the category's `mediaType`. 51088 const canInsertMediaType = { 51089 image: canInsertImage, 51090 video: canInsertVideo, 51091 audio: canInsertAudio 51092 }; 51093 inserterMediaCategories.forEach(category => { 51094 if (canInsertMediaType[category.mediaType] && categoriesHaveMedia.get(category.name)) { 51095 _categories.push(category); 51096 } 51097 }); 51098 if (!!_categories.length) { 51099 setCategories(_categories); 51100 } 51101 })(); 51102 }, [canInsertImage, canInsertVideo, canInsertAudio, inserterMediaCategories]); 51103 return categories; 51104 } 51105 51106 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-panel.js 51107 /** 51108 * WordPress dependencies 51109 */ 51110 51111 51112 51113 51114 /** 51115 * Internal dependencies 51116 */ 51117 51118 51119 51120 51121 const INITIAL_MEDIA_ITEMS_PER_PAGE = 10; 51122 function MediaCategoryPanel({ 51123 rootClientId, 51124 onInsert, 51125 category 51126 }) { 51127 const [search, setSearch, debouncedSearch] = (0,external_wp_compose_namespaceObject.useDebouncedInput)(); 51128 const { 51129 mediaList, 51130 isLoading 51131 } = useMediaResults(category, { 51132 per_page: !!debouncedSearch ? 20 : INITIAL_MEDIA_ITEMS_PER_PAGE, 51133 search: debouncedSearch 51134 }); 51135 const baseCssClass = 'block-editor-inserter__media-panel'; 51136 const searchLabel = category.labels.search_items || (0,external_wp_i18n_namespaceObject.__)('Search'); 51137 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 51138 className: baseCssClass, 51139 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SearchControl, { 51140 __nextHasNoMarginBottom: true, 51141 className: `$baseCssClass}-search`, 51142 onChange: setSearch, 51143 value: search, 51144 label: searchLabel, 51145 placeholder: searchLabel 51146 }), isLoading && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 51147 className: `$baseCssClass}-spinner`, 51148 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Spinner, {}) 51149 }), !isLoading && !mediaList?.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(no_results, {}), !isLoading && !!mediaList?.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(media_list, { 51150 rootClientId: rootClientId, 51151 onClick: onInsert, 51152 mediaList: mediaList, 51153 category: category 51154 })] 51155 }); 51156 } 51157 51158 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-tab.js 51159 /** 51160 * WordPress dependencies 51161 */ 51162 51163 51164 51165 51166 51167 /** 51168 * Internal dependencies 51169 */ 51170 51171 51172 51173 51174 51175 51176 51177 51178 51179 const media_tab_ALLOWED_MEDIA_TYPES = ['image', 'video', 'audio']; 51180 function MediaTab({ 51181 rootClientId, 51182 selectedCategory, 51183 onSelectCategory, 51184 onInsert, 51185 children 51186 }) { 51187 const mediaCategories = useMediaCategories(rootClientId); 51188 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 51189 const baseCssClass = 'block-editor-inserter__media-tabs'; 51190 const onSelectMedia = (0,external_wp_element_namespaceObject.useCallback)(media => { 51191 if (!media?.url) { 51192 return; 51193 } 51194 const [block] = getBlockAndPreviewFromMedia(media, media.type); 51195 onInsert(block); 51196 }, [onInsert]); 51197 const categories = (0,external_wp_element_namespaceObject.useMemo)(() => mediaCategories.map(mediaCategory => ({ 51198 ...mediaCategory, 51199 label: mediaCategory.labels.name 51200 })), [mediaCategories]); 51201 if (!categories.length) { 51202 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(no_results, {}); 51203 } 51204 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 51205 children: [!isMobile && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 51206 className: `$baseCssClass}-container`, 51207 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(category_tabs, { 51208 categories: categories, 51209 selectedCategory: selectedCategory, 51210 onSelectCategory: onSelectCategory, 51211 children: children 51212 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(check, { 51213 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(media_upload, { 51214 multiple: false, 51215 onSelect: onSelectMedia, 51216 allowedTypes: media_tab_ALLOWED_MEDIA_TYPES, 51217 render: ({ 51218 open 51219 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 51220 __next40pxDefaultSize: true, 51221 onClick: event => { 51222 // Safari doesn't emit a focus event on button elements when 51223 // clicked and we need to manually focus the button here. 51224 // The reason is that core's Media Library modal explicitly triggers a 51225 // focus event and therefore a `blur` event is triggered on a different 51226 // element, which doesn't contain the `data-unstable-ignore-focus-outside-for-relatedtarget` 51227 // attribute making the Inserter dialog to close. 51228 event.target.focus(); 51229 open(); 51230 }, 51231 className: "block-editor-inserter__media-library-button", 51232 variant: "secondary", 51233 "data-unstable-ignore-focus-outside-for-relatedtarget": ".media-modal", 51234 children: (0,external_wp_i18n_namespaceObject.__)('Open Media Library') 51235 }) 51236 }) 51237 })] 51238 }), isMobile && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MobileTabNavigation, { 51239 categories: categories, 51240 children: category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MediaCategoryPanel, { 51241 onInsert: onInsert, 51242 rootClientId: rootClientId, 51243 category: category 51244 }) 51245 })] 51246 }); 51247 } 51248 /* harmony default export */ const media_tab = (MediaTab); 51249 51250 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter-menu-extension/index.js 51251 /** 51252 * WordPress dependencies 51253 */ 51254 51255 const { 51256 Fill: __unstableInserterMenuExtension, 51257 Slot 51258 } = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableInserterMenuExtension'); 51259 __unstableInserterMenuExtension.Slot = Slot; 51260 /* harmony default export */ const inserter_menu_extension = (__unstableInserterMenuExtension); 51261 51262 ;// ./node_modules/@wordpress/block-editor/build-module/utils/order-inserter-block-items.js 51263 /** @typedef {import('../store/selectors').WPEditorInserterItem} WPEditorInserterItem */ 51264 51265 /** 51266 * Helper function to order inserter block items according to a provided array of prioritized blocks. 51267 * 51268 * @param {WPEditorInserterItem[]} items The array of editor inserter block items to be sorted. 51269 * @param {string[]} priority The array of block names to be prioritized. 51270 * @return {WPEditorInserterItem[]} The sorted array of editor inserter block items. 51271 */ 51272 const orderInserterBlockItems = (items, priority) => { 51273 if (!priority) { 51274 return items; 51275 } 51276 items.sort(({ 51277 id: aName 51278 }, { 51279 id: bName 51280 }) => { 51281 // Sort block items according to `priority`. 51282 let aIndex = priority.indexOf(aName); 51283 let bIndex = priority.indexOf(bName); 51284 // All other block items should come after that. 51285 if (aIndex < 0) { 51286 aIndex = priority.length; 51287 } 51288 if (bIndex < 0) { 51289 bIndex = priority.length; 51290 } 51291 return aIndex - bIndex; 51292 }); 51293 return items; 51294 }; 51295 51296 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/search-results.js 51297 /** 51298 * WordPress dependencies 51299 */ 51300 51301 51302 51303 51304 51305 51306 51307 /** 51308 * Internal dependencies 51309 */ 51310 51311 51312 51313 51314 51315 51316 51317 51318 51319 51320 51321 51322 51323 51324 const INITIAL_INSERTER_RESULTS = 9; 51325 /** 51326 * Shared reference to an empty array for cases where it is important to avoid 51327 * returning a new array reference on every invocation and rerendering the component. 51328 * 51329 * @type {Array} 51330 */ 51331 const search_results_EMPTY_ARRAY = []; 51332 function InserterSearchResults({ 51333 filterValue, 51334 onSelect, 51335 onHover, 51336 onHoverPattern, 51337 rootClientId, 51338 clientId, 51339 isAppender, 51340 __experimentalInsertionIndex, 51341 maxBlockPatterns, 51342 maxBlockTypes, 51343 showBlockDirectory = false, 51344 isDraggable = true, 51345 shouldFocusBlock = true, 51346 prioritizePatterns, 51347 selectBlockOnInsert, 51348 isQuick 51349 }) { 51350 const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500); 51351 const { 51352 prioritizedBlocks 51353 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 51354 const blockListSettings = select(store).getBlockListSettings(rootClientId); 51355 return { 51356 prioritizedBlocks: blockListSettings?.prioritizedInserterBlocks || search_results_EMPTY_ARRAY 51357 }; 51358 }, [rootClientId]); 51359 const [destinationRootClientId, onInsertBlocks] = use_insertion_point({ 51360 onSelect, 51361 rootClientId, 51362 clientId, 51363 isAppender, 51364 insertionIndex: __experimentalInsertionIndex, 51365 shouldFocusBlock, 51366 selectBlockOnInsert 51367 }); 51368 const [blockTypes, blockTypeCategories, blockTypeCollections, onSelectBlockType] = use_block_types_state(destinationRootClientId, onInsertBlocks, isQuick); 51369 const [patterns,, onClickPattern] = use_patterns_state(onInsertBlocks, destinationRootClientId, undefined, isQuick); 51370 const filteredBlockPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => { 51371 if (maxBlockPatterns === 0) { 51372 return []; 51373 } 51374 const results = searchItems(patterns, filterValue); 51375 return maxBlockPatterns !== undefined ? results.slice(0, maxBlockPatterns) : results; 51376 }, [filterValue, patterns, maxBlockPatterns]); 51377 let maxBlockTypesToShow = maxBlockTypes; 51378 if (prioritizePatterns && filteredBlockPatterns.length > 2) { 51379 maxBlockTypesToShow = 0; 51380 } 51381 const filteredBlockTypes = (0,external_wp_element_namespaceObject.useMemo)(() => { 51382 if (maxBlockTypesToShow === 0) { 51383 return []; 51384 } 51385 const nonPatternBlockTypes = blockTypes.filter(blockType => blockType.name !== 'core/block'); 51386 let orderedItems = orderBy(nonPatternBlockTypes, 'frecency', 'desc'); 51387 if (!filterValue && prioritizedBlocks.length) { 51388 orderedItems = orderInserterBlockItems(orderedItems, prioritizedBlocks); 51389 } 51390 const results = searchBlockItems(orderedItems, blockTypeCategories, blockTypeCollections, filterValue); 51391 return maxBlockTypesToShow !== undefined ? results.slice(0, maxBlockTypesToShow) : results; 51392 }, [filterValue, blockTypes, blockTypeCategories, blockTypeCollections, maxBlockTypesToShow, prioritizedBlocks]); 51393 51394 // Announce search results on change. 51395 (0,external_wp_element_namespaceObject.useEffect)(() => { 51396 if (!filterValue) { 51397 return; 51398 } 51399 const count = filteredBlockTypes.length + filteredBlockPatterns.length; 51400 const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of results. */ 51401 (0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count); 51402 debouncedSpeak(resultsFoundMessage); 51403 }, [filterValue, debouncedSpeak, filteredBlockTypes, filteredBlockPatterns]); 51404 const currentShownBlockTypes = (0,external_wp_compose_namespaceObject.useAsyncList)(filteredBlockTypes, { 51405 step: INITIAL_INSERTER_RESULTS 51406 }); 51407 const hasItems = filteredBlockTypes.length > 0 || filteredBlockPatterns.length > 0; 51408 const blocksUI = !!filteredBlockTypes.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, { 51409 title: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 51410 children: (0,external_wp_i18n_namespaceObject.__)('Blocks') 51411 }), 51412 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_types_list, { 51413 items: currentShownBlockTypes, 51414 onSelect: onSelectBlockType, 51415 onHover: onHover, 51416 label: (0,external_wp_i18n_namespaceObject.__)('Blocks'), 51417 isDraggable: isDraggable 51418 }) 51419 }); 51420 const patternsUI = !!filteredBlockPatterns.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel, { 51421 title: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 51422 children: (0,external_wp_i18n_namespaceObject.__)('Block patterns') 51423 }), 51424 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 51425 className: "block-editor-inserter__quick-inserter-patterns", 51426 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_patterns_list, { 51427 blockPatterns: filteredBlockPatterns, 51428 onClickPattern: onClickPattern, 51429 onHover: onHoverPattern, 51430 isDraggable: isDraggable 51431 }) 51432 }) 51433 }); 51434 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(inserter_listbox, { 51435 children: [!showBlockDirectory && !hasItems && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(no_results, {}), prioritizePatterns ? patternsUI : blocksUI, !!filteredBlockTypes.length && !!filteredBlockPatterns.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 51436 className: "block-editor-inserter__quick-inserter-separator" 51437 }), prioritizePatterns ? blocksUI : patternsUI, showBlockDirectory && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_menu_extension.Slot, { 51438 fillProps: { 51439 onSelect: onSelectBlockType, 51440 onHover, 51441 filterValue, 51442 hasItems, 51443 rootClientId: destinationRootClientId 51444 }, 51445 children: fills => { 51446 if (fills.length) { 51447 return fills; 51448 } 51449 if (!hasItems) { 51450 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(no_results, {}); 51451 } 51452 return null; 51453 } 51454 })] 51455 }); 51456 } 51457 /* harmony default export */ const inserter_search_results = (InserterSearchResults); 51458 51459 ;// ./node_modules/@wordpress/icons/build-module/library/close-small.js 51460 /** 51461 * WordPress dependencies 51462 */ 51463 51464 51465 const closeSmall = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 51466 xmlns: "http://www.w3.org/2000/svg", 51467 viewBox: "0 0 24 24", 51468 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 51469 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" 51470 }) 51471 }); 51472 /* harmony default export */ const close_small = (closeSmall); 51473 51474 ;// ./node_modules/@wordpress/block-editor/build-module/components/tabbed-sidebar/index.js 51475 /** 51476 * WordPress dependencies 51477 */ 51478 51479 51480 51481 51482 /** 51483 * Internal dependencies 51484 */ 51485 51486 51487 const { 51488 Tabs: tabbed_sidebar_Tabs 51489 } = unlock(external_wp_components_namespaceObject.privateApis); 51490 51491 /** 51492 * A component that creates a tabbed sidebar with a close button. 51493 * 51494 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/tabbed-sidebar/README.md 51495 * 51496 * @example 51497 * ```jsx 51498 * function MyTabbedSidebar() { 51499 * return ( 51500 * <TabbedSidebar 51501 * tabs={ [ 51502 * { 51503 * name: 'tab1', 51504 * title: 'Settings', 51505 * panel: <PanelContents />, 51506 * } 51507 * ] } 51508 * onClose={ () => {} } 51509 * onSelect={ () => {} } 51510 * defaultTabId="tab1" 51511 * selectedTab="tab1" 51512 * closeButtonLabel="Close sidebar" 51513 * /> 51514 * ); 51515 * } 51516 * ``` 51517 * 51518 * @param {Object} props Component props. 51519 * @param {string} [props.defaultTabId] The ID of the tab to be selected by default when the component renders. 51520 * @param {Function} props.onClose Function called when the close button is clicked. 51521 * @param {Function} props.onSelect Function called when a tab is selected. Receives the selected tab's ID as an argument. 51522 * @param {string} props.selectedTab The ID of the currently selected tab. 51523 * @param {Array} props.tabs Array of tab objects. Each tab should have: name (string), title (string), 51524 * panel (React.Node), and optionally panelRef (React.Ref). 51525 * @param {string} props.closeButtonLabel Accessibility label for the close button. 51526 * @param {Object} ref Forward ref to the tabs list element. 51527 * @return {Element} The tabbed sidebar component. 51528 */ 51529 function TabbedSidebar({ 51530 defaultTabId, 51531 onClose, 51532 onSelect, 51533 selectedTab, 51534 tabs, 51535 closeButtonLabel 51536 }, ref) { 51537 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 51538 className: "block-editor-tabbed-sidebar", 51539 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(tabbed_sidebar_Tabs, { 51540 selectOnMove: false, 51541 defaultTabId: defaultTabId, 51542 onSelect: onSelect, 51543 selectedTabId: selectedTab, 51544 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 51545 className: "block-editor-tabbed-sidebar__tablist-and-close-button", 51546 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 51547 className: "block-editor-tabbed-sidebar__close-button", 51548 icon: close_small, 51549 label: closeButtonLabel, 51550 onClick: () => onClose(), 51551 size: "compact" 51552 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tabbed_sidebar_Tabs.TabList, { 51553 className: "block-editor-tabbed-sidebar__tablist", 51554 ref: ref, 51555 children: tabs.map(tab => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tabbed_sidebar_Tabs.Tab, { 51556 tabId: tab.name, 51557 className: "block-editor-tabbed-sidebar__tab", 51558 children: tab.title 51559 }, tab.name)) 51560 })] 51561 }), tabs.map(tab => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tabbed_sidebar_Tabs.TabPanel, { 51562 tabId: tab.name, 51563 focusable: false, 51564 className: "block-editor-tabbed-sidebar__tabpanel", 51565 ref: tab.panelRef, 51566 children: tab.panel 51567 }, tab.name))] 51568 }) 51569 }); 51570 } 51571 /* harmony default export */ const tabbed_sidebar = ((0,external_wp_element_namespaceObject.forwardRef)(TabbedSidebar)); 51572 51573 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-zoom-out.js 51574 /** 51575 * WordPress dependencies 51576 */ 51577 51578 51579 51580 /** 51581 * Internal dependencies 51582 */ 51583 51584 51585 51586 /** 51587 * A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode. 51588 * Concepts: 51589 * - If we most recently changed the zoom level for them (in or out), we always resetZoomLevel() level when unmounting. 51590 * - If the user most recently changed the zoom level (manually toggling), we do nothing when unmounting. 51591 * 51592 * @param {boolean} enabled If we should enter into zoomOut mode or not 51593 */ 51594 function useZoomOut(enabled = true) { 51595 const { 51596 setZoomLevel, 51597 resetZoomLevel 51598 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 51599 51600 /** 51601 * We need access to both the value and the function. The value is to trigger a useEffect hook 51602 * and the function is to check zoom out within another hook without triggering a re-render. 51603 */ 51604 const { 51605 isZoomedOut, 51606 isZoomOut 51607 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 51608 const { 51609 isZoomOut: _isZoomOut 51610 } = unlock(select(store)); 51611 return { 51612 isZoomedOut: _isZoomOut(), 51613 isZoomOut: _isZoomOut 51614 }; 51615 }, []); 51616 const controlZoomLevelRef = (0,external_wp_element_namespaceObject.useRef)(false); 51617 const isEnabledRef = (0,external_wp_element_namespaceObject.useRef)(enabled); 51618 51619 /** 51620 * This hook tracks if the zoom state was changed manually by the user via clicking 51621 * the zoom out button. We only want this to run when isZoomedOut changes, so we use 51622 * a ref to track the enabled state. 51623 */ 51624 (0,external_wp_element_namespaceObject.useEffect)(() => { 51625 // If the zoom state changed (isZoomOut) and it does not match the requested zoom 51626 // state (zoomOut), then it means the user manually changed the zoom state while 51627 // this hook was mounted, and we should no longer control the zoom state. 51628 if (isZoomedOut !== isEnabledRef.current) { 51629 controlZoomLevelRef.current = false; 51630 } 51631 }, [isZoomedOut]); 51632 (0,external_wp_element_namespaceObject.useEffect)(() => { 51633 isEnabledRef.current = enabled; 51634 if (enabled !== isZoomOut()) { 51635 controlZoomLevelRef.current = true; 51636 if (enabled) { 51637 setZoomLevel('auto-scaled'); 51638 } else { 51639 resetZoomLevel(); 51640 } 51641 } 51642 return () => { 51643 // If we are controlling zoom level and are zoomed out, reset the zoom level. 51644 if (controlZoomLevelRef.current && isZoomOut()) { 51645 resetZoomLevel(); 51646 } 51647 }; 51648 }, [enabled, isZoomOut, resetZoomLevel, setZoomLevel]); 51649 } 51650 51651 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/menu.js 51652 /** 51653 * External dependencies 51654 */ 51655 51656 51657 /** 51658 * WordPress dependencies 51659 */ 51660 51661 51662 51663 51664 51665 51666 /** 51667 * Internal dependencies 51668 */ 51669 51670 51671 51672 51673 51674 51675 51676 51677 51678 51679 51680 51681 51682 const NOOP = () => {}; 51683 function InserterMenu({ 51684 rootClientId, 51685 clientId, 51686 isAppender, 51687 __experimentalInsertionIndex, 51688 onSelect, 51689 showInserterHelpPanel, 51690 showMostUsedBlocks, 51691 __experimentalFilterValue = '', 51692 shouldFocusBlock = true, 51693 onPatternCategorySelection, 51694 onClose, 51695 __experimentalInitialTab, 51696 __experimentalInitialCategory 51697 }, ref) { 51698 const { 51699 isZoomOutMode, 51700 hasSectionRootClientId 51701 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 51702 const { 51703 isZoomOut, 51704 getSectionRootClientId 51705 } = unlock(select(store)); 51706 return { 51707 isZoomOutMode: isZoomOut(), 51708 hasSectionRootClientId: !!getSectionRootClientId() 51709 }; 51710 }, []); 51711 const [filterValue, setFilterValue, delayedFilterValue] = (0,external_wp_compose_namespaceObject.useDebouncedInput)(__experimentalFilterValue); 51712 const [hoveredItem, setHoveredItem] = (0,external_wp_element_namespaceObject.useState)(null); 51713 const [selectedPatternCategory, setSelectedPatternCategory] = (0,external_wp_element_namespaceObject.useState)(__experimentalInitialCategory); 51714 const [patternFilter, setPatternFilter] = (0,external_wp_element_namespaceObject.useState)('all'); 51715 const [selectedMediaCategory, setSelectedMediaCategory] = (0,external_wp_element_namespaceObject.useState)(null); 51716 const isLargeViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('large'); 51717 function getInitialTab() { 51718 if (__experimentalInitialTab) { 51719 return __experimentalInitialTab; 51720 } 51721 if (isZoomOutMode) { 51722 return 'patterns'; 51723 } 51724 return 'blocks'; 51725 } 51726 const [selectedTab, setSelectedTab] = (0,external_wp_element_namespaceObject.useState)(getInitialTab()); 51727 const shouldUseZoomOut = hasSectionRootClientId && (selectedTab === 'patterns' || selectedTab === 'media'); 51728 useZoomOut(shouldUseZoomOut && isLargeViewport); 51729 const [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint] = use_insertion_point({ 51730 rootClientId, 51731 clientId, 51732 isAppender, 51733 insertionIndex: __experimentalInsertionIndex, 51734 shouldFocusBlock 51735 }); 51736 const blockTypesTabRef = (0,external_wp_element_namespaceObject.useRef)(); 51737 const onInsert = (0,external_wp_element_namespaceObject.useCallback)((blocks, meta, shouldForceFocusBlock, _rootClientId) => { 51738 onInsertBlocks(blocks, meta, shouldForceFocusBlock, _rootClientId); 51739 onSelect(blocks); 51740 51741 // Check for focus loss due to filtering blocks by selected block type 51742 window.requestAnimationFrame(() => { 51743 if (!shouldFocusBlock && !blockTypesTabRef.current?.contains(ref.current.ownerDocument.activeElement)) { 51744 // There has been a focus loss, so focus the first button in the block types tab 51745 blockTypesTabRef.current?.querySelector('button').focus(); 51746 } 51747 }); 51748 }, [onInsertBlocks, onSelect, shouldFocusBlock]); 51749 const onInsertPattern = (0,external_wp_element_namespaceObject.useCallback)((blocks, patternName, ...args) => { 51750 onToggleInsertionPoint(false); 51751 onInsertBlocks(blocks, { 51752 patternName 51753 }, ...args); 51754 onSelect(); 51755 }, [onInsertBlocks, onSelect]); 51756 const onHover = (0,external_wp_element_namespaceObject.useCallback)(item => { 51757 onToggleInsertionPoint(item); 51758 setHoveredItem(item); 51759 }, [onToggleInsertionPoint, setHoveredItem]); 51760 const onClickPatternCategory = (0,external_wp_element_namespaceObject.useCallback)((patternCategory, filter) => { 51761 setSelectedPatternCategory(patternCategory); 51762 setPatternFilter(filter); 51763 onPatternCategorySelection?.(); 51764 }, [setSelectedPatternCategory, onPatternCategorySelection]); 51765 const showPatternPanel = selectedTab === 'patterns' && !delayedFilterValue && !!selectedPatternCategory; 51766 const showMediaPanel = selectedTab === 'media' && !!selectedMediaCategory; 51767 const inserterSearch = (0,external_wp_element_namespaceObject.useMemo)(() => { 51768 if (selectedTab === 'media') { 51769 return null; 51770 } 51771 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 51772 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SearchControl, { 51773 __nextHasNoMarginBottom: true, 51774 className: "block-editor-inserter__search", 51775 onChange: value => { 51776 if (hoveredItem) { 51777 setHoveredItem(null); 51778 } 51779 setFilterValue(value); 51780 }, 51781 value: filterValue, 51782 label: (0,external_wp_i18n_namespaceObject.__)('Search'), 51783 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search') 51784 }), !!delayedFilterValue && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_search_results, { 51785 filterValue: delayedFilterValue, 51786 onSelect: onSelect, 51787 onHover: onHover, 51788 rootClientId: rootClientId, 51789 clientId: clientId, 51790 isAppender: isAppender, 51791 __experimentalInsertionIndex: __experimentalInsertionIndex, 51792 showBlockDirectory: true, 51793 shouldFocusBlock: shouldFocusBlock, 51794 prioritizePatterns: selectedTab === 'patterns' 51795 })] 51796 }); 51797 }, [selectedTab, hoveredItem, setHoveredItem, setFilterValue, filterValue, delayedFilterValue, onSelect, onHover, shouldFocusBlock, clientId, rootClientId, __experimentalInsertionIndex, isAppender]); 51798 const blocksTab = (0,external_wp_element_namespaceObject.useMemo)(() => { 51799 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 51800 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 51801 className: "block-editor-inserter__block-list", 51802 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_types_tab, { 51803 ref: blockTypesTabRef, 51804 rootClientId: destinationRootClientId, 51805 onInsert: onInsert, 51806 onHover: onHover, 51807 showMostUsedBlocks: showMostUsedBlocks 51808 }) 51809 }), showInserterHelpPanel && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 51810 className: "block-editor-inserter__tips", 51811 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 51812 as: "h2", 51813 children: (0,external_wp_i18n_namespaceObject.__)('A tip for using the block editor') 51814 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tips, {})] 51815 })] 51816 }); 51817 }, [destinationRootClientId, onInsert, onHover, showMostUsedBlocks, showInserterHelpPanel]); 51818 const patternsTab = (0,external_wp_element_namespaceObject.useMemo)(() => { 51819 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_patterns_tab, { 51820 rootClientId: destinationRootClientId, 51821 onInsert: onInsertPattern, 51822 onSelectCategory: onClickPatternCategory, 51823 selectedCategory: selectedPatternCategory, 51824 children: showPatternPanel && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PatternCategoryPreviews, { 51825 rootClientId: destinationRootClientId, 51826 onInsert: onInsertPattern, 51827 category: selectedPatternCategory, 51828 patternFilter: patternFilter, 51829 showTitlesAsTooltip: true 51830 }) 51831 }); 51832 }, [destinationRootClientId, onInsertPattern, onClickPatternCategory, patternFilter, selectedPatternCategory, showPatternPanel]); 51833 const mediaTab = (0,external_wp_element_namespaceObject.useMemo)(() => { 51834 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(media_tab, { 51835 rootClientId: destinationRootClientId, 51836 selectedCategory: selectedMediaCategory, 51837 onSelectCategory: setSelectedMediaCategory, 51838 onInsert: onInsert, 51839 children: showMediaPanel && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MediaCategoryPanel, { 51840 rootClientId: destinationRootClientId, 51841 onInsert: onInsert, 51842 category: selectedMediaCategory 51843 }) 51844 }); 51845 }, [destinationRootClientId, onInsert, selectedMediaCategory, setSelectedMediaCategory, showMediaPanel]); 51846 const handleSetSelectedTab = value => { 51847 // If no longer on patterns tab remove the category setting. 51848 if (value !== 'patterns') { 51849 setSelectedPatternCategory(null); 51850 } 51851 setSelectedTab(value); 51852 }; 51853 51854 // Focus first active tab, if any 51855 const tabsRef = (0,external_wp_element_namespaceObject.useRef)(); 51856 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 51857 if (tabsRef.current) { 51858 window.requestAnimationFrame(() => { 51859 tabsRef.current.querySelector('[role="tab"][aria-selected="true"]')?.focus(); 51860 }); 51861 } 51862 }, []); 51863 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 51864 className: dist_clsx('block-editor-inserter__menu', { 51865 'show-panel': showPatternPanel || showMediaPanel, 51866 'is-zoom-out': isZoomOutMode 51867 }), 51868 ref: ref, 51869 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 51870 className: "block-editor-inserter__main-area", 51871 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tabbed_sidebar, { 51872 ref: tabsRef, 51873 onSelect: handleSetSelectedTab, 51874 onClose: onClose, 51875 selectedTab: selectedTab, 51876 closeButtonLabel: (0,external_wp_i18n_namespaceObject.__)('Close Block Inserter'), 51877 tabs: [{ 51878 name: 'blocks', 51879 title: (0,external_wp_i18n_namespaceObject.__)('Blocks'), 51880 panel: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 51881 children: [inserterSearch, selectedTab === 'blocks' && !delayedFilterValue && blocksTab] 51882 }) 51883 }, { 51884 name: 'patterns', 51885 title: (0,external_wp_i18n_namespaceObject.__)('Patterns'), 51886 panel: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 51887 children: [inserterSearch, selectedTab === 'patterns' && !delayedFilterValue && patternsTab] 51888 }) 51889 }, { 51890 name: 'media', 51891 title: (0,external_wp_i18n_namespaceObject.__)('Media'), 51892 panel: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 51893 children: [inserterSearch, mediaTab] 51894 }) 51895 }] 51896 }) 51897 }), showInserterHelpPanel && hoveredItem && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 51898 className: "block-editor-inserter__preview-container__popover", 51899 placement: "right-start", 51900 offset: 16, 51901 focusOnMount: false, 51902 animate: false, 51903 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(preview_panel, { 51904 item: hoveredItem 51905 }) 51906 })] 51907 }); 51908 } 51909 const PrivateInserterMenu = (0,external_wp_element_namespaceObject.forwardRef)(InserterMenu); 51910 function PublicInserterMenu(props, ref) { 51911 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateInserterMenu, { 51912 ...props, 51913 onPatternCategorySelection: NOOP, 51914 ref: ref 51915 }); 51916 } 51917 /* harmony default export */ const menu = ((0,external_wp_element_namespaceObject.forwardRef)(PublicInserterMenu)); 51918 51919 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/quick-inserter.js 51920 /** 51921 * External dependencies 51922 */ 51923 51924 51925 /** 51926 * WordPress dependencies 51927 */ 51928 51929 51930 51931 51932 51933 /** 51934 * Internal dependencies 51935 */ 51936 51937 51938 51939 51940 51941 const SEARCH_THRESHOLD = 6; 51942 const SHOWN_BLOCK_TYPES = 6; 51943 const SHOWN_BLOCK_PATTERNS = 2; 51944 function QuickInserter({ 51945 onSelect, 51946 rootClientId, 51947 clientId, 51948 isAppender, 51949 selectBlockOnInsert, 51950 hasSearch = true 51951 }) { 51952 const [filterValue, setFilterValue] = (0,external_wp_element_namespaceObject.useState)(''); 51953 const [destinationRootClientId, onInsertBlocks] = use_insertion_point({ 51954 onSelect, 51955 rootClientId, 51956 clientId, 51957 isAppender, 51958 selectBlockOnInsert 51959 }); 51960 const [blockTypes] = use_block_types_state(destinationRootClientId, onInsertBlocks, true); 51961 const { 51962 setInserterIsOpened, 51963 insertionIndex 51964 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 51965 const { 51966 getSettings, 51967 getBlockIndex, 51968 getBlockCount 51969 } = select(store); 51970 const settings = getSettings(); 51971 const index = getBlockIndex(clientId); 51972 const blockCount = getBlockCount(); 51973 return { 51974 setInserterIsOpened: settings.__experimentalSetIsInserterOpened, 51975 insertionIndex: index === -1 ? blockCount : index 51976 }; 51977 }, [clientId]); 51978 const showSearch = hasSearch && blockTypes.length > SEARCH_THRESHOLD; 51979 (0,external_wp_element_namespaceObject.useEffect)(() => { 51980 if (setInserterIsOpened) { 51981 setInserterIsOpened(false); 51982 } 51983 }, [setInserterIsOpened]); 51984 51985 // When clicking Browse All select the appropriate block so as 51986 // the insertion point can work as expected. 51987 const onBrowseAll = () => { 51988 setInserterIsOpened({ 51989 filterValue, 51990 onSelect, 51991 rootClientId, 51992 insertionIndex 51993 }); 51994 }; 51995 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 51996 className: dist_clsx('block-editor-inserter__quick-inserter', { 51997 'has-search': showSearch, 51998 'has-expand': setInserterIsOpened 51999 }), 52000 children: [showSearch && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SearchControl, { 52001 __nextHasNoMarginBottom: true, 52002 className: "block-editor-inserter__search", 52003 value: filterValue, 52004 onChange: value => { 52005 setFilterValue(value); 52006 }, 52007 label: (0,external_wp_i18n_namespaceObject.__)('Search'), 52008 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search') 52009 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 52010 className: "block-editor-inserter__quick-inserter-results", 52011 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter_search_results, { 52012 filterValue: filterValue, 52013 onSelect: onSelect, 52014 rootClientId: rootClientId, 52015 clientId: clientId, 52016 isAppender: isAppender, 52017 maxBlockPatterns: !!filterValue ? SHOWN_BLOCK_PATTERNS : 0, 52018 maxBlockTypes: SHOWN_BLOCK_TYPES, 52019 isDraggable: false, 52020 selectBlockOnInsert: selectBlockOnInsert, 52021 isQuick: true 52022 }) 52023 }), setInserterIsOpened && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 52024 __next40pxDefaultSize: true, 52025 className: "block-editor-inserter__quick-inserter-expand", 52026 onClick: onBrowseAll, 52027 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Browse all. This will open the main inserter panel in the editor toolbar.'), 52028 children: (0,external_wp_i18n_namespaceObject.__)('Browse all') 52029 })] 52030 }); 52031 } 52032 52033 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/index.js 52034 /** 52035 * External dependencies 52036 */ 52037 52038 52039 /** 52040 * WordPress dependencies 52041 */ 52042 52043 52044 52045 52046 52047 52048 52049 52050 52051 /** 52052 * Internal dependencies 52053 */ 52054 52055 52056 52057 52058 const defaultRenderToggle = ({ 52059 onToggle, 52060 disabled, 52061 isOpen, 52062 blockTitle, 52063 hasSingleBlockType, 52064 toggleProps = {} 52065 }) => { 52066 const { 52067 as: Wrapper = external_wp_components_namespaceObject.Button, 52068 label: labelProp, 52069 onClick, 52070 ...rest 52071 } = toggleProps; 52072 let label = labelProp; 52073 if (!label && hasSingleBlockType) { 52074 label = (0,external_wp_i18n_namespaceObject.sprintf)( 52075 // translators: %s: the name of the block when there is only one 52076 (0,external_wp_i18n_namespaceObject._x)('Add %s', 'directly add the only allowed block'), blockTitle); 52077 } else if (!label) { 52078 label = (0,external_wp_i18n_namespaceObject._x)('Add block', 'Generic label for block inserter button'); 52079 } 52080 52081 // Handle both onClick functions from the toggle and the parent component. 52082 function handleClick(event) { 52083 if (onToggle) { 52084 onToggle(event); 52085 } 52086 if (onClick) { 52087 onClick(event); 52088 } 52089 } 52090 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Wrapper, { 52091 __next40pxDefaultSize: toggleProps.as ? undefined : true, 52092 icon: library_plus, 52093 label: label, 52094 tooltipPosition: "bottom", 52095 onClick: handleClick, 52096 className: "block-editor-inserter__toggle", 52097 "aria-haspopup": !hasSingleBlockType ? 'true' : false, 52098 "aria-expanded": !hasSingleBlockType ? isOpen : false, 52099 disabled: disabled, 52100 ...rest 52101 }); 52102 }; 52103 class Inserter extends external_wp_element_namespaceObject.Component { 52104 constructor() { 52105 super(...arguments); 52106 this.onToggle = this.onToggle.bind(this); 52107 this.renderToggle = this.renderToggle.bind(this); 52108 this.renderContent = this.renderContent.bind(this); 52109 } 52110 onToggle(isOpen) { 52111 const { 52112 onToggle 52113 } = this.props; 52114 52115 // Surface toggle callback to parent component. 52116 if (onToggle) { 52117 onToggle(isOpen); 52118 } 52119 } 52120 52121 /** 52122 * Render callback to display Dropdown toggle element. 52123 * 52124 * @param {Object} options 52125 * @param {Function} options.onToggle Callback to invoke when toggle is 52126 * pressed. 52127 * @param {boolean} options.isOpen Whether dropdown is currently open. 52128 * 52129 * @return {Element} Dropdown toggle element. 52130 */ 52131 renderToggle({ 52132 onToggle, 52133 isOpen 52134 }) { 52135 const { 52136 disabled, 52137 blockTitle, 52138 hasSingleBlockType, 52139 directInsertBlock, 52140 toggleProps, 52141 hasItems, 52142 renderToggle = defaultRenderToggle 52143 } = this.props; 52144 return renderToggle({ 52145 onToggle, 52146 isOpen, 52147 disabled: disabled || !hasItems, 52148 blockTitle, 52149 hasSingleBlockType, 52150 directInsertBlock, 52151 toggleProps 52152 }); 52153 } 52154 52155 /** 52156 * Render callback to display Dropdown content element. 52157 * 52158 * @param {Object} options 52159 * @param {Function} options.onClose Callback to invoke when dropdown is 52160 * closed. 52161 * 52162 * @return {Element} Dropdown content element. 52163 */ 52164 renderContent({ 52165 onClose 52166 }) { 52167 const { 52168 rootClientId, 52169 clientId, 52170 isAppender, 52171 showInserterHelpPanel, 52172 // This prop is experimental to give some time for the quick inserter to mature 52173 // Feel free to make them stable after a few releases. 52174 __experimentalIsQuick: isQuick, 52175 onSelectOrClose, 52176 selectBlockOnInsert 52177 } = this.props; 52178 if (isQuick) { 52179 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(QuickInserter, { 52180 onSelect: blocks => { 52181 const firstBlock = Array.isArray(blocks) && blocks?.length ? blocks[0] : blocks; 52182 if (onSelectOrClose && typeof onSelectOrClose === 'function') { 52183 onSelectOrClose(firstBlock); 52184 } 52185 onClose(); 52186 }, 52187 rootClientId: rootClientId, 52188 clientId: clientId, 52189 isAppender: isAppender, 52190 selectBlockOnInsert: selectBlockOnInsert 52191 }); 52192 } 52193 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(menu, { 52194 onSelect: () => { 52195 onClose(); 52196 }, 52197 rootClientId: rootClientId, 52198 clientId: clientId, 52199 isAppender: isAppender, 52200 showInserterHelpPanel: showInserterHelpPanel 52201 }); 52202 } 52203 render() { 52204 const { 52205 position, 52206 hasSingleBlockType, 52207 directInsertBlock, 52208 insertOnlyAllowedBlock, 52209 __experimentalIsQuick: isQuick, 52210 onSelectOrClose 52211 } = this.props; 52212 if (hasSingleBlockType || directInsertBlock) { 52213 return this.renderToggle({ 52214 onToggle: insertOnlyAllowedBlock 52215 }); 52216 } 52217 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 52218 className: "block-editor-inserter", 52219 contentClassName: dist_clsx('block-editor-inserter__popover', { 52220 'is-quick': isQuick 52221 }), 52222 popoverProps: { 52223 position, 52224 shift: true 52225 }, 52226 onToggle: this.onToggle, 52227 expandOnMobile: true, 52228 headerTitle: (0,external_wp_i18n_namespaceObject.__)('Add a block'), 52229 renderToggle: this.renderToggle, 52230 renderContent: this.renderContent, 52231 onClose: onSelectOrClose 52232 }); 52233 } 52234 } 52235 /* harmony default export */ const inserter = ((0,external_wp_compose_namespaceObject.compose)([(0,external_wp_data_namespaceObject.withSelect)((select, { 52236 clientId, 52237 rootClientId, 52238 shouldDirectInsert = true 52239 }) => { 52240 const { 52241 getBlockRootClientId, 52242 hasInserterItems, 52243 getAllowedBlocks, 52244 getDirectInsertBlock 52245 } = select(store); 52246 const { 52247 getBlockVariations 52248 } = select(external_wp_blocks_namespaceObject.store); 52249 rootClientId = rootClientId || getBlockRootClientId(clientId) || undefined; 52250 const allowedBlocks = getAllowedBlocks(rootClientId); 52251 const directInsertBlock = shouldDirectInsert && getDirectInsertBlock(rootClientId); 52252 const hasSingleBlockType = allowedBlocks?.length === 1 && getBlockVariations(allowedBlocks[0].name, 'inserter')?.length === 0; 52253 let allowedBlockType = false; 52254 if (hasSingleBlockType) { 52255 allowedBlockType = allowedBlocks[0]; 52256 } 52257 return { 52258 hasItems: hasInserterItems(rootClientId), 52259 hasSingleBlockType, 52260 blockTitle: allowedBlockType ? allowedBlockType.title : '', 52261 allowedBlockType, 52262 directInsertBlock, 52263 rootClientId 52264 }; 52265 }), (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps, { 52266 select 52267 }) => { 52268 return { 52269 insertOnlyAllowedBlock() { 52270 const { 52271 rootClientId, 52272 clientId, 52273 isAppender, 52274 hasSingleBlockType, 52275 allowedBlockType, 52276 directInsertBlock, 52277 onSelectOrClose, 52278 selectBlockOnInsert 52279 } = ownProps; 52280 if (!hasSingleBlockType && !directInsertBlock) { 52281 return; 52282 } 52283 function getAdjacentBlockAttributes(attributesToCopy) { 52284 const { 52285 getBlock, 52286 getPreviousBlockClientId 52287 } = select(store); 52288 if (!attributesToCopy || !clientId && !rootClientId) { 52289 return {}; 52290 } 52291 const result = {}; 52292 let adjacentAttributes = {}; 52293 52294 // If there is no clientId, then attempt to get attributes 52295 // from the last block within innerBlocks of the root block. 52296 if (!clientId) { 52297 const parentBlock = getBlock(rootClientId); 52298 if (parentBlock?.innerBlocks?.length) { 52299 const lastInnerBlock = parentBlock.innerBlocks[parentBlock.innerBlocks.length - 1]; 52300 if (directInsertBlock && directInsertBlock?.name === lastInnerBlock.name) { 52301 adjacentAttributes = lastInnerBlock.attributes; 52302 } 52303 } 52304 } else { 52305 // Otherwise, attempt to get attributes from the 52306 // previous block relative to the current clientId. 52307 const currentBlock = getBlock(clientId); 52308 const previousBlock = getBlock(getPreviousBlockClientId(clientId)); 52309 if (currentBlock?.name === previousBlock?.name) { 52310 adjacentAttributes = previousBlock?.attributes || {}; 52311 } 52312 } 52313 52314 // Copy over only those attributes flagged to be copied. 52315 attributesToCopy.forEach(attribute => { 52316 if (adjacentAttributes.hasOwnProperty(attribute)) { 52317 result[attribute] = adjacentAttributes[attribute]; 52318 } 52319 }); 52320 return result; 52321 } 52322 function getInsertionIndex() { 52323 const { 52324 getBlockIndex, 52325 getBlockSelectionEnd, 52326 getBlockOrder, 52327 getBlockRootClientId 52328 } = select(store); 52329 52330 // If the clientId is defined, we insert at the position of the block. 52331 if (clientId) { 52332 return getBlockIndex(clientId); 52333 } 52334 52335 // If there a selected block, we insert after the selected block. 52336 const end = getBlockSelectionEnd(); 52337 if (!isAppender && end && getBlockRootClientId(end) === rootClientId) { 52338 return getBlockIndex(end) + 1; 52339 } 52340 52341 // Otherwise, we insert at the end of the current rootClientId. 52342 return getBlockOrder(rootClientId).length; 52343 } 52344 const { 52345 insertBlock 52346 } = dispatch(store); 52347 let blockToInsert; 52348 52349 // Attempt to augment the directInsertBlock with attributes from an adjacent block. 52350 // This ensures styling from nearby blocks is preserved in the newly inserted block. 52351 // See: https://github.com/WordPress/gutenberg/issues/37904 52352 if (directInsertBlock) { 52353 const newAttributes = getAdjacentBlockAttributes(directInsertBlock.attributesToCopy); 52354 blockToInsert = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, { 52355 ...(directInsertBlock.attributes || {}), 52356 ...newAttributes 52357 }); 52358 } else { 52359 blockToInsert = (0,external_wp_blocks_namespaceObject.createBlock)(allowedBlockType.name); 52360 } 52361 insertBlock(blockToInsert, getInsertionIndex(), rootClientId, selectBlockOnInsert); 52362 if (onSelectOrClose) { 52363 onSelectOrClose({ 52364 clientId: blockToInsert?.clientId 52365 }); 52366 } 52367 const message = (0,external_wp_i18n_namespaceObject.sprintf)( 52368 // translators: %s: the name of the block that has been added 52369 (0,external_wp_i18n_namespaceObject.__)('%s block added'), allowedBlockType.title); 52370 (0,external_wp_a11y_namespaceObject.speak)(message); 52371 } 52372 }; 52373 }), 52374 // The global inserter should always be visible, we are using ( ! isAppender && ! rootClientId && ! clientId ) as 52375 // a way to detect the global Inserter. 52376 (0,external_wp_compose_namespaceObject.ifCondition)(({ 52377 hasItems, 52378 isAppender, 52379 rootClientId, 52380 clientId 52381 }) => hasItems || !isAppender && !rootClientId && !clientId)])(Inserter)); 52382 52383 ;// ./node_modules/@wordpress/block-editor/build-module/components/button-block-appender/index.js 52384 /** 52385 * External dependencies 52386 */ 52387 52388 52389 /** 52390 * WordPress dependencies 52391 */ 52392 52393 52394 52395 52396 52397 52398 /** 52399 * Internal dependencies 52400 */ 52401 52402 52403 function button_block_appender_ButtonBlockAppender({ 52404 rootClientId, 52405 className, 52406 onFocus, 52407 tabIndex, 52408 onSelect 52409 }, ref) { 52410 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter, { 52411 position: "bottom center", 52412 rootClientId: rootClientId, 52413 __experimentalIsQuick: true, 52414 onSelectOrClose: (...args) => { 52415 if (onSelect && typeof onSelect === 'function') { 52416 onSelect(...args); 52417 } 52418 }, 52419 renderToggle: ({ 52420 onToggle, 52421 disabled, 52422 isOpen, 52423 blockTitle, 52424 hasSingleBlockType 52425 }) => { 52426 const isToggleButton = !hasSingleBlockType; 52427 const label = hasSingleBlockType ? (0,external_wp_i18n_namespaceObject.sprintf)( 52428 // translators: %s: the name of the block when there is only one 52429 (0,external_wp_i18n_namespaceObject._x)('Add %s', 'directly add the only allowed block'), blockTitle) : (0,external_wp_i18n_namespaceObject._x)('Add block', 'Generic label for block inserter button'); 52430 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 52431 __next40pxDefaultSize: true, 52432 ref: ref, 52433 onFocus: onFocus, 52434 tabIndex: tabIndex, 52435 className: dist_clsx(className, 'block-editor-button-block-appender'), 52436 onClick: onToggle, 52437 "aria-haspopup": isToggleButton ? 'true' : undefined, 52438 "aria-expanded": isToggleButton ? isOpen : undefined 52439 // Disable reason: There shouldn't be a case where this button is disabled but not visually hidden. 52440 // eslint-disable-next-line no-restricted-syntax 52441 , 52442 disabled: disabled, 52443 label: label, 52444 showTooltip: true, 52445 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 52446 icon: library_plus 52447 }) 52448 }); 52449 }, 52450 isAppender: true 52451 }); 52452 } 52453 52454 /** 52455 * Use `ButtonBlockAppender` instead. 52456 * 52457 * @deprecated 52458 */ 52459 const ButtonBlockerAppender = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 52460 external_wp_deprecated_default()(`wp.blockEditor.ButtonBlockerAppender`, { 52461 alternative: 'wp.blockEditor.ButtonBlockAppender', 52462 since: '5.9' 52463 }); 52464 return button_block_appender_ButtonBlockAppender(props, ref); 52465 }); 52466 52467 /** 52468 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/button-block-appender/README.md 52469 */ 52470 /* harmony default export */ const button_block_appender = ((0,external_wp_element_namespaceObject.forwardRef)(button_block_appender_ButtonBlockAppender)); 52471 52472 ;// ./node_modules/@wordpress/block-editor/build-module/components/grid/grid-visualizer.js 52473 /** 52474 * External dependencies 52475 */ 52476 52477 52478 /** 52479 * WordPress dependencies 52480 */ 52481 52482 52483 52484 52485 /** 52486 * Internal dependencies 52487 */ 52488 52489 52490 52491 52492 52493 52494 52495 52496 function GridVisualizer({ 52497 clientId, 52498 contentRef, 52499 parentLayout 52500 }) { 52501 const isDistractionFree = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree, []); 52502 const gridElement = useBlockElement(clientId); 52503 if (isDistractionFree || !gridElement) { 52504 return null; 52505 } 52506 const isManualGrid = parentLayout?.isManualPlacement && window.__experimentalEnableGridInteractivity; 52507 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizerGrid, { 52508 gridClientId: clientId, 52509 gridElement: gridElement, 52510 isManualGrid: isManualGrid, 52511 ref: contentRef 52512 }); 52513 } 52514 const GridVisualizerGrid = (0,external_wp_element_namespaceObject.forwardRef)(({ 52515 gridClientId, 52516 gridElement, 52517 isManualGrid 52518 }, ref) => { 52519 const [gridInfo, setGridInfo] = (0,external_wp_element_namespaceObject.useState)(() => getGridInfo(gridElement)); 52520 const [isDroppingAllowed, setIsDroppingAllowed] = (0,external_wp_element_namespaceObject.useState)(false); 52521 (0,external_wp_element_namespaceObject.useEffect)(() => { 52522 const resizeCallback = () => setGridInfo(getGridInfo(gridElement)); 52523 // Both border-box and content-box are observed as they may change 52524 // independently. This requires two observers because a single one 52525 // can’t be made to monitor both on the same element. 52526 const borderBoxSpy = new window.ResizeObserver(resizeCallback); 52527 borderBoxSpy.observe(gridElement, { 52528 box: 'border-box' 52529 }); 52530 const contentBoxSpy = new window.ResizeObserver(resizeCallback); 52531 contentBoxSpy.observe(gridElement); 52532 return () => { 52533 borderBoxSpy.disconnect(); 52534 contentBoxSpy.disconnect(); 52535 }; 52536 }, [gridElement]); 52537 (0,external_wp_element_namespaceObject.useEffect)(() => { 52538 function onGlobalDrag() { 52539 setIsDroppingAllowed(true); 52540 } 52541 function onGlobalDragEnd() { 52542 setIsDroppingAllowed(false); 52543 } 52544 document.addEventListener('drag', onGlobalDrag); 52545 document.addEventListener('dragend', onGlobalDragEnd); 52546 return () => { 52547 document.removeEventListener('drag', onGlobalDrag); 52548 document.removeEventListener('dragend', onGlobalDragEnd); 52549 }; 52550 }, []); 52551 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(cover, { 52552 className: dist_clsx('block-editor-grid-visualizer', { 52553 'is-dropping-allowed': isDroppingAllowed 52554 }), 52555 clientId: gridClientId, 52556 __unstablePopoverSlot: "__unstable-block-tools-after", 52557 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 52558 ref: ref, 52559 className: "block-editor-grid-visualizer__grid", 52560 style: gridInfo.style, 52561 children: isManualGrid ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ManualGridVisualizer, { 52562 gridClientId: gridClientId, 52563 gridInfo: gridInfo 52564 }) : Array.from({ 52565 length: gridInfo.numItems 52566 }, (_, i) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizerCell, { 52567 color: gridInfo.currentColor 52568 }, i)) 52569 }) 52570 }); 52571 }); 52572 function ManualGridVisualizer({ 52573 gridClientId, 52574 gridInfo 52575 }) { 52576 const [highlightedRect, setHighlightedRect] = (0,external_wp_element_namespaceObject.useState)(null); 52577 const gridItemStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 52578 const { 52579 getBlockOrder, 52580 getBlockStyles 52581 } = unlock(select(store)); 52582 const blockOrder = getBlockOrder(gridClientId); 52583 return getBlockStyles(blockOrder); 52584 }, [gridClientId]); 52585 const occupiedRects = (0,external_wp_element_namespaceObject.useMemo)(() => { 52586 const rects = []; 52587 for (const style of Object.values(gridItemStyles)) { 52588 var _style$layout; 52589 const { 52590 columnStart, 52591 rowStart, 52592 columnSpan = 1, 52593 rowSpan = 1 52594 } = (_style$layout = style?.layout) !== null && _style$layout !== void 0 ? _style$layout : {}; 52595 if (!columnStart || !rowStart) { 52596 continue; 52597 } 52598 rects.push(new GridRect({ 52599 columnStart, 52600 rowStart, 52601 columnSpan, 52602 rowSpan 52603 })); 52604 } 52605 return rects; 52606 }, [gridItemStyles]); 52607 return range(1, gridInfo.numRows).map(row => range(1, gridInfo.numColumns).map(column => { 52608 var _highlightedRect$cont; 52609 const isCellOccupied = occupiedRects.some(rect => rect.contains(column, row)); 52610 const isHighlighted = (_highlightedRect$cont = highlightedRect?.contains(column, row)) !== null && _highlightedRect$cont !== void 0 ? _highlightedRect$cont : false; 52611 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizerCell, { 52612 color: gridInfo.currentColor, 52613 className: isHighlighted && 'is-highlighted', 52614 children: isCellOccupied ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizerDropZone, { 52615 column: column, 52616 row: row, 52617 gridClientId: gridClientId, 52618 gridInfo: gridInfo, 52619 setHighlightedRect: setHighlightedRect 52620 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizerAppender, { 52621 column: column, 52622 row: row, 52623 gridClientId: gridClientId, 52624 gridInfo: gridInfo, 52625 setHighlightedRect: setHighlightedRect 52626 }) 52627 }, `$row}-$column}`); 52628 })); 52629 } 52630 function GridVisualizerCell({ 52631 color, 52632 children, 52633 className 52634 }) { 52635 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 52636 className: dist_clsx('block-editor-grid-visualizer__cell', className), 52637 style: { 52638 boxShadow: `inset 0 0 0 1px color-mix(in srgb, $color} 20%, #0000)`, 52639 color 52640 }, 52641 children: children 52642 }); 52643 } 52644 function useGridVisualizerDropZone(column, row, gridClientId, gridInfo, setHighlightedRect) { 52645 const { 52646 getBlockAttributes, 52647 getBlockRootClientId, 52648 canInsertBlockType, 52649 getBlockName 52650 } = (0,external_wp_data_namespaceObject.useSelect)(store); 52651 const { 52652 updateBlockAttributes, 52653 moveBlocksToPosition, 52654 __unstableMarkNextChangeAsNotPersistent 52655 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 52656 const getNumberOfBlocksBeforeCell = useGetNumberOfBlocksBeforeCell(gridClientId, gridInfo.numColumns); 52657 return useDropZoneWithValidation({ 52658 validateDrag(srcClientId) { 52659 const blockName = getBlockName(srcClientId); 52660 if (!canInsertBlockType(blockName, gridClientId)) { 52661 return false; 52662 } 52663 const attributes = getBlockAttributes(srcClientId); 52664 const rect = new GridRect({ 52665 columnStart: column, 52666 rowStart: row, 52667 columnSpan: attributes.style?.layout?.columnSpan, 52668 rowSpan: attributes.style?.layout?.rowSpan 52669 }); 52670 const isInBounds = new GridRect({ 52671 columnSpan: gridInfo.numColumns, 52672 rowSpan: gridInfo.numRows 52673 }).containsRect(rect); 52674 return isInBounds; 52675 }, 52676 onDragEnter(srcClientId) { 52677 const attributes = getBlockAttributes(srcClientId); 52678 setHighlightedRect(new GridRect({ 52679 columnStart: column, 52680 rowStart: row, 52681 columnSpan: attributes.style?.layout?.columnSpan, 52682 rowSpan: attributes.style?.layout?.rowSpan 52683 })); 52684 }, 52685 onDragLeave() { 52686 // onDragEnter can be called before onDragLeave if the user moves 52687 // their mouse quickly, so only clear the highlight if it was set 52688 // by this cell. 52689 setHighlightedRect(prevHighlightedRect => prevHighlightedRect?.columnStart === column && prevHighlightedRect?.rowStart === row ? null : prevHighlightedRect); 52690 }, 52691 onDrop(srcClientId) { 52692 setHighlightedRect(null); 52693 const attributes = getBlockAttributes(srcClientId); 52694 updateBlockAttributes(srcClientId, { 52695 style: { 52696 ...attributes.style, 52697 layout: { 52698 ...attributes.style?.layout, 52699 columnStart: column, 52700 rowStart: row 52701 } 52702 } 52703 }); 52704 __unstableMarkNextChangeAsNotPersistent(); 52705 moveBlocksToPosition([srcClientId], getBlockRootClientId(srcClientId), gridClientId, getNumberOfBlocksBeforeCell(column, row)); 52706 } 52707 }); 52708 } 52709 function GridVisualizerDropZone({ 52710 column, 52711 row, 52712 gridClientId, 52713 gridInfo, 52714 setHighlightedRect 52715 }) { 52716 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 52717 className: "block-editor-grid-visualizer__drop-zone", 52718 ref: useGridVisualizerDropZone(column, row, gridClientId, gridInfo, setHighlightedRect) 52719 }); 52720 } 52721 function GridVisualizerAppender({ 52722 column, 52723 row, 52724 gridClientId, 52725 gridInfo, 52726 setHighlightedRect 52727 }) { 52728 const { 52729 updateBlockAttributes, 52730 moveBlocksToPosition, 52731 __unstableMarkNextChangeAsNotPersistent 52732 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 52733 const getNumberOfBlocksBeforeCell = useGetNumberOfBlocksBeforeCell(gridClientId, gridInfo.numColumns); 52734 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(button_block_appender, { 52735 rootClientId: gridClientId, 52736 className: "block-editor-grid-visualizer__appender", 52737 ref: useGridVisualizerDropZone(column, row, gridClientId, gridInfo, setHighlightedRect), 52738 style: { 52739 color: gridInfo.currentColor 52740 }, 52741 onSelect: block => { 52742 if (!block) { 52743 return; 52744 } 52745 updateBlockAttributes(block.clientId, { 52746 style: { 52747 layout: { 52748 columnStart: column, 52749 rowStart: row 52750 } 52751 } 52752 }); 52753 __unstableMarkNextChangeAsNotPersistent(); 52754 moveBlocksToPosition([block.clientId], gridClientId, gridClientId, getNumberOfBlocksBeforeCell(column, row)); 52755 } 52756 }); 52757 } 52758 function useDropZoneWithValidation({ 52759 validateDrag, 52760 onDragEnter, 52761 onDragLeave, 52762 onDrop 52763 }) { 52764 const { 52765 getDraggedBlockClientIds 52766 } = (0,external_wp_data_namespaceObject.useSelect)(store); 52767 return (0,external_wp_compose_namespaceObject.__experimentalUseDropZone)({ 52768 onDragEnter() { 52769 const [srcClientId] = getDraggedBlockClientIds(); 52770 if (srcClientId && validateDrag(srcClientId)) { 52771 onDragEnter(srcClientId); 52772 } 52773 }, 52774 onDragLeave() { 52775 onDragLeave(); 52776 }, 52777 onDrop() { 52778 const [srcClientId] = getDraggedBlockClientIds(); 52779 if (srcClientId && validateDrag(srcClientId)) { 52780 onDrop(srcClientId); 52781 } 52782 } 52783 }); 52784 } 52785 52786 ;// ./node_modules/@wordpress/block-editor/build-module/components/grid/grid-item-resizer.js 52787 /** 52788 * WordPress dependencies 52789 */ 52790 52791 52792 52793 /** 52794 * Internal dependencies 52795 */ 52796 52797 52798 52799 52800 function GridItemResizer({ 52801 clientId, 52802 bounds, 52803 onChange, 52804 parentLayout 52805 }) { 52806 const blockElement = useBlockElement(clientId); 52807 const rootBlockElement = blockElement?.parentElement; 52808 const { 52809 isManualPlacement 52810 } = parentLayout; 52811 if (!blockElement || !rootBlockElement) { 52812 return null; 52813 } 52814 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemResizerInner, { 52815 clientId: clientId, 52816 bounds: bounds, 52817 blockElement: blockElement, 52818 rootBlockElement: rootBlockElement, 52819 onChange: onChange, 52820 isManualGrid: isManualPlacement && window.__experimentalEnableGridInteractivity 52821 }); 52822 } 52823 function GridItemResizerInner({ 52824 clientId, 52825 bounds, 52826 blockElement, 52827 rootBlockElement, 52828 onChange, 52829 isManualGrid 52830 }) { 52831 const [resizeDirection, setResizeDirection] = (0,external_wp_element_namespaceObject.useState)(null); 52832 const [enableSide, setEnableSide] = (0,external_wp_element_namespaceObject.useState)({ 52833 top: false, 52834 bottom: false, 52835 left: false, 52836 right: false 52837 }); 52838 (0,external_wp_element_namespaceObject.useEffect)(() => { 52839 const observer = new window.ResizeObserver(() => { 52840 const blockClientRect = blockElement.getBoundingClientRect(); 52841 const rootBlockClientRect = rootBlockElement.getBoundingClientRect(); 52842 setEnableSide({ 52843 top: blockClientRect.top > rootBlockClientRect.top, 52844 bottom: blockClientRect.bottom < rootBlockClientRect.bottom, 52845 left: blockClientRect.left > rootBlockClientRect.left, 52846 right: blockClientRect.right < rootBlockClientRect.right 52847 }); 52848 }); 52849 observer.observe(blockElement); 52850 return () => observer.disconnect(); 52851 }, [blockElement, rootBlockElement]); 52852 const justification = { 52853 right: 'left', 52854 left: 'right' 52855 }; 52856 const alignment = { 52857 top: 'flex-end', 52858 bottom: 'flex-start' 52859 }; 52860 const styles = { 52861 display: 'flex', 52862 justifyContent: 'center', 52863 alignItems: 'center', 52864 ...(justification[resizeDirection] && { 52865 justifyContent: justification[resizeDirection] 52866 }), 52867 ...(alignment[resizeDirection] && { 52868 alignItems: alignment[resizeDirection] 52869 }) 52870 }; 52871 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(cover, { 52872 className: "block-editor-grid-item-resizer", 52873 clientId: clientId, 52874 __unstablePopoverSlot: "__unstable-block-tools-after", 52875 additionalStyles: styles, 52876 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ResizableBox, { 52877 className: "block-editor-grid-item-resizer__box", 52878 size: { 52879 width: '100%', 52880 height: '100%' 52881 }, 52882 enable: { 52883 bottom: enableSide.bottom, 52884 bottomLeft: false, 52885 bottomRight: false, 52886 left: enableSide.left, 52887 right: enableSide.right, 52888 top: enableSide.top, 52889 topLeft: false, 52890 topRight: false 52891 }, 52892 bounds: bounds, 52893 boundsByDirection: true, 52894 onPointerDown: ({ 52895 target, 52896 pointerId 52897 }) => { 52898 /* 52899 * Captures the pointer to avoid hiccups while dragging over objects 52900 * like iframes and ensures that the event to end the drag is 52901 * captured by the target (resize handle) whether or not it’s under 52902 * the pointer. 52903 */ 52904 target.setPointerCapture(pointerId); 52905 }, 52906 onResizeStart: (event, direction) => { 52907 /* 52908 * The container justification and alignment need to be set 52909 * according to the direction the resizer is being dragged in, 52910 * so that it resizes in the right direction. 52911 */ 52912 setResizeDirection(direction); 52913 }, 52914 onResizeStop: (event, direction, boxElement) => { 52915 const columnGap = parseFloat(utils_getComputedCSS(rootBlockElement, 'column-gap')); 52916 const rowGap = parseFloat(utils_getComputedCSS(rootBlockElement, 'row-gap')); 52917 const gridColumnTracks = getGridTracks(utils_getComputedCSS(rootBlockElement, 'grid-template-columns'), columnGap); 52918 const gridRowTracks = getGridTracks(utils_getComputedCSS(rootBlockElement, 'grid-template-rows'), rowGap); 52919 const rect = new window.DOMRect(blockElement.offsetLeft + boxElement.offsetLeft, blockElement.offsetTop + boxElement.offsetTop, boxElement.offsetWidth, boxElement.offsetHeight); 52920 const columnStart = getClosestTrack(gridColumnTracks, rect.left) + 1; 52921 const rowStart = getClosestTrack(gridRowTracks, rect.top) + 1; 52922 const columnEnd = getClosestTrack(gridColumnTracks, rect.right, 'end') + 1; 52923 const rowEnd = getClosestTrack(gridRowTracks, rect.bottom, 'end') + 1; 52924 onChange({ 52925 columnSpan: columnEnd - columnStart + 1, 52926 rowSpan: rowEnd - rowStart + 1, 52927 columnStart: isManualGrid ? columnStart : undefined, 52928 rowStart: isManualGrid ? rowStart : undefined 52929 }); 52930 } 52931 }) 52932 }); 52933 } 52934 52935 ;// ./node_modules/@wordpress/icons/build-module/library/chevron-up.js 52936 /** 52937 * WordPress dependencies 52938 */ 52939 52940 52941 const chevronUp = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 52942 viewBox: "0 0 24 24", 52943 xmlns: "http://www.w3.org/2000/svg", 52944 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 52945 d: "M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z" 52946 }) 52947 }); 52948 /* harmony default export */ const chevron_up = (chevronUp); 52949 52950 ;// ./node_modules/@wordpress/icons/build-module/library/chevron-down.js 52951 /** 52952 * WordPress dependencies 52953 */ 52954 52955 52956 const chevronDown = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 52957 viewBox: "0 0 24 24", 52958 xmlns: "http://www.w3.org/2000/svg", 52959 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 52960 d: "M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z" 52961 }) 52962 }); 52963 /* harmony default export */ const chevron_down = (chevronDown); 52964 52965 ;// ./node_modules/@wordpress/block-editor/build-module/components/grid/grid-item-movers.js 52966 /** 52967 * External dependencies 52968 */ 52969 52970 52971 /** 52972 * WordPress dependencies 52973 */ 52974 52975 52976 52977 52978 52979 52980 /** 52981 * Internal dependencies 52982 */ 52983 52984 52985 52986 52987 function GridItemMovers({ 52988 layout, 52989 parentLayout, 52990 onChange, 52991 gridClientId, 52992 blockClientId 52993 }) { 52994 var _layout$columnStart, _layout$rowStart, _layout$columnSpan, _layout$rowSpan; 52995 const { 52996 moveBlocksToPosition, 52997 __unstableMarkNextChangeAsNotPersistent 52998 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 52999 const columnStart = (_layout$columnStart = layout?.columnStart) !== null && _layout$columnStart !== void 0 ? _layout$columnStart : 1; 53000 const rowStart = (_layout$rowStart = layout?.rowStart) !== null && _layout$rowStart !== void 0 ? _layout$rowStart : 1; 53001 const columnSpan = (_layout$columnSpan = layout?.columnSpan) !== null && _layout$columnSpan !== void 0 ? _layout$columnSpan : 1; 53002 const rowSpan = (_layout$rowSpan = layout?.rowSpan) !== null && _layout$rowSpan !== void 0 ? _layout$rowSpan : 1; 53003 const columnEnd = columnStart + columnSpan - 1; 53004 const rowEnd = rowStart + rowSpan - 1; 53005 const columnCount = parentLayout?.columnCount; 53006 const rowCount = parentLayout?.rowCount; 53007 const getNumberOfBlocksBeforeCell = useGetNumberOfBlocksBeforeCell(gridClientId, columnCount); 53008 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 53009 group: "parent", 53010 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.ToolbarGroup, { 53011 className: "block-editor-grid-item-mover__move-button-container", 53012 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 53013 className: "block-editor-grid-item-mover__move-horizontal-button-container is-left", 53014 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemMover, { 53015 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left, 53016 label: (0,external_wp_i18n_namespaceObject.__)('Move left'), 53017 description: (0,external_wp_i18n_namespaceObject.__)('Move left'), 53018 isDisabled: columnStart <= 1, 53019 onClick: () => { 53020 onChange({ 53021 columnStart: columnStart - 1 53022 }); 53023 __unstableMarkNextChangeAsNotPersistent(); 53024 moveBlocksToPosition([blockClientId], gridClientId, gridClientId, getNumberOfBlocksBeforeCell(columnStart - 1, rowStart)); 53025 } 53026 }) 53027 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 53028 className: "block-editor-grid-item-mover__move-vertical-button-container", 53029 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemMover, { 53030 className: "is-up-button", 53031 icon: chevron_up, 53032 label: (0,external_wp_i18n_namespaceObject.__)('Move up'), 53033 description: (0,external_wp_i18n_namespaceObject.__)('Move up'), 53034 isDisabled: rowStart <= 1, 53035 onClick: () => { 53036 onChange({ 53037 rowStart: rowStart - 1 53038 }); 53039 __unstableMarkNextChangeAsNotPersistent(); 53040 moveBlocksToPosition([blockClientId], gridClientId, gridClientId, getNumberOfBlocksBeforeCell(columnStart, rowStart - 1)); 53041 } 53042 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemMover, { 53043 className: "is-down-button", 53044 icon: chevron_down, 53045 label: (0,external_wp_i18n_namespaceObject.__)('Move down'), 53046 description: (0,external_wp_i18n_namespaceObject.__)('Move down'), 53047 isDisabled: rowCount && rowEnd >= rowCount, 53048 onClick: () => { 53049 onChange({ 53050 rowStart: rowStart + 1 53051 }); 53052 __unstableMarkNextChangeAsNotPersistent(); 53053 moveBlocksToPosition([blockClientId], gridClientId, gridClientId, getNumberOfBlocksBeforeCell(columnStart, rowStart + 1)); 53054 } 53055 })] 53056 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 53057 className: "block-editor-grid-item-mover__move-horizontal-button-container is-right", 53058 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemMover, { 53059 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right, 53060 label: (0,external_wp_i18n_namespaceObject.__)('Move right'), 53061 description: (0,external_wp_i18n_namespaceObject.__)('Move right'), 53062 isDisabled: columnCount && columnEnd >= columnCount, 53063 onClick: () => { 53064 onChange({ 53065 columnStart: columnStart + 1 53066 }); 53067 __unstableMarkNextChangeAsNotPersistent(); 53068 moveBlocksToPosition([blockClientId], gridClientId, gridClientId, getNumberOfBlocksBeforeCell(columnStart + 1, rowStart)); 53069 } 53070 }) 53071 })] 53072 }) 53073 }); 53074 } 53075 function GridItemMover({ 53076 className, 53077 icon, 53078 label, 53079 isDisabled, 53080 onClick, 53081 description 53082 }) { 53083 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(GridItemMover); 53084 const descriptionId = `block-editor-grid-item-mover-button__description-$instanceId}`; 53085 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 53086 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 53087 className: dist_clsx('block-editor-grid-item-mover-button', className), 53088 icon: icon, 53089 label: label, 53090 "aria-describedby": descriptionId, 53091 onClick: isDisabled ? null : onClick, 53092 disabled: isDisabled, 53093 accessibleWhenDisabled: true 53094 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 53095 id: descriptionId, 53096 children: description 53097 })] 53098 }); 53099 } 53100 53101 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/layout-child.js 53102 /** 53103 * WordPress dependencies 53104 */ 53105 53106 53107 53108 53109 /** 53110 * Internal dependencies 53111 */ 53112 53113 53114 53115 53116 53117 // Used for generating the instance ID 53118 53119 const LAYOUT_CHILD_BLOCK_PROPS_REFERENCE = {}; 53120 function useBlockPropsChildLayoutStyles({ 53121 style 53122 }) { 53123 var _style$layout; 53124 const shouldRenderChildLayoutStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 53125 return !select(store).getSettings().disableLayoutStyles; 53126 }); 53127 const layout = (_style$layout = style?.layout) !== null && _style$layout !== void 0 ? _style$layout : {}; 53128 const { 53129 selfStretch, 53130 flexSize, 53131 columnStart, 53132 rowStart, 53133 columnSpan, 53134 rowSpan 53135 } = layout; 53136 const parentLayout = useLayout() || {}; 53137 const { 53138 columnCount, 53139 minimumColumnWidth 53140 } = parentLayout; 53141 const id = (0,external_wp_compose_namespaceObject.useInstanceId)(LAYOUT_CHILD_BLOCK_PROPS_REFERENCE); 53142 const selector = `.wp-container-content-$id}`; 53143 53144 // Check that the grid layout attributes are of the correct type, so that we don't accidentally 53145 // write code that stores a string attribute instead of a number. 53146 if (false) {} 53147 let css = ''; 53148 if (shouldRenderChildLayoutStyles) { 53149 if (selfStretch === 'fixed' && flexSize) { 53150 css = `$selector} { 53151 flex-basis: $flexSize}; 53152 box-sizing: border-box; 53153 }`; 53154 } else if (selfStretch === 'fill') { 53155 css = `$selector} { 53156 flex-grow: 1; 53157 }`; 53158 } else if (columnStart && columnSpan) { 53159 css = `$selector} { 53160 grid-column: $columnStart} / span $columnSpan}; 53161 }`; 53162 } else if (columnStart) { 53163 css = `$selector} { 53164 grid-column: $columnStart}; 53165 }`; 53166 } else if (columnSpan) { 53167 css = `$selector} { 53168 grid-column: span $columnSpan}; 53169 }`; 53170 } 53171 if (rowStart && rowSpan) { 53172 css += `$selector} { 53173 grid-row: $rowStart} / span $rowSpan}; 53174 }`; 53175 } else if (rowStart) { 53176 css += `$selector} { 53177 grid-row: $rowStart}; 53178 }`; 53179 } else if (rowSpan) { 53180 css += `$selector} { 53181 grid-row: span $rowSpan}; 53182 }`; 53183 } 53184 /** 53185 * If minimumColumnWidth is set on the parent, or if no 53186 * columnCount is set, the grid is responsive so a 53187 * container query is needed for the span to resize. 53188 */ 53189 if ((columnSpan || columnStart) && (minimumColumnWidth || !columnCount)) { 53190 let parentColumnValue = parseFloat(minimumColumnWidth); 53191 /** 53192 * 12rem is the default minimumColumnWidth value. 53193 * If parentColumnValue is not a number, default to 12. 53194 */ 53195 if (isNaN(parentColumnValue)) { 53196 parentColumnValue = 12; 53197 } 53198 let parentColumnUnit = minimumColumnWidth?.replace(parentColumnValue, ''); 53199 /** 53200 * Check that parent column unit is either 'px', 'rem' or 'em'. 53201 * If not, default to 'rem'. 53202 */ 53203 if (!['px', 'rem', 'em'].includes(parentColumnUnit)) { 53204 parentColumnUnit = 'rem'; 53205 } 53206 let numColsToBreakAt = 2; 53207 if (columnSpan && columnStart) { 53208 numColsToBreakAt = columnSpan + columnStart - 1; 53209 } else if (columnSpan) { 53210 numColsToBreakAt = columnSpan; 53211 } else { 53212 numColsToBreakAt = columnStart; 53213 } 53214 const defaultGapValue = parentColumnUnit === 'px' ? 24 : 1.5; 53215 const containerQueryValue = numColsToBreakAt * parentColumnValue + (numColsToBreakAt - 1) * defaultGapValue; 53216 // For blocks that only span one column, we want to remove any rowStart values as 53217 // the container reduces in size, so that blocks are still arranged in markup order. 53218 const minimumContainerQueryValue = parentColumnValue * 2 + defaultGapValue - 1; 53219 // If a span is set we want to preserve it as long as possible, otherwise we just reset the value. 53220 const gridColumnValue = columnSpan && columnSpan > 1 ? '1/-1' : 'auto'; 53221 css += `@container (max-width: $Math.max(containerQueryValue, minimumContainerQueryValue)}$parentColumnUnit}) { 53222 $selector} { 53223 grid-column: $gridColumnValue}; 53224 grid-row: auto; 53225 } 53226 }`; 53227 } 53228 } 53229 useStyleOverride({ 53230 css 53231 }); 53232 53233 // Only attach a container class if there is generated CSS to be attached. 53234 if (!css) { 53235 return; 53236 } 53237 53238 // Attach a `wp-container-content` id-based classname. 53239 return { 53240 className: `wp-container-content-$id}` 53241 }; 53242 } 53243 function ChildLayoutControlsPure({ 53244 clientId, 53245 style, 53246 setAttributes 53247 }) { 53248 const parentLayout = useLayout() || {}; 53249 const { 53250 type: parentLayoutType = 'default', 53251 allowSizingOnChildren = false, 53252 isManualPlacement 53253 } = parentLayout; 53254 if (parentLayoutType !== 'grid') { 53255 return null; 53256 } 53257 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridTools, { 53258 clientId: clientId, 53259 style: style, 53260 setAttributes: setAttributes, 53261 allowSizingOnChildren: allowSizingOnChildren, 53262 isManualPlacement: isManualPlacement, 53263 parentLayout: parentLayout 53264 }); 53265 } 53266 function GridTools({ 53267 clientId, 53268 style, 53269 setAttributes, 53270 allowSizingOnChildren, 53271 isManualPlacement, 53272 parentLayout 53273 }) { 53274 const { 53275 rootClientId, 53276 isVisible 53277 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 53278 const { 53279 getBlockRootClientId, 53280 getBlockEditingMode, 53281 getTemplateLock 53282 } = select(store); 53283 const _rootClientId = getBlockRootClientId(clientId); 53284 if (getTemplateLock(_rootClientId) || getBlockEditingMode(_rootClientId) !== 'default') { 53285 return { 53286 rootClientId: _rootClientId, 53287 isVisible: false 53288 }; 53289 } 53290 return { 53291 rootClientId: _rootClientId, 53292 isVisible: true 53293 }; 53294 }, [clientId]); 53295 53296 // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. 53297 const [resizerBounds, setResizerBounds] = (0,external_wp_element_namespaceObject.useState)(); 53298 if (!isVisible) { 53299 return null; 53300 } 53301 function updateLayout(layout) { 53302 setAttributes({ 53303 style: { 53304 ...style, 53305 layout: { 53306 ...style?.layout, 53307 ...layout 53308 } 53309 } 53310 }); 53311 } 53312 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 53313 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizer, { 53314 clientId: rootClientId, 53315 contentRef: setResizerBounds, 53316 parentLayout: parentLayout 53317 }), allowSizingOnChildren && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemResizer, { 53318 clientId: clientId 53319 // Don't allow resizing beyond the grid visualizer. 53320 , 53321 bounds: resizerBounds, 53322 onChange: updateLayout, 53323 parentLayout: parentLayout 53324 }), isManualPlacement && window.__experimentalEnableGridInteractivity && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridItemMovers, { 53325 layout: style?.layout, 53326 parentLayout: parentLayout, 53327 onChange: updateLayout, 53328 gridClientId: rootClientId, 53329 blockClientId: clientId 53330 })] 53331 }); 53332 } 53333 /* harmony default export */ const layout_child = ({ 53334 useBlockProps: useBlockPropsChildLayoutStyles, 53335 edit: ChildLayoutControlsPure, 53336 attributeKeys: ['style'], 53337 hasSupport() { 53338 return true; 53339 } 53340 }); 53341 53342 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/content-lock-ui.js 53343 /** 53344 * WordPress dependencies 53345 */ 53346 53347 53348 53349 53350 53351 /** 53352 * Internal dependencies 53353 */ 53354 53355 53356 53357 53358 // The implementation of content locking is mainly in this file, although the mechanism 53359 // to stop temporarily editing as blocks when an outside block is selected is on component StopEditingAsBlocksOnOutsideSelect 53360 // at block-editor/src/components/block-list/index.js. 53361 // Besides the components on this file and the file referenced above the implementation 53362 // also includes artifacts on the store (actions, reducers, and selector). 53363 53364 function ContentLockControlsPure({ 53365 clientId 53366 }) { 53367 const { 53368 templateLock, 53369 isLockedByParent, 53370 isEditingAsBlocks 53371 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 53372 const { 53373 getContentLockingParent, 53374 getTemplateLock, 53375 getTemporarilyEditingAsBlocks 53376 } = unlock(select(store)); 53377 return { 53378 templateLock: getTemplateLock(clientId), 53379 isLockedByParent: !!getContentLockingParent(clientId), 53380 isEditingAsBlocks: getTemporarilyEditingAsBlocks() === clientId 53381 }; 53382 }, [clientId]); 53383 const { 53384 stopEditingAsBlocks 53385 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 53386 const isContentLocked = !isLockedByParent && templateLock === 'contentOnly'; 53387 const stopEditingAsBlockCallback = (0,external_wp_element_namespaceObject.useCallback)(() => { 53388 stopEditingAsBlocks(clientId); 53389 }, [clientId, stopEditingAsBlocks]); 53390 if (!isContentLocked && !isEditingAsBlocks) { 53391 return null; 53392 } 53393 const showStopEditingAsBlocks = isEditingAsBlocks && !isContentLocked; 53394 return showStopEditingAsBlocks && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 53395 group: "other", 53396 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 53397 onClick: stopEditingAsBlockCallback, 53398 children: (0,external_wp_i18n_namespaceObject.__)('Done') 53399 }) 53400 }); 53401 } 53402 /* harmony default export */ const content_lock_ui = ({ 53403 edit: ContentLockControlsPure, 53404 hasSupport() { 53405 return true; 53406 } 53407 }); 53408 53409 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/metadata.js 53410 /** 53411 * WordPress dependencies 53412 */ 53413 53414 const META_ATTRIBUTE_NAME = 'metadata'; 53415 53416 /** 53417 * Filters registered block settings, extending attributes to include `metadata`. 53418 * 53419 * see: https://github.com/WordPress/gutenberg/pull/40393/files#r864632012 53420 * 53421 * @param {Object} blockTypeSettings Original block settings. 53422 * @return {Object} Filtered block settings. 53423 */ 53424 function addMetaAttribute(blockTypeSettings) { 53425 // Allow blocks to specify their own attribute definition with default values if needed. 53426 if (blockTypeSettings?.attributes?.[META_ATTRIBUTE_NAME]?.type) { 53427 return blockTypeSettings; 53428 } 53429 blockTypeSettings.attributes = { 53430 ...blockTypeSettings.attributes, 53431 [META_ATTRIBUTE_NAME]: { 53432 type: 'object' 53433 } 53434 }; 53435 return blockTypeSettings; 53436 } 53437 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/metadata/addMetaAttribute', addMetaAttribute); 53438 53439 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/block-hooks.js 53440 /** 53441 * WordPress dependencies 53442 */ 53443 53444 53445 53446 53447 53448 53449 /** 53450 * Internal dependencies 53451 */ 53452 53453 53454 53455 const block_hooks_EMPTY_OBJECT = {}; 53456 function BlockHooksControlPure({ 53457 name, 53458 clientId, 53459 metadata: { 53460 ignoredHookedBlocks = [] 53461 } = {} 53462 }) { 53463 const blockTypes = (0,external_wp_data_namespaceObject.useSelect)(select => select(external_wp_blocks_namespaceObject.store).getBlockTypes(), []); 53464 53465 // A hooked block added via a filter will not be exposed through a block 53466 // type's `blockHooks` property; however, if the containing layout has been 53467 // modified, it will be present in the anchor block's `ignoredHookedBlocks` 53468 // metadata. 53469 const hookedBlocksForCurrentBlock = (0,external_wp_element_namespaceObject.useMemo)(() => blockTypes?.filter(({ 53470 name: blockName, 53471 blockHooks 53472 }) => blockHooks && name in blockHooks || ignoredHookedBlocks.includes(blockName)), [blockTypes, name, ignoredHookedBlocks]); 53473 const hookedBlockClientIds = (0,external_wp_data_namespaceObject.useSelect)(select => { 53474 const { 53475 getBlocks, 53476 getBlockRootClientId, 53477 getGlobalBlockCount 53478 } = select(store); 53479 const rootClientId = getBlockRootClientId(clientId); 53480 const _hookedBlockClientIds = hookedBlocksForCurrentBlock.reduce((clientIds, block) => { 53481 // If the block doesn't exist anywhere in the block tree, 53482 // we know that we have to set the toggle to disabled. 53483 if (getGlobalBlockCount(block.name) === 0) { 53484 return clientIds; 53485 } 53486 const relativePosition = block?.blockHooks?.[name]; 53487 let candidates; 53488 switch (relativePosition) { 53489 case 'before': 53490 case 'after': 53491 // Any of the current block's siblings (with the right block type) qualifies 53492 // as a hooked block (inserted `before` or `after` the current one), as the block 53493 // might've been automatically inserted and then moved around a bit by the user. 53494 candidates = getBlocks(rootClientId); 53495 break; 53496 case 'first_child': 53497 case 'last_child': 53498 // Any of the current block's child blocks (with the right block type) qualifies 53499 // as a hooked first or last child block, as the block might've been automatically 53500 // inserted and then moved around a bit by the user. 53501 candidates = getBlocks(clientId); 53502 break; 53503 case undefined: 53504 // If we haven't found a blockHooks field with a relative position for the hooked 53505 // block, it means that it was added by a filter. In this case, we look for the block 53506 // both among the current block's siblings and its children. 53507 candidates = [...getBlocks(rootClientId), ...getBlocks(clientId)]; 53508 break; 53509 } 53510 const hookedBlock = candidates?.find(candidate => candidate.name === block.name); 53511 53512 // If the block exists in the designated location, we consider it hooked 53513 // and show the toggle as enabled. 53514 if (hookedBlock) { 53515 return { 53516 ...clientIds, 53517 [block.name]: hookedBlock.clientId 53518 }; 53519 } 53520 53521 // If no hooked block was found in any of its designated locations, 53522 // we set the toggle to disabled. 53523 return clientIds; 53524 }, {}); 53525 if (Object.values(_hookedBlockClientIds).length > 0) { 53526 return _hookedBlockClientIds; 53527 } 53528 return block_hooks_EMPTY_OBJECT; 53529 }, [hookedBlocksForCurrentBlock, name, clientId]); 53530 const { 53531 getBlockIndex, 53532 getBlockCount, 53533 getBlockRootClientId 53534 } = (0,external_wp_data_namespaceObject.useSelect)(store); 53535 const { 53536 insertBlock, 53537 removeBlock 53538 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 53539 if (!hookedBlocksForCurrentBlock.length) { 53540 return null; 53541 } 53542 53543 // Group by block namespace (i.e. prefix before the slash). 53544 const groupedHookedBlocks = hookedBlocksForCurrentBlock.reduce((groups, block) => { 53545 const [namespace] = block.name.split('/'); 53546 if (!groups[namespace]) { 53547 groups[namespace] = []; 53548 } 53549 groups[namespace].push(block); 53550 return groups; 53551 }, {}); 53552 const insertBlockIntoDesignatedLocation = (block, relativePosition) => { 53553 const blockIndex = getBlockIndex(clientId); 53554 const innerBlocksLength = getBlockCount(clientId); 53555 const rootClientId = getBlockRootClientId(clientId); 53556 switch (relativePosition) { 53557 case 'before': 53558 case 'after': 53559 insertBlock(block, relativePosition === 'after' ? blockIndex + 1 : blockIndex, rootClientId, 53560 // Insert as a child of the current block's parent 53561 false); 53562 break; 53563 case 'first_child': 53564 case 'last_child': 53565 insertBlock(block, 53566 // TODO: It'd be great if insertBlock() would accept negative indices for insertion. 53567 relativePosition === 'first_child' ? 0 : innerBlocksLength, clientId, 53568 // Insert as a child of the current block. 53569 false); 53570 break; 53571 case undefined: 53572 // If we do not know the relative position, it is because the block was 53573 // added via a filter. In this case, we default to inserting it after the 53574 // current block. 53575 insertBlock(block, blockIndex + 1, rootClientId, 53576 // Insert as a child of the current block's parent 53577 false); 53578 break; 53579 } 53580 }; 53581 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 53582 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.PanelBody, { 53583 className: "block-editor-hooks__block-hooks", 53584 title: (0,external_wp_i18n_namespaceObject.__)('Plugins'), 53585 initialOpen: true, 53586 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 53587 className: "block-editor-hooks__block-hooks-helptext", 53588 children: (0,external_wp_i18n_namespaceObject.__)('Manage the inclusion of blocks added automatically by plugins.') 53589 }), Object.keys(groupedHookedBlocks).map(vendor => { 53590 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_element_namespaceObject.Fragment, { 53591 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("h3", { 53592 children: vendor 53593 }), groupedHookedBlocks[vendor].map(block => { 53594 const checked = block.name in hookedBlockClientIds; 53595 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 53596 __nextHasNoMarginBottom: true, 53597 checked: checked, 53598 label: block.title, 53599 onChange: () => { 53600 if (!checked) { 53601 // Create and insert block. 53602 const relativePosition = block.blockHooks[name]; 53603 insertBlockIntoDesignatedLocation((0,external_wp_blocks_namespaceObject.createBlock)(block.name), relativePosition); 53604 return; 53605 } 53606 53607 // Remove block. 53608 removeBlock(hookedBlockClientIds[block.name], false); 53609 } 53610 }, block.title); 53611 })] 53612 }, vendor); 53613 })] 53614 }) 53615 }); 53616 } 53617 /* harmony default export */ const block_hooks = ({ 53618 edit: BlockHooksControlPure, 53619 attributeKeys: ['metadata'], 53620 hasSupport() { 53621 return true; 53622 } 53623 }); 53624 53625 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/block-bindings.js 53626 /** 53627 * WordPress dependencies 53628 */ 53629 53630 53631 53632 53633 53634 53635 53636 /** 53637 * Internal dependencies 53638 */ 53639 53640 53641 53642 53643 53644 53645 53646 const { 53647 Menu 53648 } = unlock(external_wp_components_namespaceObject.privateApis); 53649 const block_bindings_EMPTY_OBJECT = {}; 53650 const block_bindings_useToolsPanelDropdownMenuProps = () => { 53651 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 53652 return !isMobile ? { 53653 popoverProps: { 53654 placement: 'left-start', 53655 // For non-mobile, inner sidebar width (248px) - button width (24px) - border (1px) + padding (16px) + spacing (20px) 53656 offset: 259 53657 } 53658 } : {}; 53659 }; 53660 function BlockBindingsPanelMenuContent({ 53661 fieldsList, 53662 attribute, 53663 binding 53664 }) { 53665 const { 53666 clientId 53667 } = useBlockEditContext(); 53668 const registeredSources = (0,external_wp_blocks_namespaceObject.getBlockBindingsSources)(); 53669 const { 53670 updateBlockBindings 53671 } = useBlockBindingsUtils(); 53672 const currentKey = binding?.args?.key; 53673 const attributeType = (0,external_wp_data_namespaceObject.useSelect)(select => { 53674 const { 53675 name: blockName 53676 } = select(store).getBlock(clientId); 53677 const _attributeType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName).attributes?.[attribute]?.type; 53678 return _attributeType === 'rich-text' ? 'string' : _attributeType; 53679 }, [clientId, attribute]); 53680 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 53681 children: Object.entries(fieldsList).map(([name, fields], i) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_element_namespaceObject.Fragment, { 53682 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Menu.Group, { 53683 children: [Object.keys(fieldsList).length > 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Menu.GroupLabel, { 53684 children: registeredSources[name].label 53685 }), Object.entries(fields).filter(([, args]) => args?.type === attributeType).map(([key, args]) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Menu.RadioItem, { 53686 onChange: () => updateBlockBindings({ 53687 [attribute]: { 53688 source: name, 53689 args: { 53690 key 53691 } 53692 } 53693 }), 53694 name: attribute + '-binding', 53695 value: key, 53696 checked: key === currentKey, 53697 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Menu.ItemLabel, { 53698 children: args?.label 53699 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Menu.ItemHelpText, { 53700 children: args?.value 53701 })] 53702 }, key))] 53703 }), i !== Object.keys(fieldsList).length - 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Menu.Separator, {})] 53704 }, name)) 53705 }); 53706 } 53707 function BlockBindingsAttribute({ 53708 attribute, 53709 binding, 53710 fieldsList 53711 }) { 53712 const { 53713 source: sourceName, 53714 args 53715 } = binding || {}; 53716 const sourceProps = (0,external_wp_blocks_namespaceObject.getBlockBindingsSource)(sourceName); 53717 const isSourceInvalid = !sourceProps; 53718 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 53719 className: "block-editor-bindings__item", 53720 spacing: 0, 53721 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 53722 truncate: true, 53723 children: attribute 53724 }), !!binding && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 53725 truncate: true, 53726 variant: !isSourceInvalid && 'muted', 53727 isDestructive: isSourceInvalid, 53728 children: isSourceInvalid ? (0,external_wp_i18n_namespaceObject.__)('Invalid source') : fieldsList?.[sourceName]?.[args?.key]?.label || sourceProps?.label || sourceName 53729 })] 53730 }); 53731 } 53732 function ReadOnlyBlockBindingsPanelItems({ 53733 bindings, 53734 fieldsList 53735 }) { 53736 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 53737 children: Object.entries(bindings).map(([attribute, binding]) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalItem, { 53738 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockBindingsAttribute, { 53739 attribute: attribute, 53740 binding: binding, 53741 fieldsList: fieldsList 53742 }) 53743 }, attribute)) 53744 }); 53745 } 53746 function EditableBlockBindingsPanelItems({ 53747 attributes, 53748 bindings, 53749 fieldsList 53750 }) { 53751 const { 53752 updateBlockBindings 53753 } = useBlockBindingsUtils(); 53754 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 53755 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 53756 children: attributes.map(attribute => { 53757 const binding = bindings[attribute]; 53758 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 53759 hasValue: () => !!binding, 53760 label: attribute, 53761 onDeselect: () => { 53762 updateBlockBindings({ 53763 [attribute]: undefined 53764 }); 53765 }, 53766 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(Menu, { 53767 placement: isMobile ? 'bottom-start' : 'left-start', 53768 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Menu.TriggerButton, { 53769 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalItem, {}), 53770 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockBindingsAttribute, { 53771 attribute: attribute, 53772 binding: binding, 53773 fieldsList: fieldsList 53774 }) 53775 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Menu.Popover, { 53776 gutter: isMobile ? 8 : 36, 53777 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockBindingsPanelMenuContent, { 53778 fieldsList: fieldsList, 53779 attribute: attribute, 53780 binding: binding 53781 }) 53782 })] 53783 }) 53784 }, attribute); 53785 }) 53786 }); 53787 } 53788 const BlockBindingsPanel = ({ 53789 name: blockName, 53790 metadata 53791 }) => { 53792 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 53793 const { 53794 removeAllBlockBindings 53795 } = useBlockBindingsUtils(); 53796 const bindableAttributes = getBindableAttributes(blockName); 53797 const dropdownMenuProps = block_bindings_useToolsPanelDropdownMenuProps(); 53798 53799 // `useSelect` is used purposely here to ensure `getFieldsList` 53800 // is updated whenever there are updates in block context. 53801 // `source.getFieldsList` may also call a selector via `select`. 53802 const _fieldsList = {}; 53803 const { 53804 fieldsList, 53805 canUpdateBlockBindings 53806 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 53807 if (!bindableAttributes || bindableAttributes.length === 0) { 53808 return block_bindings_EMPTY_OBJECT; 53809 } 53810 const registeredSources = (0,external_wp_blocks_namespaceObject.getBlockBindingsSources)(); 53811 Object.entries(registeredSources).forEach(([sourceName, { 53812 getFieldsList, 53813 usesContext 53814 }]) => { 53815 if (getFieldsList) { 53816 // Populate context. 53817 const context = {}; 53818 if (usesContext?.length) { 53819 for (const key of usesContext) { 53820 context[key] = blockContext[key]; 53821 } 53822 } 53823 const sourceList = getFieldsList({ 53824 select, 53825 context 53826 }); 53827 // Only add source if the list is not empty. 53828 if (Object.keys(sourceList || {}).length) { 53829 _fieldsList[sourceName] = { 53830 ...sourceList 53831 }; 53832 } 53833 } 53834 }); 53835 return { 53836 fieldsList: Object.values(_fieldsList).length > 0 ? _fieldsList : block_bindings_EMPTY_OBJECT, 53837 canUpdateBlockBindings: select(store).getSettings().canUpdateBlockBindings 53838 }; 53839 }, [blockContext, bindableAttributes]); 53840 // Return early if there are no bindable attributes. 53841 if (!bindableAttributes || bindableAttributes.length === 0) { 53842 return null; 53843 } 53844 // Filter bindings to only show bindable attributes and remove pattern overrides. 53845 const { 53846 bindings 53847 } = metadata || {}; 53848 const filteredBindings = { 53849 ...bindings 53850 }; 53851 Object.keys(filteredBindings).forEach(key => { 53852 if (!canBindAttribute(blockName, key) || filteredBindings[key].source === 'core/pattern-overrides') { 53853 delete filteredBindings[key]; 53854 } 53855 }); 53856 53857 // Lock the UI when the user can't update bindings or there are no fields to connect to. 53858 const readOnly = !canUpdateBlockBindings || !Object.keys(fieldsList).length; 53859 if (readOnly && Object.keys(filteredBindings).length === 0) { 53860 return null; 53861 } 53862 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls, { 53863 group: "bindings", 53864 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 53865 label: (0,external_wp_i18n_namespaceObject.__)('Attributes'), 53866 resetAll: () => { 53867 removeAllBlockBindings(); 53868 }, 53869 dropdownMenuProps: dropdownMenuProps, 53870 className: "block-editor-bindings__panel", 53871 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalItemGroup, { 53872 isBordered: true, 53873 isSeparated: true, 53874 children: readOnly ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ReadOnlyBlockBindingsPanelItems, { 53875 bindings: filteredBindings, 53876 fieldsList: fieldsList 53877 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EditableBlockBindingsPanelItems, { 53878 attributes: bindableAttributes, 53879 bindings: filteredBindings, 53880 fieldsList: fieldsList 53881 }) 53882 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 53883 as: "div", 53884 variant: "muted", 53885 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 53886 children: (0,external_wp_i18n_namespaceObject.__)('Attributes connected to custom fields or other dynamic data.') 53887 }) 53888 })] 53889 }) 53890 }); 53891 }; 53892 /* harmony default export */ const block_bindings = ({ 53893 edit: BlockBindingsPanel, 53894 attributeKeys: ['metadata'], 53895 hasSupport() { 53896 return true; 53897 } 53898 }); 53899 53900 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/block-renaming.js 53901 /** 53902 * WordPress dependencies 53903 */ 53904 53905 53906 53907 /** 53908 * Filters registered block settings, adding an `__experimentalLabel` callback if one does not already exist. 53909 * 53910 * @param {Object} settings Original block settings. 53911 * 53912 * @return {Object} Filtered block settings. 53913 */ 53914 function addLabelCallback(settings) { 53915 // If blocks provide their own label callback, do not override it. 53916 if (settings.__experimentalLabel) { 53917 return settings; 53918 } 53919 const supportsBlockNaming = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'renaming', true // default value 53920 ); 53921 53922 // Check whether block metadata is supported before using it. 53923 if (supportsBlockNaming) { 53924 settings.__experimentalLabel = (attributes, { 53925 context 53926 }) => { 53927 const { 53928 metadata 53929 } = attributes; 53930 53931 // In the list view, use the block's name attribute as the label. 53932 if (context === 'list-view' && metadata?.name) { 53933 return metadata.name; 53934 } 53935 }; 53936 } 53937 return settings; 53938 } 53939 (0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/metadata/addLabelCallback', addLabelCallback); 53940 53941 ;// ./node_modules/@wordpress/block-editor/build-module/components/grid/use-grid-layout-sync.js 53942 /** 53943 * WordPress dependencies 53944 */ 53945 53946 53947 53948 53949 /** 53950 * Internal dependencies 53951 */ 53952 53953 53954 53955 function useGridLayoutSync({ 53956 clientId: gridClientId 53957 }) { 53958 const { 53959 gridLayout, 53960 blockOrder, 53961 selectedBlockLayout 53962 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 53963 var _getBlockAttributes$l; 53964 const { 53965 getBlockAttributes, 53966 getBlockOrder 53967 } = select(store); 53968 const selectedBlock = select(store).getSelectedBlock(); 53969 return { 53970 gridLayout: (_getBlockAttributes$l = getBlockAttributes(gridClientId).layout) !== null && _getBlockAttributes$l !== void 0 ? _getBlockAttributes$l : {}, 53971 blockOrder: getBlockOrder(gridClientId), 53972 selectedBlockLayout: selectedBlock?.attributes.style?.layout 53973 }; 53974 }, [gridClientId]); 53975 const { 53976 getBlockAttributes, 53977 getBlockRootClientId 53978 } = (0,external_wp_data_namespaceObject.useSelect)(store); 53979 const { 53980 updateBlockAttributes, 53981 __unstableMarkNextChangeAsNotPersistent 53982 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 53983 const selectedBlockRect = (0,external_wp_element_namespaceObject.useMemo)(() => selectedBlockLayout ? new GridRect(selectedBlockLayout) : null, [selectedBlockLayout]); 53984 const previouslySelectedBlockRect = (0,external_wp_compose_namespaceObject.usePrevious)(selectedBlockRect); 53985 const previousIsManualPlacement = (0,external_wp_compose_namespaceObject.usePrevious)(gridLayout.isManualPlacement); 53986 const previousBlockOrder = (0,external_wp_compose_namespaceObject.usePrevious)(blockOrder); 53987 (0,external_wp_element_namespaceObject.useEffect)(() => { 53988 const updates = {}; 53989 if (gridLayout.isManualPlacement) { 53990 const occupiedRects = []; 53991 53992 // Respect the position of blocks that already have a columnStart and rowStart value. 53993 for (const clientId of blockOrder) { 53994 var _getBlockAttributes$s; 53995 const { 53996 columnStart, 53997 rowStart, 53998 columnSpan = 1, 53999 rowSpan = 1 54000 } = (_getBlockAttributes$s = getBlockAttributes(clientId).style?.layout) !== null && _getBlockAttributes$s !== void 0 ? _getBlockAttributes$s : {}; 54001 if (!columnStart || !rowStart) { 54002 continue; 54003 } 54004 occupiedRects.push(new GridRect({ 54005 columnStart, 54006 rowStart, 54007 columnSpan, 54008 rowSpan 54009 })); 54010 } 54011 54012 // When in manual mode, ensure that every block has a columnStart and rowStart value. 54013 for (const clientId of blockOrder) { 54014 var _attributes$style$lay; 54015 const attributes = getBlockAttributes(clientId); 54016 const { 54017 columnStart, 54018 rowStart, 54019 columnSpan = 1, 54020 rowSpan = 1 54021 } = (_attributes$style$lay = attributes.style?.layout) !== null && _attributes$style$lay !== void 0 ? _attributes$style$lay : {}; 54022 if (columnStart && rowStart) { 54023 continue; 54024 } 54025 const [newColumnStart, newRowStart] = placeBlock(occupiedRects, gridLayout.columnCount, columnSpan, rowSpan, previouslySelectedBlockRect?.columnEnd, previouslySelectedBlockRect?.rowEnd); 54026 occupiedRects.push(new GridRect({ 54027 columnStart: newColumnStart, 54028 rowStart: newRowStart, 54029 columnSpan, 54030 rowSpan 54031 })); 54032 updates[clientId] = { 54033 style: { 54034 ...attributes.style, 54035 layout: { 54036 ...attributes.style?.layout, 54037 columnStart: newColumnStart, 54038 rowStart: newRowStart 54039 } 54040 } 54041 }; 54042 } 54043 54044 // Ensure there's enough rows to fit all blocks. 54045 const bottomMostRow = Math.max(...occupiedRects.map(r => r.rowEnd)); 54046 if (!gridLayout.rowCount || gridLayout.rowCount < bottomMostRow) { 54047 updates[gridClientId] = { 54048 layout: { 54049 ...gridLayout, 54050 rowCount: bottomMostRow 54051 } 54052 }; 54053 } 54054 54055 // Unset grid layout attributes for blocks removed from the grid. 54056 for (const clientId of previousBlockOrder !== null && previousBlockOrder !== void 0 ? previousBlockOrder : []) { 54057 if (!blockOrder.includes(clientId)) { 54058 var _attributes$style$lay2; 54059 const rootClientId = getBlockRootClientId(clientId); 54060 54061 // Block was removed from the editor, so nothing to do. 54062 if (rootClientId === null) { 54063 continue; 54064 } 54065 54066 // Check if the block is being moved to another grid. 54067 // If so, do nothing and let the new grid parent handle 54068 // the attributes. 54069 const rootAttributes = getBlockAttributes(rootClientId); 54070 if (rootAttributes?.layout?.type === 'grid') { 54071 continue; 54072 } 54073 const attributes = getBlockAttributes(clientId); 54074 const { 54075 columnStart, 54076 rowStart, 54077 columnSpan, 54078 rowSpan, 54079 ...layout 54080 } = (_attributes$style$lay2 = attributes.style?.layout) !== null && _attributes$style$lay2 !== void 0 ? _attributes$style$lay2 : {}; 54081 if (columnStart || rowStart || columnSpan || rowSpan) { 54082 const hasEmptyLayoutAttribute = Object.keys(layout).length === 0; 54083 updates[clientId] = setImmutably(attributes, ['style', 'layout'], hasEmptyLayoutAttribute ? undefined : layout); 54084 } 54085 } 54086 } 54087 } else { 54088 // Remove all of the columnStart and rowStart values 54089 // when switching from manual to auto mode, 54090 if (previousIsManualPlacement === true) { 54091 for (const clientId of blockOrder) { 54092 var _attributes$style$lay3; 54093 const attributes = getBlockAttributes(clientId); 54094 const { 54095 columnStart, 54096 rowStart, 54097 ...layout 54098 } = (_attributes$style$lay3 = attributes.style?.layout) !== null && _attributes$style$lay3 !== void 0 ? _attributes$style$lay3 : {}; 54099 // Only update attributes if columnStart or rowStart are set. 54100 if (columnStart || rowStart) { 54101 const hasEmptyLayoutAttribute = Object.keys(layout).length === 0; 54102 updates[clientId] = setImmutably(attributes, ['style', 'layout'], hasEmptyLayoutAttribute ? undefined : layout); 54103 } 54104 } 54105 } 54106 54107 // Remove row styles in auto mode 54108 if (gridLayout.rowCount) { 54109 updates[gridClientId] = { 54110 layout: { 54111 ...gridLayout, 54112 rowCount: undefined 54113 } 54114 }; 54115 } 54116 } 54117 if (Object.keys(updates).length) { 54118 __unstableMarkNextChangeAsNotPersistent(); 54119 updateBlockAttributes(Object.keys(updates), updates, /* uniqueByBlock: */true); 54120 } 54121 }, [ 54122 // Actual deps to sync: 54123 gridClientId, gridLayout, previousBlockOrder, blockOrder, previouslySelectedBlockRect, previousIsManualPlacement, 54124 // These won't change, but the linter thinks they might: 54125 __unstableMarkNextChangeAsNotPersistent, getBlockAttributes, getBlockRootClientId, updateBlockAttributes]); 54126 } 54127 54128 /** 54129 * @param {GridRect[]} occupiedRects 54130 * @param {number} gridColumnCount 54131 * @param {number} blockColumnSpan 54132 * @param {number} blockRowSpan 54133 * @param {number?} startColumn 54134 * @param {number?} startRow 54135 */ 54136 function placeBlock(occupiedRects, gridColumnCount, blockColumnSpan, blockRowSpan, startColumn = 1, startRow = 1) { 54137 for (let row = startRow;; row++) { 54138 for (let column = row === startRow ? startColumn : 1; column <= gridColumnCount; column++) { 54139 const candidateRect = new GridRect({ 54140 columnStart: column, 54141 rowStart: row, 54142 columnSpan: blockColumnSpan, 54143 rowSpan: blockRowSpan 54144 }); 54145 if (!occupiedRects.some(r => r.intersectsRect(candidateRect))) { 54146 return [column, row]; 54147 } 54148 } 54149 } 54150 } 54151 54152 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/grid-visualizer.js 54153 /** 54154 * WordPress dependencies 54155 */ 54156 54157 54158 54159 54160 /** 54161 * Internal dependencies 54162 */ 54163 54164 54165 54166 function GridLayoutSync(props) { 54167 useGridLayoutSync(props); 54168 } 54169 function grid_visualizer_GridTools({ 54170 clientId, 54171 layout 54172 }) { 54173 const isVisible = (0,external_wp_data_namespaceObject.useSelect)(select => { 54174 const { 54175 isBlockSelected, 54176 isDraggingBlocks, 54177 getTemplateLock, 54178 getBlockEditingMode 54179 } = select(store); 54180 54181 // These calls are purposely ordered from least expensive to most expensive. 54182 // Hides the visualizer in cases where the user is not or cannot interact with it. 54183 if (!isDraggingBlocks() && !isBlockSelected(clientId) || getTemplateLock(clientId) || getBlockEditingMode(clientId) !== 'default') { 54184 return false; 54185 } 54186 return true; 54187 }, [clientId]); 54188 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 54189 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridLayoutSync, { 54190 clientId: clientId 54191 }), isVisible && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(GridVisualizer, { 54192 clientId: clientId, 54193 parentLayout: layout 54194 })] 54195 }); 54196 } 54197 const addGridVisualizerToBlockEdit = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockEdit => props => { 54198 if (props.attributes.layout?.type !== 'grid') { 54199 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockEdit, { 54200 ...props 54201 }, "edit"); 54202 } 54203 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 54204 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(grid_visualizer_GridTools, { 54205 clientId: props.clientId, 54206 layout: props.attributes.layout 54207 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockEdit, { 54208 ...props 54209 }, "edit")] 54210 }); 54211 }, 'addGridVisualizerToBlockEdit'); 54212 (0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockEdit', 'core/editor/grid-visualizer', addGridVisualizerToBlockEdit); 54213 54214 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-border-props.js 54215 /** 54216 * Internal dependencies 54217 */ 54218 54219 54220 54221 54222 // This utility is intended to assist where the serialization of the border 54223 // block support is being skipped for a block but the border related CSS classes 54224 // & styles still need to be generated so they can be applied to inner elements. 54225 54226 /** 54227 * Provides the CSS class names and inline styles for a block's border support 54228 * attributes. 54229 * 54230 * @param {Object} attributes Block attributes. 54231 * @return {Object} Border block support derived CSS classes & styles. 54232 */ 54233 function getBorderClassesAndStyles(attributes) { 54234 const border = attributes.style?.border || {}; 54235 const className = getBorderClasses(attributes); 54236 return { 54237 className: className || undefined, 54238 style: getInlineStyles({ 54239 border 54240 }) 54241 }; 54242 } 54243 54244 /** 54245 * Derives the border related props for a block from its border block support 54246 * attributes. 54247 * 54248 * Inline styles are forced for named colors to ensure these selections are 54249 * reflected when themes do not load their color stylesheets in the editor. 54250 * 54251 * @param {Object} attributes Block attributes. 54252 * 54253 * @return {Object} ClassName & style props from border block support. 54254 */ 54255 function useBorderProps(attributes) { 54256 const { 54257 colors 54258 } = useMultipleOriginColorsAndGradients(); 54259 const borderProps = getBorderClassesAndStyles(attributes); 54260 const { 54261 borderColor 54262 } = attributes; 54263 54264 // Force inline styles to apply named border colors when themes do not load 54265 // their color stylesheets in the editor. 54266 if (borderColor) { 54267 const borderColorObject = getMultiOriginColor({ 54268 colors, 54269 namedColor: borderColor 54270 }); 54271 borderProps.style.borderColor = borderColorObject.color; 54272 } 54273 return borderProps; 54274 } 54275 54276 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-shadow-props.js 54277 /** 54278 * Internal dependencies 54279 */ 54280 54281 54282 // This utility is intended to assist where the serialization of the shadow 54283 // block support is being skipped for a block but the shadow related CSS classes 54284 // & styles still need to be generated so they can be applied to inner elements. 54285 54286 /** 54287 * Provides the CSS class names and inline styles for a block's shadow support 54288 * attributes. 54289 * 54290 * @param {Object} attributes Block attributes. 54291 * @return {Object} Shadow block support derived CSS classes & styles. 54292 */ 54293 function getShadowClassesAndStyles(attributes) { 54294 const shadow = attributes.style?.shadow || ''; 54295 return { 54296 style: getInlineStyles({ 54297 shadow 54298 }) 54299 }; 54300 } 54301 54302 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-color-props.js 54303 /** 54304 * External dependencies 54305 */ 54306 54307 54308 /** 54309 * WordPress dependencies 54310 */ 54311 54312 54313 /** 54314 * Internal dependencies 54315 */ 54316 54317 54318 54319 54320 54321 // The code in this file has largely been lifted from the color block support 54322 // hook. 54323 // 54324 // This utility is intended to assist where the serialization of the colors 54325 // block support is being skipped for a block but the color related CSS classes 54326 // & styles still need to be generated so they can be applied to inner elements. 54327 54328 /** 54329 * Provides the CSS class names and inline styles for a block's color support 54330 * attributes. 54331 * 54332 * @param {Object} attributes Block attributes. 54333 * 54334 * @return {Object} Color block support derived CSS classes & styles. 54335 */ 54336 function getColorClassesAndStyles(attributes) { 54337 const { 54338 backgroundColor, 54339 textColor, 54340 gradient, 54341 style 54342 } = attributes; 54343 54344 // Collect color CSS classes. 54345 const backgroundClass = getColorClassName('background-color', backgroundColor); 54346 const textClass = getColorClassName('color', textColor); 54347 const gradientClass = __experimentalGetGradientClass(gradient); 54348 const hasGradient = gradientClass || style?.color?.gradient; 54349 54350 // Determine color CSS class name list. 54351 const className = dist_clsx(textClass, gradientClass, { 54352 // Don't apply the background class if there's a gradient. 54353 [backgroundClass]: !hasGradient && !!backgroundClass, 54354 'has-text-color': textColor || style?.color?.text, 54355 'has-background': backgroundColor || style?.color?.background || gradient || style?.color?.gradient, 54356 'has-link-color': style?.elements?.link?.color 54357 }); 54358 54359 // Collect inline styles for colors. 54360 const colorStyles = style?.color || {}; 54361 const styleProp = getInlineStyles({ 54362 color: colorStyles 54363 }); 54364 return { 54365 className: className || undefined, 54366 style: styleProp 54367 }; 54368 } 54369 54370 /** 54371 * Determines the color related props for a block derived from its color block 54372 * support attributes. 54373 * 54374 * Inline styles are forced for named colors to ensure these selections are 54375 * reflected when themes do not load their color stylesheets in the editor. 54376 * 54377 * @param {Object} attributes Block attributes. 54378 * 54379 * @return {Object} ClassName & style props from colors block support. 54380 */ 54381 function useColorProps(attributes) { 54382 const { 54383 backgroundColor, 54384 textColor, 54385 gradient 54386 } = attributes; 54387 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'); 54388 const colors = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); 54389 const gradients = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userGradients || []), ...(themeGradients || []), ...(defaultGradients || [])], [userGradients, themeGradients, defaultGradients]); 54390 const colorProps = getColorClassesAndStyles(attributes); 54391 54392 // Force inline styles to apply colors when themes do not load their color 54393 // stylesheets in the editor. 54394 if (backgroundColor) { 54395 const backgroundColorObject = getColorObjectByAttributeValues(colors, backgroundColor); 54396 colorProps.style.backgroundColor = backgroundColorObject.color; 54397 } 54398 if (gradient) { 54399 colorProps.style.background = getGradientValueBySlug(gradients, gradient); 54400 } 54401 if (textColor) { 54402 const textColorObject = getColorObjectByAttributeValues(colors, textColor); 54403 colorProps.style.color = textColorObject.color; 54404 } 54405 return colorProps; 54406 } 54407 54408 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-spacing-props.js 54409 /** 54410 * Internal dependencies 54411 */ 54412 54413 54414 // This utility is intended to assist where the serialization of the spacing 54415 // block support is being skipped for a block but the spacing related CSS 54416 // styles still need to be generated so they can be applied to inner elements. 54417 54418 /** 54419 * Provides the CSS class names and inline styles for a block's spacing support 54420 * attributes. 54421 * 54422 * @param {Object} attributes Block attributes. 54423 * 54424 * @return {Object} Spacing block support derived CSS classes & styles. 54425 */ 54426 function getSpacingClassesAndStyles(attributes) { 54427 const { 54428 style 54429 } = attributes; 54430 54431 // Collect inline styles for spacing. 54432 const spacingStyles = style?.spacing || {}; 54433 const styleProp = getInlineStyles({ 54434 spacing: spacingStyles 54435 }); 54436 return { 54437 style: styleProp 54438 }; 54439 } 54440 54441 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-typography-props.js 54442 /** 54443 * External dependencies 54444 */ 54445 54446 54447 /** 54448 * WordPress dependencies 54449 */ 54450 54451 54452 /** 54453 * Internal dependencies 54454 */ 54455 54456 54457 54458 54459 const { 54460 kebabCase: use_typography_props_kebabCase 54461 } = unlock(external_wp_components_namespaceObject.privateApis); 54462 54463 /* 54464 * This utility is intended to assist where the serialization of the typography 54465 * block support is being skipped for a block but the typography related CSS 54466 * styles still need to be generated so they can be applied to inner elements. 54467 */ 54468 /** 54469 * Provides the CSS class names and inline styles for a block's typography support 54470 * attributes. 54471 * 54472 * @param {Object} attributes Block attributes. 54473 * @param {Object|boolean} settings Merged theme.json settings 54474 * 54475 * @return {Object} Typography block support derived CSS classes & styles. 54476 */ 54477 function getTypographyClassesAndStyles(attributes, settings) { 54478 let typographyStyles = attributes?.style?.typography || {}; 54479 typographyStyles = { 54480 ...typographyStyles, 54481 fontSize: getTypographyFontSizeValue({ 54482 size: attributes?.style?.typography?.fontSize 54483 }, settings) 54484 }; 54485 const style = getInlineStyles({ 54486 typography: typographyStyles 54487 }); 54488 const fontFamilyClassName = !!attributes?.fontFamily ? `has-$use_typography_props_kebabCase(attributes.fontFamily)}-font-family` : ''; 54489 const textAlignClassName = !!attributes?.style?.typography?.textAlign ? `has-text-align-$attributes?.style?.typography?.textAlign}` : ''; 54490 const className = dist_clsx(fontFamilyClassName, textAlignClassName, getFontSizeClass(attributes?.fontSize)); 54491 return { 54492 className, 54493 style 54494 }; 54495 } 54496 54497 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/use-cached-truthy.js 54498 /** 54499 * WordPress dependencies 54500 */ 54501 54502 54503 /** 54504 * Keeps an up-to-date copy of the passed value and returns it. If value becomes falsy, it will return the last truthy copy. 54505 * 54506 * @param {any} value 54507 * @return {any} value 54508 */ 54509 function useCachedTruthy(value) { 54510 const [cachedValue, setCachedValue] = (0,external_wp_element_namespaceObject.useState)(value); 54511 (0,external_wp_element_namespaceObject.useEffect)(() => { 54512 if (value) { 54513 setCachedValue(value); 54514 } 54515 }, [value]); 54516 return cachedValue; 54517 } 54518 54519 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/index.js 54520 /** 54521 * Internal dependencies 54522 */ 54523 54524 54525 54526 54527 54528 54529 54530 54531 54532 54533 54534 54535 54536 54537 54538 54539 54540 54541 54542 54543 54544 54545 54546 54547 54548 54549 54550 54551 createBlockEditFilter([align, text_align, hooks_anchor, custom_class_name, style, duotone, position, layout, content_lock_ui, block_hooks, block_bindings, layout_child].filter(Boolean)); 54552 createBlockListBlockFilter([align, text_align, background, style, color, dimensions, duotone, font_family, font_size, border, position, block_style_variation, layout_child]); 54553 createBlockSaveFilter([align, text_align, hooks_anchor, aria_label, custom_class_name, border, color, style, font_family, font_size]); 54554 54555 54556 54557 54558 54559 54560 54561 54562 54563 54564 54565 54566 54567 54568 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors/with-colors.js 54569 /** 54570 * WordPress dependencies 54571 */ 54572 54573 54574 54575 54576 /** 54577 * Internal dependencies 54578 */ 54579 54580 54581 54582 54583 const { 54584 kebabCase: with_colors_kebabCase 54585 } = unlock(external_wp_components_namespaceObject.privateApis); 54586 54587 /** 54588 * Capitalizes the first letter in a string. 54589 * 54590 * @param {string} str The string whose first letter the function will capitalize. 54591 * 54592 * @return {string} Capitalized string. 54593 */ 54594 const upperFirst = ([firstLetter, ...rest]) => firstLetter.toUpperCase() + rest.join(''); 54595 54596 /** 54597 * Higher order component factory for injecting the `colorsArray` argument as 54598 * the colors prop in the `withCustomColors` HOC. 54599 * 54600 * @param {Array} colorsArray An array of color objects. 54601 * 54602 * @return {Function} The higher order component. 54603 */ 54604 const withCustomColorPalette = colorsArray => (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 54605 ...props, 54606 colors: colorsArray 54607 }), 'withCustomColorPalette'); 54608 54609 /** 54610 * Higher order component factory for injecting the editor colors as the 54611 * `colors` prop in the `withColors` HOC. 54612 * 54613 * @return {Function} The higher order component. 54614 */ 54615 const withEditorColorPalette = () => (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => { 54616 const [userPalette, themePalette, defaultPalette] = use_settings_useSettings('color.palette.custom', 'color.palette.theme', 'color.palette.default'); 54617 const allColors = (0,external_wp_element_namespaceObject.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]); 54618 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 54619 ...props, 54620 colors: allColors 54621 }); 54622 }, 'withEditorColorPalette'); 54623 54624 /** 54625 * Helper function used with `createHigherOrderComponent` to create 54626 * higher order components for managing color logic. 54627 * 54628 * @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor). 54629 * @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent. 54630 * 54631 * @return {Component} The component that can be used as a HOC. 54632 */ 54633 function createColorHOC(colorTypes, withColorPalette) { 54634 const colorMap = colorTypes.reduce((colorObject, colorType) => { 54635 return { 54636 ...colorObject, 54637 ...(typeof colorType === 'string' ? { 54638 [colorType]: with_colors_kebabCase(colorType) 54639 } : colorType) 54640 }; 54641 }, {}); 54642 return (0,external_wp_compose_namespaceObject.compose)([withColorPalette, WrappedComponent => { 54643 return class extends external_wp_element_namespaceObject.Component { 54644 constructor(props) { 54645 super(props); 54646 this.setters = this.createSetters(); 54647 this.colorUtils = { 54648 getMostReadableColor: this.getMostReadableColor.bind(this) 54649 }; 54650 this.state = {}; 54651 } 54652 getMostReadableColor(colorValue) { 54653 const { 54654 colors 54655 } = this.props; 54656 return getMostReadableColor(colors, colorValue); 54657 } 54658 createSetters() { 54659 return Object.keys(colorMap).reduce((settersAccumulator, colorAttributeName) => { 54660 const upperFirstColorAttributeName = upperFirst(colorAttributeName); 54661 const customColorAttributeName = `custom$upperFirstColorAttributeName}`; 54662 settersAccumulator[`set$upperFirstColorAttributeName}`] = this.createSetColor(colorAttributeName, customColorAttributeName); 54663 return settersAccumulator; 54664 }, {}); 54665 } 54666 createSetColor(colorAttributeName, customColorAttributeName) { 54667 return colorValue => { 54668 const colorObject = getColorObjectByColorValue(this.props.colors, colorValue); 54669 this.props.setAttributes({ 54670 [colorAttributeName]: colorObject && colorObject.slug ? colorObject.slug : undefined, 54671 [customColorAttributeName]: colorObject && colorObject.slug ? undefined : colorValue 54672 }); 54673 }; 54674 } 54675 static getDerivedStateFromProps({ 54676 attributes, 54677 colors 54678 }, previousState) { 54679 return Object.entries(colorMap).reduce((newState, [colorAttributeName, colorContext]) => { 54680 const colorObject = getColorObjectByAttributeValues(colors, attributes[colorAttributeName], attributes[`custom$upperFirst(colorAttributeName)}`]); 54681 const previousColorObject = previousState[colorAttributeName]; 54682 const previousColor = previousColorObject?.color; 54683 /** 54684 * The "and previousColorObject" condition checks that a previous color object was already computed. 54685 * At the start previousColorObject and colorValue are both equal to undefined 54686 * bus as previousColorObject does not exist we should compute the object. 54687 */ 54688 if (previousColor === colorObject.color && previousColorObject) { 54689 newState[colorAttributeName] = previousColorObject; 54690 } else { 54691 newState[colorAttributeName] = { 54692 ...colorObject, 54693 class: getColorClassName(colorContext, colorObject.slug) 54694 }; 54695 } 54696 return newState; 54697 }, {}); 54698 } 54699 render() { 54700 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 54701 ...this.props, 54702 colors: undefined, 54703 ...this.state, 54704 ...this.setters, 54705 colorUtils: this.colorUtils 54706 }); 54707 } 54708 }; 54709 }]); 54710 } 54711 54712 /** 54713 * A higher-order component factory for creating a 'withCustomColors' HOC, which handles color logic 54714 * for class generation color value, retrieval and color attribute setting. 54715 * 54716 * Use this higher-order component to work with a custom set of colors. 54717 * 54718 * @example 54719 * 54720 * ```jsx 54721 * const CUSTOM_COLORS = [ { name: 'Red', slug: 'red', color: '#ff0000' }, { name: 'Blue', slug: 'blue', color: '#0000ff' } ]; 54722 * const withCustomColors = createCustomColorsHOC( CUSTOM_COLORS ); 54723 * // ... 54724 * export default compose( 54725 * withCustomColors( 'backgroundColor', 'borderColor' ), 54726 * MyColorfulComponent, 54727 * ); 54728 * ``` 54729 * 54730 * @param {Array} colorsArray The array of color objects (name, slug, color, etc... ). 54731 * 54732 * @return {Function} Higher-order component. 54733 */ 54734 function createCustomColorsHOC(colorsArray) { 54735 return (...colorTypes) => { 54736 const withColorPalette = withCustomColorPalette(colorsArray); 54737 return (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(createColorHOC(colorTypes, withColorPalette), 'withCustomColors'); 54738 }; 54739 } 54740 54741 /** 54742 * A higher-order component, which handles color logic for class generation color value, retrieval and color attribute setting. 54743 * 54744 * For use with the default editor/theme color palette. 54745 * 54746 * @example 54747 * 54748 * ```jsx 54749 * export default compose( 54750 * withColors( 'backgroundColor', { textColor: 'color' } ), 54751 * MyColorfulComponent, 54752 * ); 54753 * ``` 54754 * 54755 * @param {...(Object|string)} colorTypes The arguments can be strings or objects. If the argument is an object, 54756 * it should contain the color attribute name as key and the color context as value. 54757 * If the argument is a string the value should be the color attribute name, 54758 * the color context is computed by applying a kebab case transform to the value. 54759 * Color context represents the context/place where the color is going to be used. 54760 * The class name of the color is generated using 'has' followed by the color name 54761 * and ending with the color context all in kebab case e.g: has-green-background-color. 54762 * 54763 * @return {Function} Higher-order component. 54764 */ 54765 function withColors(...colorTypes) { 54766 const withColorPalette = withEditorColorPalette(); 54767 return (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(createColorHOC(colorTypes, withColorPalette), 'withColors'); 54768 } 54769 54770 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors/index.js 54771 54772 54773 54774 ;// ./node_modules/@wordpress/block-editor/build-module/components/gradients/index.js 54775 54776 54777 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/font-size-picker.js 54778 /** 54779 * WordPress dependencies 54780 */ 54781 54782 54783 /** 54784 * Internal dependencies 54785 */ 54786 54787 54788 function font_size_picker_FontSizePicker(props) { 54789 const [fontSizes, customFontSize] = use_settings_useSettings('typography.fontSizes', 'typography.customFontSize'); 54790 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FontSizePicker, { 54791 ...props, 54792 fontSizes: fontSizes, 54793 disableCustomFontSizes: !customFontSize 54794 }); 54795 } 54796 54797 /** 54798 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/font-sizes/README.md 54799 */ 54800 /* harmony default export */ const font_size_picker = (font_size_picker_FontSizePicker); 54801 54802 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/with-font-sizes.js 54803 /** 54804 * WordPress dependencies 54805 */ 54806 54807 54808 54809 /** 54810 * Internal dependencies 54811 */ 54812 54813 54814 54815 const DEFAULT_FONT_SIZES = []; 54816 54817 /** 54818 * Capitalizes the first letter in a string. 54819 * 54820 * @param {string} str The string whose first letter the function will capitalize. 54821 * 54822 * @return {string} Capitalized string. 54823 */ 54824 const with_font_sizes_upperFirst = ([firstLetter, ...rest]) => firstLetter.toUpperCase() + rest.join(''); 54825 54826 /** 54827 * Higher-order component, which handles font size logic for class generation, 54828 * font size value retrieval, and font size change handling. 54829 * 54830 * @param {...(Object|string)} fontSizeNames The arguments should all be strings. 54831 * Each string contains the font size 54832 * attribute name e.g: 'fontSize'. 54833 * 54834 * @return {Function} Higher-order component. 54835 */ 54836 /* harmony default export */ const with_font_sizes = ((...fontSizeNames) => { 54837 /* 54838 * Computes an object whose key is the font size attribute name as passed in the array, 54839 * and the value is the custom font size attribute name. 54840 * Custom font size is automatically compted by appending custom followed by the font size attribute name in with the first letter capitalized. 54841 */ 54842 const fontSizeAttributeNames = fontSizeNames.reduce((fontSizeAttributeNamesAccumulator, fontSizeAttributeName) => { 54843 fontSizeAttributeNamesAccumulator[fontSizeAttributeName] = `custom$with_font_sizes_upperFirst(fontSizeAttributeName)}`; 54844 return fontSizeAttributeNamesAccumulator; 54845 }, {}); 54846 return (0,external_wp_compose_namespaceObject.createHigherOrderComponent)((0,external_wp_compose_namespaceObject.compose)([(0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => { 54847 const [fontSizes] = use_settings_useSettings('typography.fontSizes'); 54848 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 54849 ...props, 54850 fontSizes: fontSizes || DEFAULT_FONT_SIZES 54851 }); 54852 }, 'withFontSizes'), WrappedComponent => { 54853 return class extends external_wp_element_namespaceObject.Component { 54854 constructor(props) { 54855 super(props); 54856 this.setters = this.createSetters(); 54857 this.state = {}; 54858 } 54859 createSetters() { 54860 return Object.entries(fontSizeAttributeNames).reduce((settersAccumulator, [fontSizeAttributeName, customFontSizeAttributeName]) => { 54861 const upperFirstFontSizeAttributeName = with_font_sizes_upperFirst(fontSizeAttributeName); 54862 settersAccumulator[`set$upperFirstFontSizeAttributeName}`] = this.createSetFontSize(fontSizeAttributeName, customFontSizeAttributeName); 54863 return settersAccumulator; 54864 }, {}); 54865 } 54866 createSetFontSize(fontSizeAttributeName, customFontSizeAttributeName) { 54867 return fontSizeValue => { 54868 const fontSizeObject = this.props.fontSizes?.find(({ 54869 size 54870 }) => size === Number(fontSizeValue)); 54871 this.props.setAttributes({ 54872 [fontSizeAttributeName]: fontSizeObject && fontSizeObject.slug ? fontSizeObject.slug : undefined, 54873 [customFontSizeAttributeName]: fontSizeObject && fontSizeObject.slug ? undefined : fontSizeValue 54874 }); 54875 }; 54876 } 54877 static getDerivedStateFromProps({ 54878 attributes, 54879 fontSizes 54880 }, previousState) { 54881 const didAttributesChange = (customFontSizeAttributeName, fontSizeAttributeName) => { 54882 if (previousState[fontSizeAttributeName]) { 54883 // If new font size is name compare with the previous slug. 54884 if (attributes[fontSizeAttributeName]) { 54885 return attributes[fontSizeAttributeName] !== previousState[fontSizeAttributeName].slug; 54886 } 54887 // If font size is not named, update when the font size value changes. 54888 return previousState[fontSizeAttributeName].size !== attributes[customFontSizeAttributeName]; 54889 } 54890 // In this case we need to build the font size object. 54891 return true; 54892 }; 54893 if (!Object.values(fontSizeAttributeNames).some(didAttributesChange)) { 54894 return null; 54895 } 54896 const newState = Object.entries(fontSizeAttributeNames).filter(([key, value]) => didAttributesChange(value, key)).reduce((newStateAccumulator, [fontSizeAttributeName, customFontSizeAttributeName]) => { 54897 const fontSizeAttributeValue = attributes[fontSizeAttributeName]; 54898 const fontSizeObject = utils_getFontSize(fontSizes, fontSizeAttributeValue, attributes[customFontSizeAttributeName]); 54899 newStateAccumulator[fontSizeAttributeName] = { 54900 ...fontSizeObject, 54901 class: getFontSizeClass(fontSizeAttributeValue) 54902 }; 54903 return newStateAccumulator; 54904 }, {}); 54905 return { 54906 ...previousState, 54907 ...newState 54908 }; 54909 } 54910 render() { 54911 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 54912 ...this.props, 54913 fontSizes: undefined, 54914 ...this.state, 54915 ...this.setters 54916 }); 54917 } 54918 }; 54919 }]), 'withFontSizes'); 54920 }); 54921 54922 ;// ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/index.js 54923 54924 54925 54926 54927 54928 ;// ./node_modules/@wordpress/block-editor/build-module/autocompleters/block.js 54929 /** 54930 * WordPress dependencies 54931 */ 54932 54933 54934 54935 54936 /** 54937 * Internal dependencies 54938 */ 54939 54940 54941 54942 54943 54944 54945 54946 const block_noop = () => {}; 54947 const block_SHOWN_BLOCK_TYPES = 9; 54948 54949 /** 54950 * Creates a blocks repeater for replacing the current block with a selected block type. 54951 * 54952 * @return {Object} A blocks completer. 54953 */ 54954 function createBlockCompleter() { 54955 return { 54956 name: 'blocks', 54957 className: 'block-editor-autocompleters__block', 54958 triggerPrefix: '/', 54959 useItems(filterValue) { 54960 const { 54961 rootClientId, 54962 selectedBlockId, 54963 prioritizedBlocks 54964 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 54965 const { 54966 getSelectedBlockClientId, 54967 getBlock, 54968 getBlockListSettings, 54969 getBlockRootClientId 54970 } = select(store); 54971 const { 54972 getActiveBlockVariation 54973 } = select(external_wp_blocks_namespaceObject.store); 54974 const selectedBlockClientId = getSelectedBlockClientId(); 54975 const { 54976 name: blockName, 54977 attributes 54978 } = getBlock(selectedBlockClientId); 54979 const activeBlockVariation = getActiveBlockVariation(blockName, attributes); 54980 const _rootClientId = getBlockRootClientId(selectedBlockClientId); 54981 return { 54982 selectedBlockId: activeBlockVariation ? `$blockName}/$activeBlockVariation.name}` : blockName, 54983 rootClientId: _rootClientId, 54984 prioritizedBlocks: getBlockListSettings(_rootClientId)?.prioritizedInserterBlocks 54985 }; 54986 }, []); 54987 const [items, categories, collections] = use_block_types_state(rootClientId, block_noop, true); 54988 const filteredItems = (0,external_wp_element_namespaceObject.useMemo)(() => { 54989 const initialFilteredItems = !!filterValue.trim() ? searchBlockItems(items, categories, collections, filterValue) : orderInserterBlockItems(orderBy(items, 'frecency', 'desc'), prioritizedBlocks); 54990 return initialFilteredItems.filter(item => item.id !== selectedBlockId).slice(0, block_SHOWN_BLOCK_TYPES); 54991 }, [filterValue, selectedBlockId, items, categories, collections, prioritizedBlocks]); 54992 const options = (0,external_wp_element_namespaceObject.useMemo)(() => filteredItems.map(blockItem => { 54993 const { 54994 title, 54995 icon, 54996 isDisabled 54997 } = blockItem; 54998 return { 54999 key: `block-$blockItem.id}`, 55000 value: blockItem, 55001 label: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 55002 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 55003 icon: icon, 55004 showColors: true 55005 }, "icon"), title] 55006 }), 55007 isDisabled 55008 }; 55009 }), [filteredItems]); 55010 return [options]; 55011 }, 55012 allowContext(before, after) { 55013 return !(/\S/.test(before) || /\S/.test(after)); 55014 }, 55015 getOptionCompletion(inserterItem) { 55016 const { 55017 name, 55018 initialAttributes, 55019 innerBlocks, 55020 syncStatus, 55021 content 55022 } = inserterItem; 55023 return { 55024 action: 'replace', 55025 value: syncStatus === 'unsynced' ? (0,external_wp_blocks_namespaceObject.parse)(content, { 55026 __unstableSkipMigrationLogs: true 55027 }) : (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(innerBlocks)) 55028 }; 55029 } 55030 }; 55031 } 55032 55033 /** 55034 * Creates a blocks repeater for replacing the current block with a selected block type. 55035 * 55036 * @return {Object} A blocks completer. 55037 */ 55038 /* harmony default export */ const autocompleters_block = (createBlockCompleter()); 55039 55040 ;// external ["wp","apiFetch"] 55041 const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"]; 55042 var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject); 55043 ;// ./node_modules/@wordpress/icons/build-module/library/post.js 55044 /** 55045 * WordPress dependencies 55046 */ 55047 55048 55049 const post = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 55050 xmlns: "http://www.w3.org/2000/svg", 55051 viewBox: "0 0 24 24", 55052 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 55053 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" 55054 }) 55055 }); 55056 /* harmony default export */ const library_post = (post); 55057 55058 ;// ./node_modules/@wordpress/block-editor/build-module/autocompleters/link.js 55059 /** 55060 * WordPress dependencies 55061 */ 55062 // Disable Reason: Needs to be refactored. 55063 // eslint-disable-next-line no-restricted-imports 55064 55065 55066 55067 55068 55069 const SHOWN_SUGGESTIONS = 10; 55070 55071 /** 55072 * Creates a suggestion list for links to posts or pages. 55073 * 55074 * @return {Object} A links completer. 55075 */ 55076 function createLinkCompleter() { 55077 return { 55078 name: 'links', 55079 className: 'block-editor-autocompleters__link', 55080 triggerPrefix: '[[', 55081 options: async letters => { 55082 let options = await external_wp_apiFetch_default()({ 55083 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', { 55084 per_page: SHOWN_SUGGESTIONS, 55085 search: letters, 55086 type: 'post', 55087 order_by: 'menu_order' 55088 }) 55089 }); 55090 options = options.filter(option => option.title !== ''); 55091 return options; 55092 }, 55093 getOptionKeywords(item) { 55094 const expansionWords = item.title.split(/\s+/); 55095 return [...expansionWords]; 55096 }, 55097 getOptionLabel(item) { 55098 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 55099 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 55100 icon: item.subtype === 'page' ? library_page : library_post 55101 }, "icon"), (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(item.title)] 55102 }); 55103 }, 55104 getOptionCompletion(item) { 55105 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("a", { 55106 href: item.url, 55107 children: item.title 55108 }); 55109 } 55110 }; 55111 } 55112 55113 /** 55114 * Creates a suggestion list for links to posts or pages.. 55115 * 55116 * @return {Object} A link completer. 55117 */ 55118 /* harmony default export */ const autocompleters_link = (createLinkCompleter()); 55119 55120 ;// ./node_modules/@wordpress/block-editor/build-module/components/autocomplete/index.js 55121 /** 55122 * WordPress dependencies 55123 */ 55124 55125 55126 55127 55128 55129 /** 55130 * Internal dependencies 55131 */ 55132 55133 55134 55135 55136 /** 55137 * Shared reference to an empty array for cases where it is important to avoid 55138 * returning a new array reference on every invocation. 55139 * 55140 * @type {Array} 55141 */ 55142 55143 const autocomplete_EMPTY_ARRAY = []; 55144 function useCompleters({ 55145 completers = autocomplete_EMPTY_ARRAY 55146 }) { 55147 const { 55148 name 55149 } = useBlockEditContext(); 55150 return (0,external_wp_element_namespaceObject.useMemo)(() => { 55151 let filteredCompleters = [...completers, autocompleters_link]; 55152 if (name === (0,external_wp_blocks_namespaceObject.getDefaultBlockName)() || (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, '__experimentalSlashInserter', false)) { 55153 filteredCompleters = [...filteredCompleters, autocompleters_block]; 55154 } 55155 if ((0,external_wp_hooks_namespaceObject.hasFilter)('editor.Autocomplete.completers')) { 55156 // Provide copies so filters may directly modify them. 55157 if (filteredCompleters === completers) { 55158 filteredCompleters = filteredCompleters.map(completer => ({ 55159 ...completer 55160 })); 55161 } 55162 filteredCompleters = (0,external_wp_hooks_namespaceObject.applyFilters)('editor.Autocomplete.completers', filteredCompleters, name); 55163 } 55164 return filteredCompleters; 55165 }, [completers, name]); 55166 } 55167 function useBlockEditorAutocompleteProps(props) { 55168 return (0,external_wp_components_namespaceObject.__unstableUseAutocompleteProps)({ 55169 ...props, 55170 completers: useCompleters(props) 55171 }); 55172 } 55173 55174 /** 55175 * Wrap the default Autocomplete component with one that supports a filter hook 55176 * for customizing its list of autocompleters. 55177 * 55178 * @type {import('react').FC} 55179 */ 55180 function BlockEditorAutocomplete(props) { 55181 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Autocomplete, { 55182 ...props, 55183 completers: useCompleters(props) 55184 }); 55185 } 55186 55187 /** 55188 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/autocomplete/README.md 55189 */ 55190 /* harmony default export */ const autocomplete = (BlockEditorAutocomplete); 55191 55192 ;// ./node_modules/@wordpress/icons/build-module/library/fullscreen.js 55193 /** 55194 * WordPress dependencies 55195 */ 55196 55197 55198 const fullscreen = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 55199 xmlns: "http://www.w3.org/2000/svg", 55200 viewBox: "0 0 24 24", 55201 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 55202 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" 55203 }) 55204 }); 55205 /* harmony default export */ const library_fullscreen = (fullscreen); 55206 55207 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-full-height-alignment-control/index.js 55208 /** 55209 * WordPress dependencies 55210 */ 55211 55212 55213 55214 55215 function BlockFullHeightAlignmentControl({ 55216 isActive, 55217 label = (0,external_wp_i18n_namespaceObject.__)('Full height'), 55218 onToggle, 55219 isDisabled 55220 }) { 55221 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 55222 isActive: isActive, 55223 icon: library_fullscreen, 55224 label: label, 55225 onClick: () => onToggle(!isActive), 55226 disabled: isDisabled 55227 }); 55228 } 55229 /* harmony default export */ const block_full_height_alignment_control = (BlockFullHeightAlignmentControl); 55230 55231 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-matrix-control/index.js 55232 /** 55233 * WordPress dependencies 55234 */ 55235 55236 55237 55238 55239 const block_alignment_matrix_control_noop = () => {}; 55240 55241 /** 55242 * The alignment matrix control allows users to quickly adjust inner block alignment. 55243 * 55244 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-alignment-matrix-control/README.md 55245 * 55246 * @example 55247 * ```jsx 55248 * function Example() { 55249 * return ( 55250 * <BlockControls> 55251 * <BlockAlignmentMatrixControl 55252 * label={ __( 'Change content position' ) } 55253 * value="center" 55254 * onChange={ ( nextPosition ) => 55255 * setAttributes( { contentPosition: nextPosition } ) 55256 * } 55257 * /> 55258 * </BlockControls> 55259 * ); 55260 * } 55261 * ``` 55262 * 55263 * @param {Object} props Component props. 55264 * @param {string} props.label Label for the control. Defaults to 'Change matrix alignment'. 55265 * @param {Function} props.onChange Function to execute upon change of matrix state. 55266 * @param {string} props.value Content alignment location. One of: 'center', 'center center', 55267 * 'center left', 'center right', 'top center', 'top left', 55268 * 'top right', 'bottom center', 'bottom left', 'bottom right'. 55269 * @param {boolean} props.isDisabled Whether the control should be disabled. 55270 * @return {Element} The BlockAlignmentMatrixControl component. 55271 */ 55272 function BlockAlignmentMatrixControl(props) { 55273 const { 55274 label = (0,external_wp_i18n_namespaceObject.__)('Change matrix alignment'), 55275 onChange = block_alignment_matrix_control_noop, 55276 value = 'center', 55277 isDisabled 55278 } = props; 55279 const icon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.AlignmentMatrixControl.Icon, { 55280 value: value 55281 }); 55282 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 55283 popoverProps: { 55284 placement: 'bottom-start' 55285 }, 55286 renderToggle: ({ 55287 onToggle, 55288 isOpen 55289 }) => { 55290 const openOnArrowDown = event => { 55291 if (!isOpen && event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 55292 event.preventDefault(); 55293 onToggle(); 55294 } 55295 }; 55296 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 55297 onClick: onToggle, 55298 "aria-haspopup": "true", 55299 "aria-expanded": isOpen, 55300 onKeyDown: openOnArrowDown, 55301 label: label, 55302 icon: icon, 55303 showTooltip: true, 55304 disabled: isDisabled 55305 }); 55306 }, 55307 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.AlignmentMatrixControl, { 55308 hasFocusBorder: false, 55309 onChange: onChange, 55310 value: value 55311 }) 55312 }); 55313 } 55314 /* harmony default export */ const block_alignment_matrix_control = (BlockAlignmentMatrixControl); 55315 55316 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-title/use-block-display-title.js 55317 /** 55318 * WordPress dependencies 55319 */ 55320 55321 55322 55323 /** 55324 * Internal dependencies 55325 */ 55326 55327 55328 /** 55329 * Returns the block's configured title as a string, or empty if the title 55330 * cannot be determined. 55331 * 55332 * @example 55333 * 55334 * ```js 55335 * useBlockDisplayTitle( { clientId: 'afd1cb17-2c08-4e7a-91be-007ba7ddc3a1', maximumLength: 17 } ); 55336 * ``` 55337 * 55338 * @param {Object} props 55339 * @param {string} props.clientId Client ID of block. 55340 * @param {number|undefined} props.maximumLength The maximum length that the block title string may be before truncated. 55341 * @param {string|undefined} props.context The context to pass to `getBlockLabel`. 55342 * @return {?string} Block title. 55343 */ 55344 function useBlockDisplayTitle({ 55345 clientId, 55346 maximumLength, 55347 context 55348 }) { 55349 const blockTitle = (0,external_wp_data_namespaceObject.useSelect)(select => { 55350 if (!clientId) { 55351 return null; 55352 } 55353 const { 55354 getBlockName, 55355 getBlockAttributes 55356 } = select(store); 55357 const { 55358 getBlockType, 55359 getActiveBlockVariation 55360 } = select(external_wp_blocks_namespaceObject.store); 55361 const blockName = getBlockName(clientId); 55362 const blockType = getBlockType(blockName); 55363 if (!blockType) { 55364 return null; 55365 } 55366 const attributes = getBlockAttributes(clientId); 55367 const label = (0,external_wp_blocks_namespaceObject.__experimentalGetBlockLabel)(blockType, attributes, context); 55368 // If the label is defined we prioritize it over a possible block variation title match. 55369 if (label !== blockType.title) { 55370 return label; 55371 } 55372 const match = getActiveBlockVariation(blockName, attributes); 55373 // Label will fallback to the title if no label is defined for the current label context. 55374 return match?.title || blockType.title; 55375 }, [clientId, context]); 55376 if (!blockTitle) { 55377 return null; 55378 } 55379 if (maximumLength && maximumLength > 0 && blockTitle.length > maximumLength) { 55380 const omission = '...'; 55381 return blockTitle.slice(0, maximumLength - omission.length) + omission; 55382 } 55383 return blockTitle; 55384 } 55385 55386 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-title/index.js 55387 /** 55388 * Internal dependencies 55389 */ 55390 55391 55392 55393 /** 55394 * Renders the block's configured title as a string, or empty if the title 55395 * cannot be determined. 55396 * 55397 * @example 55398 * 55399 * ```jsx 55400 * <BlockTitle clientId="afd1cb17-2c08-4e7a-91be-007ba7ddc3a1" maximumLength={ 17 }/> 55401 * ``` 55402 * 55403 * @param {Object} props 55404 * @param {string} props.clientId Client ID of block. 55405 * @param {number|undefined} props.maximumLength The maximum length that the block title string may be before truncated. 55406 * @param {string|undefined} props.context The context to pass to `getBlockLabel`. 55407 * 55408 * @return {JSX.Element} Block title. 55409 */ 55410 function BlockTitle({ 55411 clientId, 55412 maximumLength, 55413 context 55414 }) { 55415 return useBlockDisplayTitle({ 55416 clientId, 55417 maximumLength, 55418 context 55419 }); 55420 } 55421 55422 ;// ./node_modules/@wordpress/block-editor/build-module/utils/get-editor-region.js 55423 /** 55424 * Gets the editor region for a given editor canvas element or 55425 * returns the passed element if no region is found 55426 * 55427 * @param { Object } editor The editor canvas element. 55428 * @return { Object } The editor region or given editor element 55429 */ 55430 function getEditorRegion(editor) { 55431 var _Array$from$find, _editorCanvas$closest; 55432 if (!editor) { 55433 return null; 55434 } 55435 55436 // If there are multiple editors, we need to find the iframe that contains our contentRef to make sure 55437 // we're focusing the region that contains this editor. 55438 const editorCanvas = (_Array$from$find = Array.from(document.querySelectorAll('iframe[name="editor-canvas"]').values()).find(iframe => { 55439 // Find the iframe that contains our contentRef 55440 const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; 55441 return iframeDocument === editor.ownerDocument; 55442 })) !== null && _Array$from$find !== void 0 ? _Array$from$find : editor; 55443 55444 // The region is provided by the editor, not the block-editor. 55445 // We should send focus to the region if one is available to reuse the 55446 // same interface for navigating landmarks. If no region is available, 55447 // use the canvas instead. 55448 return (_editorCanvas$closest = editorCanvas?.closest('[role="region"]')) !== null && _editorCanvas$closest !== void 0 ? _editorCanvas$closest : editorCanvas; 55449 } 55450 55451 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-breadcrumb/index.js 55452 /** 55453 * WordPress dependencies 55454 */ 55455 55456 55457 55458 55459 55460 55461 /** 55462 * Internal dependencies 55463 */ 55464 55465 55466 55467 55468 55469 55470 /** 55471 * Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. 55472 * 55473 * @param {Object} props Component props. 55474 * @param {string} props.rootLabelText Translated label for the root element of the breadcrumb trail. 55475 * @return {Element} Block Breadcrumb. 55476 */ 55477 55478 function BlockBreadcrumb({ 55479 rootLabelText 55480 }) { 55481 const { 55482 selectBlock, 55483 clearSelectedBlock 55484 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 55485 const { 55486 clientId, 55487 parents, 55488 hasSelection 55489 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 55490 const { 55491 getSelectionStart, 55492 getSelectedBlockClientId, 55493 getEnabledBlockParents 55494 } = unlock(select(store)); 55495 const selectedBlockClientId = getSelectedBlockClientId(); 55496 return { 55497 parents: getEnabledBlockParents(selectedBlockClientId), 55498 clientId: selectedBlockClientId, 55499 hasSelection: !!getSelectionStart().clientId 55500 }; 55501 }, []); 55502 const rootLabel = rootLabelText || (0,external_wp_i18n_namespaceObject.__)('Document'); 55503 55504 // We don't care about this specific ref, but this is a way 55505 // to get a ref within the editor canvas so we can focus it later. 55506 const blockRef = (0,external_wp_element_namespaceObject.useRef)(); 55507 useBlockElementRef(clientId, blockRef); 55508 55509 /* 55510 * Disable reason: The `list` ARIA role is redundant but 55511 * Safari+VoiceOver won't announce the list otherwise. 55512 */ 55513 /* eslint-disable jsx-a11y/no-redundant-roles */ 55514 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("ul", { 55515 className: "block-editor-block-breadcrumb", 55516 role: "list", 55517 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block breadcrumb'), 55518 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 55519 className: !hasSelection ? 'block-editor-block-breadcrumb__current' : undefined, 55520 "aria-current": !hasSelection ? 'true' : undefined, 55521 children: [hasSelection && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 55522 size: "small", 55523 className: "block-editor-block-breadcrumb__button", 55524 onClick: () => { 55525 // Find the block editor wrapper for the selected block 55526 const blockEditor = blockRef.current?.closest('.editor-styles-wrapper'); 55527 clearSelectedBlock(); 55528 getEditorRegion(blockEditor)?.focus(); 55529 }, 55530 children: rootLabel 55531 }), !hasSelection && rootLabel, !!clientId && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 55532 icon: chevron_right_small, 55533 className: "block-editor-block-breadcrumb__separator" 55534 })] 55535 }), parents.map(parentClientId => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 55536 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 55537 size: "small", 55538 className: "block-editor-block-breadcrumb__button", 55539 onClick: () => selectBlock(parentClientId), 55540 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTitle, { 55541 clientId: parentClientId, 55542 maximumLength: 35 55543 }) 55544 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 55545 icon: chevron_right_small, 55546 className: "block-editor-block-breadcrumb__separator" 55547 })] 55548 }, parentClientId)), !!clientId && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("li", { 55549 className: "block-editor-block-breadcrumb__current", 55550 "aria-current": "true", 55551 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTitle, { 55552 clientId: clientId, 55553 maximumLength: 35 55554 }) 55555 })] 55556 }) 55557 /* eslint-enable jsx-a11y/no-redundant-roles */; 55558 } 55559 /* harmony default export */ const block_breadcrumb = (BlockBreadcrumb); 55560 55561 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-content-overlay/index.js 55562 /** 55563 * WordPress dependencies 55564 */ 55565 55566 55567 /** 55568 * Internal dependencies 55569 */ 55570 55571 function useBlockOverlayActive(clientId) { 55572 return (0,external_wp_data_namespaceObject.useSelect)(select => { 55573 const { 55574 __unstableHasActiveBlockOverlayActive 55575 } = select(store); 55576 return __unstableHasActiveBlockOverlayActive(clientId); 55577 }, [clientId]); 55578 } 55579 55580 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/use-block-toolbar-popover-props.js 55581 /** 55582 * WordPress dependencies 55583 */ 55584 55585 55586 55587 55588 55589 /** 55590 * Internal dependencies 55591 */ 55592 55593 55594 55595 55596 const COMMON_PROPS = { 55597 placement: 'top-start' 55598 }; 55599 55600 // By default the toolbar sets the `shift` prop. If the user scrolls the page 55601 // down the toolbar will stay on screen by adopting a sticky position at the 55602 // top of the viewport. 55603 const DEFAULT_PROPS = { 55604 ...COMMON_PROPS, 55605 flip: false, 55606 shift: true 55607 }; 55608 55609 // When there isn't enough height between the top of the block and the editor 55610 // canvas, the `shift` prop is set to `false`, as it will cause the block to be 55611 // obscured. The `flip` behavior is enabled, which positions the toolbar below 55612 // the block. This only happens if the block is smaller than the viewport, as 55613 // otherwise the toolbar will be off-screen. 55614 const RESTRICTED_HEIGHT_PROPS = { 55615 ...COMMON_PROPS, 55616 flip: true, 55617 shift: false 55618 }; 55619 55620 /** 55621 * Get the popover props for the block toolbar, determined by the space at the top of the canvas and the toolbar height. 55622 * 55623 * @param {Element} contentElement The DOM element that represents the editor content or canvas. 55624 * @param {Element} selectedBlockElement The outer DOM element of the first selected block. 55625 * @param {Element} scrollContainer The scrollable container for the contentElement. 55626 * @param {number} toolbarHeight The height of the toolbar in pixels. 55627 * @param {boolean} isSticky Whether or not the selected block is sticky or fixed. 55628 * 55629 * @return {Object} The popover props used to determine the position of the toolbar. 55630 */ 55631 function getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky) { 55632 if (!contentElement || !selectedBlockElement) { 55633 return DEFAULT_PROPS; 55634 } 55635 55636 // Get how far the content area has been scrolled. 55637 const scrollTop = scrollContainer?.scrollTop || 0; 55638 const blockRect = getElementBounds(selectedBlockElement); 55639 const contentRect = contentElement.getBoundingClientRect(); 55640 55641 // Get the vertical position of top of the visible content area. 55642 const topOfContentElementInViewport = scrollTop + contentRect.top; 55643 55644 // The document element's clientHeight represents the viewport height. 55645 const viewportHeight = contentElement.ownerDocument.documentElement.clientHeight; 55646 55647 // The restricted height area is calculated as the sum of the 55648 // vertical position of the visible content area, plus the height 55649 // of the block toolbar. 55650 const restrictedTopArea = topOfContentElementInViewport + toolbarHeight; 55651 const hasSpaceForToolbarAbove = blockRect.top > restrictedTopArea; 55652 const isBlockTallerThanViewport = blockRect.height > viewportHeight - toolbarHeight; 55653 55654 // Sticky blocks are treated as if they will never have enough space for the toolbar above. 55655 if (!isSticky && (hasSpaceForToolbarAbove || isBlockTallerThanViewport)) { 55656 return DEFAULT_PROPS; 55657 } 55658 return RESTRICTED_HEIGHT_PROPS; 55659 } 55660 55661 /** 55662 * Determines the desired popover positioning behavior, returning a set of appropriate props. 55663 * 55664 * @param {Object} elements 55665 * @param {Element} elements.contentElement The DOM element that represents the editor content or canvas. 55666 * @param {string} elements.clientId The clientId of the first selected block. 55667 * 55668 * @return {Object} The popover props used to determine the position of the toolbar. 55669 */ 55670 function useBlockToolbarPopoverProps({ 55671 contentElement, 55672 clientId 55673 }) { 55674 const selectedBlockElement = useBlockElement(clientId); 55675 const [toolbarHeight, setToolbarHeight] = (0,external_wp_element_namespaceObject.useState)(0); 55676 const { 55677 blockIndex, 55678 isSticky 55679 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 55680 const { 55681 getBlockIndex, 55682 getBlockAttributes 55683 } = select(store); 55684 return { 55685 blockIndex: getBlockIndex(clientId), 55686 isSticky: hasStickyOrFixedPositionValue(getBlockAttributes(clientId)) 55687 }; 55688 }, [clientId]); 55689 const scrollContainer = (0,external_wp_element_namespaceObject.useMemo)(() => { 55690 if (!contentElement) { 55691 return; 55692 } 55693 return (0,external_wp_dom_namespaceObject.getScrollContainer)(contentElement); 55694 }, [contentElement]); 55695 const [props, setProps] = (0,external_wp_element_namespaceObject.useState)(() => getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky)); 55696 const popoverRef = (0,external_wp_compose_namespaceObject.useRefEffect)(popoverNode => { 55697 setToolbarHeight(popoverNode.offsetHeight); 55698 }, []); 55699 const updateProps = (0,external_wp_element_namespaceObject.useCallback)(() => setProps(getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky)), [contentElement, selectedBlockElement, scrollContainer, toolbarHeight]); 55700 55701 // Update props when the block is moved. This also ensures the props are 55702 // correct on initial mount, and when the selected block or content element 55703 // changes (since the callback ref will update). 55704 (0,external_wp_element_namespaceObject.useLayoutEffect)(updateProps, [blockIndex, updateProps]); 55705 55706 // Update props when the viewport is resized or the block is resized. 55707 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 55708 if (!contentElement || !selectedBlockElement) { 55709 return; 55710 } 55711 55712 // Update the toolbar props on viewport resize. 55713 const contentView = contentElement?.ownerDocument?.defaultView; 55714 contentView?.addEventHandler?.('resize', updateProps); 55715 55716 // Update the toolbar props on block resize. 55717 let resizeObserver; 55718 const blockView = selectedBlockElement?.ownerDocument?.defaultView; 55719 if (blockView.ResizeObserver) { 55720 resizeObserver = new blockView.ResizeObserver(updateProps); 55721 resizeObserver.observe(selectedBlockElement); 55722 } 55723 return () => { 55724 contentView?.removeEventHandler?.('resize', updateProps); 55725 if (resizeObserver) { 55726 resizeObserver.disconnect(); 55727 } 55728 }; 55729 }, [updateProps, contentElement, selectedBlockElement]); 55730 return { 55731 ...props, 55732 ref: popoverRef 55733 }; 55734 } 55735 55736 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/use-selected-block-tool-props.js 55737 /** 55738 * WordPress dependencies 55739 */ 55740 55741 55742 /** 55743 * Internal dependencies 55744 */ 55745 55746 55747 /** 55748 * Returns props for the selected block tools and empty block inserter. 55749 * 55750 * @param {string} clientId Selected block client ID. 55751 */ 55752 function useSelectedBlockToolProps(clientId) { 55753 const selectedBlockProps = (0,external_wp_data_namespaceObject.useSelect)(select => { 55754 const { 55755 getBlockRootClientId, 55756 getBlockParents, 55757 __experimentalGetBlockListSettingsForBlocks, 55758 isBlockInsertionPointVisible, 55759 getBlockInsertionPoint, 55760 getBlockOrder, 55761 hasMultiSelection, 55762 getLastMultiSelectedBlockClientId 55763 } = select(store); 55764 const blockParentsClientIds = getBlockParents(clientId); 55765 55766 // Get Block List Settings for all ancestors of the current Block clientId. 55767 const parentBlockListSettings = __experimentalGetBlockListSettingsForBlocks(blockParentsClientIds); 55768 55769 // Get the clientId of the topmost parent with the capture toolbars setting. 55770 const capturingClientId = blockParentsClientIds.find(parentClientId => parentBlockListSettings[parentClientId]?.__experimentalCaptureToolbars); 55771 let isInsertionPointVisible = false; 55772 if (isBlockInsertionPointVisible()) { 55773 const insertionPoint = getBlockInsertionPoint(); 55774 const order = getBlockOrder(insertionPoint.rootClientId); 55775 isInsertionPointVisible = order[insertionPoint.index] === clientId; 55776 } 55777 return { 55778 capturingClientId, 55779 isInsertionPointVisible, 55780 lastClientId: hasMultiSelection() ? getLastMultiSelectedBlockClientId() : null, 55781 rootClientId: getBlockRootClientId(clientId) 55782 }; 55783 }, [clientId]); 55784 return selectedBlockProps; 55785 } 55786 55787 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/empty-block-inserter.js 55788 /** 55789 * External dependencies 55790 */ 55791 55792 55793 /** 55794 * Internal dependencies 55795 */ 55796 55797 55798 55799 55800 55801 function EmptyBlockInserter({ 55802 clientId, 55803 __unstableContentRef 55804 }) { 55805 const { 55806 capturingClientId, 55807 isInsertionPointVisible, 55808 lastClientId, 55809 rootClientId 55810 } = useSelectedBlockToolProps(clientId); 55811 const popoverProps = useBlockToolbarPopoverProps({ 55812 contentElement: __unstableContentRef?.current, 55813 clientId 55814 }); 55815 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(cover, { 55816 clientId: capturingClientId || clientId, 55817 bottomClientId: lastClientId, 55818 className: dist_clsx('block-editor-block-list__block-side-inserter-popover', { 55819 'is-insertion-point-visible': isInsertionPointVisible 55820 }), 55821 __unstableContentRef: __unstableContentRef, 55822 ...popoverProps, 55823 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 55824 className: "block-editor-block-list__empty-block-inserter", 55825 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter, { 55826 position: "bottom right", 55827 rootClientId: rootClientId, 55828 clientId: clientId, 55829 __experimentalIsQuick: true 55830 }) 55831 }) 55832 }); 55833 } 55834 55835 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/use-scroll-when-dragging.js 55836 /** 55837 * WordPress dependencies 55838 */ 55839 55840 55841 const SCROLL_INACTIVE_DISTANCE_PX = 50; 55842 const SCROLL_INTERVAL_MS = 25; 55843 const PIXELS_PER_SECOND_PER_PERCENTAGE = 1000; 55844 const VELOCITY_MULTIPLIER = PIXELS_PER_SECOND_PER_PERCENTAGE * (SCROLL_INTERVAL_MS / 1000); 55845 55846 /** 55847 * React hook that scrolls the scroll container when a block is being dragged. 55848 * 55849 * @return {Function[]} `startScrolling`, `scrollOnDragOver`, `stopScrolling` 55850 * functions to be called in `onDragStart`, `onDragOver` 55851 * and `onDragEnd` events respectively. 55852 */ 55853 function useScrollWhenDragging() { 55854 const dragStartYRef = (0,external_wp_element_namespaceObject.useRef)(null); 55855 const velocityYRef = (0,external_wp_element_namespaceObject.useRef)(null); 55856 const scrollParentYRef = (0,external_wp_element_namespaceObject.useRef)(null); 55857 const scrollEditorIntervalRef = (0,external_wp_element_namespaceObject.useRef)(null); 55858 55859 // Clear interval when unmounting. 55860 (0,external_wp_element_namespaceObject.useEffect)(() => () => { 55861 if (scrollEditorIntervalRef.current) { 55862 clearInterval(scrollEditorIntervalRef.current); 55863 scrollEditorIntervalRef.current = null; 55864 } 55865 }, []); 55866 const startScrolling = (0,external_wp_element_namespaceObject.useCallback)(event => { 55867 dragStartYRef.current = event.clientY; 55868 55869 // Find nearest parent(s) to scroll. 55870 scrollParentYRef.current = (0,external_wp_dom_namespaceObject.getScrollContainer)(event.target); 55871 scrollEditorIntervalRef.current = setInterval(() => { 55872 if (scrollParentYRef.current && velocityYRef.current) { 55873 const newTop = scrollParentYRef.current.scrollTop + velocityYRef.current; 55874 55875 // Setting `behavior: 'smooth'` as a scroll property seems to hurt performance. 55876 // Better to use a small scroll interval. 55877 scrollParentYRef.current.scroll({ 55878 top: newTop 55879 }); 55880 } 55881 }, SCROLL_INTERVAL_MS); 55882 }, []); 55883 const scrollOnDragOver = (0,external_wp_element_namespaceObject.useCallback)(event => { 55884 if (!scrollParentYRef.current) { 55885 return; 55886 } 55887 const scrollParentHeight = scrollParentYRef.current.offsetHeight; 55888 const offsetDragStartPosition = dragStartYRef.current - scrollParentYRef.current.offsetTop; 55889 const offsetDragPosition = event.clientY - scrollParentYRef.current.offsetTop; 55890 if (event.clientY > offsetDragStartPosition) { 55891 // User is dragging downwards. 55892 const moveableDistance = Math.max(scrollParentHeight - offsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 55893 const dragDistance = Math.max(offsetDragPosition - offsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 55894 const distancePercentage = moveableDistance === 0 || dragDistance === 0 ? 0 : dragDistance / moveableDistance; 55895 velocityYRef.current = VELOCITY_MULTIPLIER * distancePercentage; 55896 } else if (event.clientY < offsetDragStartPosition) { 55897 // User is dragging upwards. 55898 const moveableDistance = Math.max(offsetDragStartPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 55899 const dragDistance = Math.max(offsetDragStartPosition - offsetDragPosition - SCROLL_INACTIVE_DISTANCE_PX, 0); 55900 const distancePercentage = moveableDistance === 0 || dragDistance === 0 ? 0 : dragDistance / moveableDistance; 55901 velocityYRef.current = -VELOCITY_MULTIPLIER * distancePercentage; 55902 } else { 55903 velocityYRef.current = 0; 55904 } 55905 }, []); 55906 const stopScrolling = () => { 55907 dragStartYRef.current = null; 55908 scrollParentYRef.current = null; 55909 if (scrollEditorIntervalRef.current) { 55910 clearInterval(scrollEditorIntervalRef.current); 55911 scrollEditorIntervalRef.current = null; 55912 } 55913 }; 55914 return [startScrolling, scrollOnDragOver, stopScrolling]; 55915 } 55916 55917 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/index.js 55918 /** 55919 * WordPress dependencies 55920 */ 55921 55922 55923 55924 55925 55926 55927 /** 55928 * Internal dependencies 55929 */ 55930 55931 55932 55933 55934 55935 55936 const BlockDraggable = ({ 55937 appendToOwnerDocument, 55938 children, 55939 clientIds, 55940 cloneClassname, 55941 elementId, 55942 onDragStart, 55943 onDragEnd, 55944 fadeWhenDisabled = false, 55945 dragComponent 55946 }) => { 55947 const { 55948 srcRootClientId, 55949 isDraggable, 55950 icon, 55951 visibleInserter, 55952 getBlockType 55953 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 55954 const { 55955 canMoveBlocks, 55956 getBlockRootClientId, 55957 getBlockName, 55958 getBlockAttributes, 55959 isBlockInsertionPointVisible 55960 } = select(store); 55961 const { 55962 getBlockType: _getBlockType, 55963 getActiveBlockVariation 55964 } = select(external_wp_blocks_namespaceObject.store); 55965 const rootClientId = getBlockRootClientId(clientIds[0]); 55966 const blockName = getBlockName(clientIds[0]); 55967 const variation = getActiveBlockVariation(blockName, getBlockAttributes(clientIds[0])); 55968 return { 55969 srcRootClientId: rootClientId, 55970 isDraggable: canMoveBlocks(clientIds), 55971 icon: variation?.icon || _getBlockType(blockName)?.icon, 55972 visibleInserter: isBlockInsertionPointVisible(), 55973 getBlockType: _getBlockType 55974 }; 55975 }, [clientIds]); 55976 const isDraggingRef = (0,external_wp_element_namespaceObject.useRef)(false); 55977 const [startScrolling, scrollOnDragOver, stopScrolling] = useScrollWhenDragging(); 55978 const { 55979 getAllowedBlocks, 55980 getBlockNamesByClientId, 55981 getBlockRootClientId 55982 } = (0,external_wp_data_namespaceObject.useSelect)(store); 55983 const { 55984 startDraggingBlocks, 55985 stopDraggingBlocks 55986 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 55987 55988 // Stop dragging blocks if the block draggable is unmounted. 55989 (0,external_wp_element_namespaceObject.useEffect)(() => { 55990 return () => { 55991 if (isDraggingRef.current) { 55992 stopDraggingBlocks(); 55993 } 55994 }; 55995 }, []); 55996 55997 // Find the root of the editor iframe. 55998 const blockEl = useBlockElement(clientIds[0]); 55999 const editorRoot = blockEl?.closest('body'); 56000 56001 /* 56002 * Add a dragover event listener to the editor root to track the blocks being dragged over. 56003 * The listener has to be inside the editor iframe otherwise the target isn't accessible. 56004 */ 56005 (0,external_wp_element_namespaceObject.useEffect)(() => { 56006 if (!editorRoot || !fadeWhenDisabled) { 56007 return; 56008 } 56009 const onDragOver = event => { 56010 if (!event.target.closest('[data-block]')) { 56011 return; 56012 } 56013 const draggedBlockNames = getBlockNamesByClientId(clientIds); 56014 const targetClientId = event.target.closest('[data-block]').getAttribute('data-block'); 56015 const allowedBlocks = getAllowedBlocks(targetClientId); 56016 const targetBlockName = getBlockNamesByClientId([targetClientId])[0]; 56017 56018 /* 56019 * Check if the target is valid to drop in. 56020 * If the target's allowedBlocks is an empty array, 56021 * it isn't a container block, in which case we check 56022 * its parent's validity instead. 56023 */ 56024 let dropTargetValid; 56025 if (allowedBlocks?.length === 0) { 56026 const targetRootClientId = getBlockRootClientId(targetClientId); 56027 const targetRootBlockName = getBlockNamesByClientId([targetRootClientId])[0]; 56028 const rootAllowedBlocks = getAllowedBlocks(targetRootClientId); 56029 dropTargetValid = isDropTargetValid(getBlockType, rootAllowedBlocks, draggedBlockNames, targetRootBlockName); 56030 } else { 56031 dropTargetValid = isDropTargetValid(getBlockType, allowedBlocks, draggedBlockNames, targetBlockName); 56032 } 56033 56034 /* 56035 * Update the body class to reflect if drop target is valid. 56036 * This has to be done on the document body because the draggable 56037 * chip is rendered outside of the editor iframe. 56038 */ 56039 if (!dropTargetValid && !visibleInserter) { 56040 window?.document?.body?.classList?.add('block-draggable-invalid-drag-token'); 56041 } else { 56042 window?.document?.body?.classList?.remove('block-draggable-invalid-drag-token'); 56043 } 56044 }; 56045 const throttledOnDragOver = (0,external_wp_compose_namespaceObject.throttle)(onDragOver, 200); 56046 editorRoot.addEventListener('dragover', throttledOnDragOver); 56047 return () => { 56048 editorRoot.removeEventListener('dragover', throttledOnDragOver); 56049 }; 56050 }, [clientIds, editorRoot, fadeWhenDisabled, getAllowedBlocks, getBlockNamesByClientId, getBlockRootClientId, getBlockType, visibleInserter]); 56051 if (!isDraggable) { 56052 return children({ 56053 draggable: false 56054 }); 56055 } 56056 const transferData = { 56057 type: 'block', 56058 srcClientIds: clientIds, 56059 srcRootClientId 56060 }; 56061 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Draggable, { 56062 appendToOwnerDocument: appendToOwnerDocument, 56063 cloneClassname: cloneClassname, 56064 __experimentalTransferDataType: "wp-blocks", 56065 transferData: transferData, 56066 onDragStart: event => { 56067 // Defer hiding the dragged source element to the next 56068 // frame to enable dragging. 56069 window.requestAnimationFrame(() => { 56070 startDraggingBlocks(clientIds); 56071 isDraggingRef.current = true; 56072 startScrolling(event); 56073 if (onDragStart) { 56074 onDragStart(); 56075 } 56076 }); 56077 }, 56078 onDragOver: scrollOnDragOver, 56079 onDragEnd: () => { 56080 stopDraggingBlocks(); 56081 isDraggingRef.current = false; 56082 stopScrolling(); 56083 if (onDragEnd) { 56084 onDragEnd(); 56085 } 56086 }, 56087 __experimentalDragComponent: 56088 // Check against `undefined` so that `null` can be used to disable 56089 // the default drag component. 56090 dragComponent !== undefined ? dragComponent : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockDraggableChip, { 56091 count: clientIds.length, 56092 icon: icon, 56093 fadeWhenDisabled: true 56094 }), 56095 elementId: elementId, 56096 children: ({ 56097 onDraggableStart, 56098 onDraggableEnd 56099 }) => { 56100 return children({ 56101 draggable: true, 56102 onDragStart: onDraggableStart, 56103 onDragEnd: onDraggableEnd 56104 }); 56105 } 56106 }); 56107 }; 56108 /* harmony default export */ const block_draggable = (BlockDraggable); 56109 56110 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-mover/mover-description.js 56111 /** 56112 * WordPress dependencies 56113 */ 56114 56115 const getMovementDirection = (moveDirection, orientation) => { 56116 if (moveDirection === 'up') { 56117 if (orientation === 'horizontal') { 56118 return (0,external_wp_i18n_namespaceObject.isRTL)() ? 'right' : 'left'; 56119 } 56120 return 'up'; 56121 } else if (moveDirection === 'down') { 56122 if (orientation === 'horizontal') { 56123 return (0,external_wp_i18n_namespaceObject.isRTL)() ? 'left' : 'right'; 56124 } 56125 return 'down'; 56126 } 56127 return null; 56128 }; 56129 56130 /** 56131 * Return a label for the block movement controls depending on block position. 56132 * 56133 * @param {number} selectedCount Number of blocks selected. 56134 * @param {string} type Block type - in the case of a single block, should 56135 * define its 'type'. I.e. 'Text', 'Heading', 'Image' etc. 56136 * @param {number} firstIndex The index (position - 1) of the first block selected. 56137 * @param {boolean} isFirst This is the first block. 56138 * @param {boolean} isLast This is the last block. 56139 * @param {number} dir Direction of movement (> 0 is considered to be going 56140 * down, < 0 is up). 56141 * @param {string} orientation The orientation of the block movers, vertical or 56142 * horizontal. 56143 * 56144 * @return {string | undefined} Label for the block movement controls. 56145 */ 56146 function getBlockMoverDescription(selectedCount, type, firstIndex, isFirst, isLast, dir, orientation) { 56147 const position = firstIndex + 1; 56148 if (selectedCount > 1) { 56149 return getMultiBlockMoverDescription(selectedCount, firstIndex, isFirst, isLast, dir, orientation); 56150 } 56151 if (isFirst && isLast) { 56152 return (0,external_wp_i18n_namespaceObject.sprintf)( 56153 // translators: %s: Type of block (i.e. Text, Image etc) 56154 (0,external_wp_i18n_namespaceObject.__)('Block %s is the only block, and cannot be moved'), type); 56155 } 56156 if (dir > 0 && !isLast) { 56157 // Moving down. 56158 const movementDirection = getMovementDirection('down', orientation); 56159 if (movementDirection === 'down') { 56160 return (0,external_wp_i18n_namespaceObject.sprintf)( 56161 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 56162 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d down to position %3$d'), type, position, position + 1); 56163 } 56164 if (movementDirection === 'left') { 56165 return (0,external_wp_i18n_namespaceObject.sprintf)( 56166 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 56167 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d left to position %3$d'), type, position, position + 1); 56168 } 56169 if (movementDirection === 'right') { 56170 return (0,external_wp_i18n_namespaceObject.sprintf)( 56171 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 56172 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d right to position %3$d'), type, position, position + 1); 56173 } 56174 } 56175 if (dir > 0 && isLast) { 56176 // Moving down, and is the last item. 56177 const movementDirection = getMovementDirection('down', orientation); 56178 if (movementDirection === 'down') { 56179 return (0,external_wp_i18n_namespaceObject.sprintf)( 56180 // translators: 1: Type of block (i.e. Text, Image etc) 56181 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the end of the content and can’t be moved down'), type); 56182 } 56183 if (movementDirection === 'left') { 56184 return (0,external_wp_i18n_namespaceObject.sprintf)( 56185 // translators: 1: Type of block (i.e. Text, Image etc) 56186 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the end of the content and can’t be moved left'), type); 56187 } 56188 if (movementDirection === 'right') { 56189 return (0,external_wp_i18n_namespaceObject.sprintf)( 56190 // translators: 1: Type of block (i.e. Text, Image etc) 56191 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the end of the content and can’t be moved right'), type); 56192 } 56193 } 56194 if (dir < 0 && !isFirst) { 56195 // Moving up. 56196 const movementDirection = getMovementDirection('up', orientation); 56197 if (movementDirection === 'up') { 56198 return (0,external_wp_i18n_namespaceObject.sprintf)( 56199 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 56200 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d up to position %3$d'), type, position, position - 1); 56201 } 56202 if (movementDirection === 'left') { 56203 return (0,external_wp_i18n_namespaceObject.sprintf)( 56204 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 56205 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d left to position %3$d'), type, position, position - 1); 56206 } 56207 if (movementDirection === 'right') { 56208 return (0,external_wp_i18n_namespaceObject.sprintf)( 56209 // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position 56210 (0,external_wp_i18n_namespaceObject.__)('Move %1$s block from position %2$d right to position %3$d'), type, position, position - 1); 56211 } 56212 } 56213 if (dir < 0 && isFirst) { 56214 // Moving up, and is the first item. 56215 const movementDirection = getMovementDirection('up', orientation); 56216 if (movementDirection === 'up') { 56217 return (0,external_wp_i18n_namespaceObject.sprintf)( 56218 // translators: 1: Type of block (i.e. Text, Image etc) 56219 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the beginning of the content and can’t be moved up'), type); 56220 } 56221 if (movementDirection === 'left') { 56222 return (0,external_wp_i18n_namespaceObject.sprintf)( 56223 // translators: 1: Type of block (i.e. Text, Image etc) 56224 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the beginning of the content and can’t be moved left'), type); 56225 } 56226 if (movementDirection === 'right') { 56227 return (0,external_wp_i18n_namespaceObject.sprintf)( 56228 // translators: 1: Type of block (i.e. Text, Image etc) 56229 (0,external_wp_i18n_namespaceObject.__)('Block %1$s is at the beginning of the content and can’t be moved right'), type); 56230 } 56231 } 56232 } 56233 56234 /** 56235 * Return a label for the block movement controls depending on block position. 56236 * 56237 * @param {number} selectedCount Number of blocks selected. 56238 * @param {number} firstIndex The index (position - 1) of the first block selected. 56239 * @param {boolean} isFirst This is the first block. 56240 * @param {boolean} isLast This is the last block. 56241 * @param {number} dir Direction of movement (> 0 is considered to be going 56242 * down, < 0 is up). 56243 * @param {string} orientation The orientation of the block movers, vertical or 56244 * horizontal. 56245 * 56246 * @return {string | undefined} Label for the block movement controls. 56247 */ 56248 function getMultiBlockMoverDescription(selectedCount, firstIndex, isFirst, isLast, dir, orientation) { 56249 const position = firstIndex + 1; 56250 if (isFirst && isLast) { 56251 // All blocks are selected 56252 return (0,external_wp_i18n_namespaceObject.__)('All blocks are selected, and cannot be moved'); 56253 } 56254 if (dir > 0 && !isLast) { 56255 // moving down 56256 const movementDirection = getMovementDirection('down', orientation); 56257 if (movementDirection === 'down') { 56258 return (0,external_wp_i18n_namespaceObject.sprintf)( 56259 // translators: 1: Number of selected blocks, 2: Position of selected blocks 56260 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d down by one place'), selectedCount, position); 56261 } 56262 if (movementDirection === 'left') { 56263 return (0,external_wp_i18n_namespaceObject.sprintf)( 56264 // translators: 1: Number of selected blocks, 2: Position of selected blocks 56265 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d left by one place'), selectedCount, position); 56266 } 56267 if (movementDirection === 'right') { 56268 return (0,external_wp_i18n_namespaceObject.sprintf)( 56269 // translators: 1: Number of selected blocks, 2: Position of selected blocks 56270 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d right by one place'), selectedCount, position); 56271 } 56272 } 56273 if (dir > 0 && isLast) { 56274 // moving down, and the selected blocks are the last item 56275 const movementDirection = getMovementDirection('down', orientation); 56276 if (movementDirection === 'down') { 56277 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved down as they are already at the bottom'); 56278 } 56279 if (movementDirection === 'left') { 56280 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved left as they are already are at the leftmost position'); 56281 } 56282 if (movementDirection === 'right') { 56283 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved right as they are already are at the rightmost position'); 56284 } 56285 } 56286 if (dir < 0 && !isFirst) { 56287 // moving up 56288 const movementDirection = getMovementDirection('up', orientation); 56289 if (movementDirection === 'up') { 56290 return (0,external_wp_i18n_namespaceObject.sprintf)( 56291 // translators: 1: Number of selected blocks, 2: Position of selected blocks 56292 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d up by one place'), selectedCount, position); 56293 } 56294 if (movementDirection === 'left') { 56295 return (0,external_wp_i18n_namespaceObject.sprintf)( 56296 // translators: 1: Number of selected blocks, 2: Position of selected blocks 56297 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d left by one place'), selectedCount, position); 56298 } 56299 if (movementDirection === 'right') { 56300 return (0,external_wp_i18n_namespaceObject.sprintf)( 56301 // translators: 1: Number of selected blocks, 2: Position of selected blocks 56302 (0,external_wp_i18n_namespaceObject.__)('Move %1$d blocks from position %2$d right by one place'), selectedCount, position); 56303 } 56304 } 56305 if (dir < 0 && isFirst) { 56306 // moving up, and the selected blocks are the first item 56307 const movementDirection = getMovementDirection('up', orientation); 56308 if (movementDirection === 'up') { 56309 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved up as they are already at the top'); 56310 } 56311 if (movementDirection === 'left') { 56312 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved left as they are already are at the leftmost position'); 56313 } 56314 if (movementDirection === 'right') { 56315 return (0,external_wp_i18n_namespaceObject.__)('Blocks cannot be moved right as they are already are at the rightmost position'); 56316 } 56317 } 56318 } 56319 56320 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-mover/button.js 56321 /** 56322 * External dependencies 56323 */ 56324 56325 56326 /** 56327 * WordPress dependencies 56328 */ 56329 56330 56331 56332 56333 56334 56335 56336 /** 56337 * Internal dependencies 56338 */ 56339 56340 56341 56342 56343 const getArrowIcon = (direction, orientation) => { 56344 if (direction === 'up') { 56345 if (orientation === 'horizontal') { 56346 return (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left; 56347 } 56348 return chevron_up; 56349 } else if (direction === 'down') { 56350 if (orientation === 'horizontal') { 56351 return (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right; 56352 } 56353 return chevron_down; 56354 } 56355 return null; 56356 }; 56357 const getMovementDirectionLabel = (moveDirection, orientation) => { 56358 if (moveDirection === 'up') { 56359 if (orientation === 'horizontal') { 56360 return (0,external_wp_i18n_namespaceObject.isRTL)() ? (0,external_wp_i18n_namespaceObject.__)('Move right') : (0,external_wp_i18n_namespaceObject.__)('Move left'); 56361 } 56362 return (0,external_wp_i18n_namespaceObject.__)('Move up'); 56363 } else if (moveDirection === 'down') { 56364 if (orientation === 'horizontal') { 56365 return (0,external_wp_i18n_namespaceObject.isRTL)() ? (0,external_wp_i18n_namespaceObject.__)('Move left') : (0,external_wp_i18n_namespaceObject.__)('Move right'); 56366 } 56367 return (0,external_wp_i18n_namespaceObject.__)('Move down'); 56368 } 56369 return null; 56370 }; 56371 const BlockMoverButton = (0,external_wp_element_namespaceObject.forwardRef)(({ 56372 clientIds, 56373 direction, 56374 orientation: moverOrientation, 56375 ...props 56376 }, ref) => { 56377 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockMoverButton); 56378 const normalizedClientIds = Array.isArray(clientIds) ? clientIds : [clientIds]; 56379 const blocksCount = normalizedClientIds.length; 56380 const { 56381 disabled 56382 } = props; 56383 const { 56384 blockType, 56385 isDisabled, 56386 rootClientId, 56387 isFirst, 56388 isLast, 56389 firstIndex, 56390 orientation = 'vertical' 56391 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 56392 const { 56393 getBlockIndex, 56394 getBlockRootClientId, 56395 getBlockOrder, 56396 getBlock, 56397 getBlockListSettings 56398 } = select(store); 56399 const firstClientId = normalizedClientIds[0]; 56400 const blockRootClientId = getBlockRootClientId(firstClientId); 56401 const firstBlockIndex = getBlockIndex(firstClientId); 56402 const lastBlockIndex = getBlockIndex(normalizedClientIds[normalizedClientIds.length - 1]); 56403 const blockOrder = getBlockOrder(blockRootClientId); 56404 const block = getBlock(firstClientId); 56405 const isFirstBlock = firstBlockIndex === 0; 56406 const isLastBlock = lastBlockIndex === blockOrder.length - 1; 56407 const { 56408 orientation: blockListOrientation 56409 } = getBlockListSettings(blockRootClientId) || {}; 56410 return { 56411 blockType: block ? (0,external_wp_blocks_namespaceObject.getBlockType)(block.name) : null, 56412 isDisabled: disabled || (direction === 'up' ? isFirstBlock : isLastBlock), 56413 rootClientId: blockRootClientId, 56414 firstIndex: firstBlockIndex, 56415 isFirst: isFirstBlock, 56416 isLast: isLastBlock, 56417 orientation: moverOrientation || blockListOrientation 56418 }; 56419 }, [clientIds, direction]); 56420 const { 56421 moveBlocksDown, 56422 moveBlocksUp 56423 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 56424 const moverFunction = direction === 'up' ? moveBlocksUp : moveBlocksDown; 56425 const onClick = event => { 56426 moverFunction(clientIds, rootClientId); 56427 if (props.onClick) { 56428 props.onClick(event); 56429 } 56430 }; 56431 const descriptionId = `block-editor-block-mover-button__description-$instanceId}`; 56432 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 56433 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 56434 __next40pxDefaultSize: true, 56435 ref: ref, 56436 className: dist_clsx('block-editor-block-mover-button', `is-$direction}-button`), 56437 icon: getArrowIcon(direction, orientation), 56438 label: getMovementDirectionLabel(direction, orientation), 56439 "aria-describedby": descriptionId, 56440 ...props, 56441 onClick: isDisabled ? null : onClick, 56442 disabled: isDisabled, 56443 accessibleWhenDisabled: true 56444 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 56445 id: descriptionId, 56446 children: getBlockMoverDescription(blocksCount, blockType && blockType.title, firstIndex, isFirst, isLast, direction === 'up' ? -1 : 1, orientation) 56447 })] 56448 }); 56449 }); 56450 const BlockMoverUpButton = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 56451 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockMoverButton, { 56452 direction: "up", 56453 ref: ref, 56454 ...props 56455 }); 56456 }); 56457 const BlockMoverDownButton = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 56458 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockMoverButton, { 56459 direction: "down", 56460 ref: ref, 56461 ...props 56462 }); 56463 }); 56464 56465 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-mover/index.js 56466 /** 56467 * External dependencies 56468 */ 56469 56470 56471 /** 56472 * WordPress dependencies 56473 */ 56474 56475 56476 56477 56478 56479 56480 /** 56481 * Internal dependencies 56482 */ 56483 56484 56485 56486 56487 function BlockMover({ 56488 clientIds, 56489 hideDragHandle, 56490 isBlockMoverUpButtonDisabled, 56491 isBlockMoverDownButtonDisabled 56492 }) { 56493 const { 56494 canMove, 56495 rootClientId, 56496 isFirst, 56497 isLast, 56498 orientation, 56499 isManualGrid 56500 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 56501 var _getBlockAttributes; 56502 const { 56503 getBlockIndex, 56504 getBlockListSettings, 56505 canMoveBlocks, 56506 getBlockOrder, 56507 getBlockRootClientId, 56508 getBlockAttributes 56509 } = select(store); 56510 const normalizedClientIds = Array.isArray(clientIds) ? clientIds : [clientIds]; 56511 const firstClientId = normalizedClientIds[0]; 56512 const _rootClientId = getBlockRootClientId(firstClientId); 56513 const firstIndex = getBlockIndex(firstClientId); 56514 const lastIndex = getBlockIndex(normalizedClientIds[normalizedClientIds.length - 1]); 56515 const blockOrder = getBlockOrder(_rootClientId); 56516 const { 56517 layout = {} 56518 } = (_getBlockAttributes = getBlockAttributes(_rootClientId)) !== null && _getBlockAttributes !== void 0 ? _getBlockAttributes : {}; 56519 return { 56520 canMove: canMoveBlocks(clientIds), 56521 rootClientId: _rootClientId, 56522 isFirst: firstIndex === 0, 56523 isLast: lastIndex === blockOrder.length - 1, 56524 orientation: getBlockListSettings(_rootClientId)?.orientation, 56525 isManualGrid: layout.type === 'grid' && layout.isManualPlacement && window.__experimentalEnableGridInteractivity 56526 }; 56527 }, [clientIds]); 56528 if (!canMove || isFirst && isLast && !rootClientId || hideDragHandle && isManualGrid) { 56529 return null; 56530 } 56531 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.ToolbarGroup, { 56532 className: dist_clsx('block-editor-block-mover', { 56533 'is-horizontal': orientation === 'horizontal' 56534 }), 56535 children: [!hideDragHandle && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_draggable, { 56536 clientIds: clientIds, 56537 fadeWhenDisabled: true, 56538 children: draggableProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 56539 __next40pxDefaultSize: true, 56540 icon: drag_handle, 56541 className: "block-editor-block-mover__drag-handle", 56542 label: (0,external_wp_i18n_namespaceObject.__)('Drag') 56543 // Should not be able to tab to drag handle as this 56544 // button can only be used with a pointer device. 56545 , 56546 tabIndex: "-1", 56547 ...draggableProps 56548 }) 56549 }), !isManualGrid && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 56550 className: "block-editor-block-mover__move-button-container", 56551 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarItem, { 56552 children: itemProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockMoverUpButton, { 56553 disabled: isBlockMoverUpButtonDisabled, 56554 clientIds: clientIds, 56555 ...itemProps 56556 }) 56557 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarItem, { 56558 children: itemProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockMoverDownButton, { 56559 disabled: isBlockMoverDownButtonDisabled, 56560 clientIds: clientIds, 56561 ...itemProps 56562 }) 56563 })] 56564 })] 56565 }); 56566 } 56567 56568 /** 56569 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-mover/README.md 56570 */ 56571 /* harmony default export */ const block_mover = (BlockMover); 56572 56573 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/utils.js 56574 /** 56575 * WordPress dependencies 56576 */ 56577 56578 56579 56580 /** 56581 * Internal dependencies 56582 */ 56583 56584 const { 56585 clearTimeout: utils_clearTimeout, 56586 setTimeout: utils_setTimeout 56587 } = window; 56588 const DEBOUNCE_TIMEOUT = 200; 56589 56590 /** 56591 * Hook that creates debounced callbacks when the node is hovered or focused. 56592 * 56593 * @param {Object} props Component props. 56594 * @param {Object} props.ref Element reference. 56595 * @param {boolean} props.isFocused Whether the component has current focus. 56596 * @param {number} props.highlightParent Whether to highlight the parent block. It defaults in highlighting the selected block. 56597 * @param {number} [props.debounceTimeout=250] Debounce timeout in milliseconds. 56598 */ 56599 function useDebouncedShowGestures({ 56600 ref, 56601 isFocused, 56602 highlightParent, 56603 debounceTimeout = DEBOUNCE_TIMEOUT 56604 }) { 56605 const { 56606 getSelectedBlockClientId, 56607 getBlockRootClientId 56608 } = (0,external_wp_data_namespaceObject.useSelect)(store); 56609 const { 56610 toggleBlockHighlight 56611 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 56612 const timeoutRef = (0,external_wp_element_namespaceObject.useRef)(); 56613 const isDistractionFree = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree, []); 56614 const handleOnChange = nextIsFocused => { 56615 if (nextIsFocused && isDistractionFree) { 56616 return; 56617 } 56618 const selectedBlockClientId = getSelectedBlockClientId(); 56619 const clientId = highlightParent ? getBlockRootClientId(selectedBlockClientId) : selectedBlockClientId; 56620 toggleBlockHighlight(clientId, nextIsFocused); 56621 }; 56622 const getIsHovered = () => { 56623 return ref?.current && ref.current.matches(':hover'); 56624 }; 56625 const shouldHideGestures = () => { 56626 const isHovered = getIsHovered(); 56627 return !isFocused && !isHovered; 56628 }; 56629 const clearTimeoutRef = () => { 56630 const timeout = timeoutRef.current; 56631 if (timeout && utils_clearTimeout) { 56632 utils_clearTimeout(timeout); 56633 } 56634 }; 56635 const debouncedShowGestures = event => { 56636 if (event) { 56637 event.stopPropagation(); 56638 } 56639 clearTimeoutRef(); 56640 handleOnChange(true); 56641 }; 56642 const debouncedHideGestures = event => { 56643 if (event) { 56644 event.stopPropagation(); 56645 } 56646 clearTimeoutRef(); 56647 timeoutRef.current = utils_setTimeout(() => { 56648 if (shouldHideGestures()) { 56649 handleOnChange(false); 56650 } 56651 }, debounceTimeout); 56652 }; 56653 (0,external_wp_element_namespaceObject.useEffect)(() => () => { 56654 /** 56655 * We need to call the change handler with `isFocused` 56656 * set to false on unmount because we also clear the 56657 * timeout that would handle that. 56658 */ 56659 handleOnChange(false); 56660 clearTimeoutRef(); 56661 }, []); 56662 return { 56663 debouncedShowGestures, 56664 debouncedHideGestures 56665 }; 56666 } 56667 56668 /** 56669 * Hook that provides gesture events for DOM elements 56670 * that interact with the isFocused state. 56671 * 56672 * @param {Object} props Component props. 56673 * @param {Object} props.ref Element reference. 56674 * @param {number} [props.highlightParent=false] Whether to highlight the parent block. It defaults to highlighting the selected block. 56675 * @param {number} [props.debounceTimeout=250] Debounce timeout in milliseconds. 56676 */ 56677 function useShowHoveredOrFocusedGestures({ 56678 ref, 56679 highlightParent = false, 56680 debounceTimeout = DEBOUNCE_TIMEOUT 56681 }) { 56682 const [isFocused, setIsFocused] = (0,external_wp_element_namespaceObject.useState)(false); 56683 const { 56684 debouncedShowGestures, 56685 debouncedHideGestures 56686 } = useDebouncedShowGestures({ 56687 ref, 56688 debounceTimeout, 56689 isFocused, 56690 highlightParent 56691 }); 56692 const registerRef = (0,external_wp_element_namespaceObject.useRef)(false); 56693 const isFocusedWithin = () => { 56694 return ref?.current && ref.current.contains(ref.current.ownerDocument.activeElement); 56695 }; 56696 (0,external_wp_element_namespaceObject.useEffect)(() => { 56697 const node = ref.current; 56698 const handleOnFocus = () => { 56699 if (isFocusedWithin()) { 56700 setIsFocused(true); 56701 debouncedShowGestures(); 56702 } 56703 }; 56704 const handleOnBlur = () => { 56705 if (!isFocusedWithin()) { 56706 setIsFocused(false); 56707 debouncedHideGestures(); 56708 } 56709 }; 56710 56711 /** 56712 * Events are added via DOM events (vs. React synthetic events), 56713 * as the child React components swallow mouse events. 56714 */ 56715 if (node && !registerRef.current) { 56716 node.addEventListener('focus', handleOnFocus, true); 56717 node.addEventListener('blur', handleOnBlur, true); 56718 registerRef.current = true; 56719 } 56720 return () => { 56721 if (node) { 56722 node.removeEventListener('focus', handleOnFocus); 56723 node.removeEventListener('blur', handleOnBlur); 56724 } 56725 }; 56726 }, [ref, registerRef, setIsFocused, debouncedShowGestures, debouncedHideGestures]); 56727 return { 56728 onMouseMove: debouncedShowGestures, 56729 onMouseLeave: debouncedHideGestures 56730 }; 56731 } 56732 56733 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-parent-selector/index.js 56734 /** 56735 * WordPress dependencies 56736 */ 56737 56738 56739 56740 56741 56742 /** 56743 * Internal dependencies 56744 */ 56745 56746 56747 56748 56749 56750 56751 /** 56752 * Block parent selector component, displaying the hierarchy of the 56753 * current block selection as a single icon to "go up" a level. 56754 * 56755 * @return {Component} Parent block selector. 56756 */ 56757 56758 function BlockParentSelector() { 56759 const { 56760 selectBlock 56761 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 56762 const { 56763 parentClientId 56764 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 56765 const { 56766 getBlockParents, 56767 getSelectedBlockClientId, 56768 getParentSectionBlock 56769 } = unlock(select(store)); 56770 const selectedBlockClientId = getSelectedBlockClientId(); 56771 const parentSection = getParentSectionBlock(selectedBlockClientId); 56772 const parents = getBlockParents(selectedBlockClientId); 56773 const _parentClientId = parentSection !== null && parentSection !== void 0 ? parentSection : parents[parents.length - 1]; 56774 return { 56775 parentClientId: _parentClientId 56776 }; 56777 }, []); 56778 const blockInformation = useBlockDisplayInformation(parentClientId); 56779 56780 // Allows highlighting the parent block outline when focusing or hovering 56781 // the parent block selector within the child. 56782 const nodeRef = (0,external_wp_element_namespaceObject.useRef)(); 56783 const showHoveredOrFocusedGestures = useShowHoveredOrFocusedGestures({ 56784 ref: nodeRef, 56785 highlightParent: true 56786 }); 56787 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 56788 className: "block-editor-block-parent-selector", 56789 ref: nodeRef, 56790 ...showHoveredOrFocusedGestures, 56791 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 56792 className: "block-editor-block-parent-selector__button", 56793 onClick: () => selectBlock(parentClientId), 56794 label: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Name of the block's parent. */ 56795 (0,external_wp_i18n_namespaceObject.__)('Select parent block: %s'), blockInformation?.title), 56796 showTooltip: true, 56797 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 56798 icon: blockInformation?.icon 56799 }) 56800 }) 56801 }, parentClientId); 56802 } 56803 56804 ;// ./node_modules/@wordpress/icons/build-module/library/copy.js 56805 /** 56806 * WordPress dependencies 56807 */ 56808 56809 56810 const copy_copy = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 56811 xmlns: "http://www.w3.org/2000/svg", 56812 viewBox: "0 0 24 24", 56813 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 56814 fillRule: "evenodd", 56815 clipRule: "evenodd", 56816 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" 56817 }) 56818 }); 56819 /* harmony default export */ const library_copy = (copy_copy); 56820 56821 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/preview-block-popover.js 56822 /** 56823 * WordPress dependencies 56824 */ 56825 56826 56827 56828 56829 /** 56830 * Internal dependencies 56831 */ 56832 56833 56834 function PreviewBlockPopover({ 56835 blocks 56836 }) { 56837 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 56838 if (isMobile) { 56839 return null; 56840 } 56841 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 56842 className: "block-editor-block-switcher__popover-preview-container", 56843 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 56844 className: "block-editor-block-switcher__popover-preview", 56845 placement: "right-start", 56846 focusOnMount: false, 56847 offset: 16, 56848 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 56849 className: "block-editor-block-switcher__preview", 56850 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 56851 className: "block-editor-block-switcher__preview-title", 56852 children: (0,external_wp_i18n_namespaceObject.__)('Preview') 56853 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview, { 56854 viewportWidth: 500, 56855 blocks: blocks 56856 })] 56857 }) 56858 }) 56859 }); 56860 } 56861 56862 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/block-variation-transformations.js 56863 /** 56864 * WordPress dependencies 56865 */ 56866 56867 56868 56869 56870 56871 /** 56872 * Internal dependencies 56873 */ 56874 56875 56876 56877 56878 const block_variation_transformations_EMPTY_OBJECT = {}; 56879 function useBlockVariationTransforms({ 56880 clientIds, 56881 blocks 56882 }) { 56883 const { 56884 activeBlockVariation, 56885 blockVariationTransformations 56886 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 56887 const { 56888 getBlockAttributes, 56889 canRemoveBlocks 56890 } = select(store); 56891 const { 56892 getActiveBlockVariation, 56893 getBlockVariations 56894 } = select(external_wp_blocks_namespaceObject.store); 56895 const canRemove = canRemoveBlocks(clientIds); 56896 // Only handle single selected blocks for now. 56897 if (blocks.length !== 1 || !canRemove) { 56898 return block_variation_transformations_EMPTY_OBJECT; 56899 } 56900 const [firstBlock] = blocks; 56901 return { 56902 blockVariationTransformations: getBlockVariations(firstBlock.name, 'transform'), 56903 activeBlockVariation: getActiveBlockVariation(firstBlock.name, getBlockAttributes(firstBlock.clientId)) 56904 }; 56905 }, [clientIds, blocks]); 56906 const transformations = (0,external_wp_element_namespaceObject.useMemo)(() => { 56907 return blockVariationTransformations?.filter(({ 56908 name 56909 }) => name !== activeBlockVariation?.name); 56910 }, [blockVariationTransformations, activeBlockVariation]); 56911 return transformations; 56912 } 56913 const BlockVariationTransformations = ({ 56914 transformations, 56915 onSelect, 56916 blocks 56917 }) => { 56918 const [hoveredTransformItemName, setHoveredTransformItemName] = (0,external_wp_element_namespaceObject.useState)(); 56919 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 56920 children: [hoveredTransformItemName && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreviewBlockPopover, { 56921 blocks: (0,external_wp_blocks_namespaceObject.cloneBlock)(blocks[0], transformations.find(({ 56922 name 56923 }) => name === hoveredTransformItemName).attributes) 56924 }), transformations?.map(item => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockVariationTransformationItem, { 56925 item: item, 56926 onSelect: onSelect, 56927 setHoveredTransformItemName: setHoveredTransformItemName 56928 }, item.name))] 56929 }); 56930 }; 56931 function BlockVariationTransformationItem({ 56932 item, 56933 onSelect, 56934 setHoveredTransformItemName 56935 }) { 56936 const { 56937 name, 56938 icon, 56939 title 56940 } = item; 56941 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuItem, { 56942 className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(name), 56943 onClick: event => { 56944 event.preventDefault(); 56945 onSelect(name); 56946 }, 56947 onMouseLeave: () => setHoveredTransformItemName(null), 56948 onMouseEnter: () => setHoveredTransformItemName(name), 56949 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 56950 icon: icon, 56951 showColors: true 56952 }), title] 56953 }); 56954 } 56955 /* harmony default export */ const block_variation_transformations = (BlockVariationTransformations); 56956 56957 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/block-transformations-menu.js 56958 /** 56959 * WordPress dependencies 56960 */ 56961 56962 56963 56964 56965 56966 /** 56967 * Internal dependencies 56968 */ 56969 56970 56971 56972 56973 /** 56974 * Helper hook to group transformations to display them in a specific order in the UI. 56975 * For now we group only priority content driven transformations(ex. paragraph -> heading). 56976 * 56977 * Later on we could also group 'layout' transformations(ex. paragraph -> group) and 56978 * display them in different sections. 56979 * 56980 * @param {Object[]} possibleBlockTransformations The available block transformations. 56981 * @return {Record<string, Object[]>} The grouped block transformations. 56982 */ 56983 56984 function useGroupedTransforms(possibleBlockTransformations) { 56985 const priorityContentTransformationBlocks = { 56986 'core/paragraph': 1, 56987 'core/heading': 2, 56988 'core/list': 3, 56989 'core/quote': 4 56990 }; 56991 const transformations = (0,external_wp_element_namespaceObject.useMemo)(() => { 56992 const priorityTextTransformsNames = Object.keys(priorityContentTransformationBlocks); 56993 const groupedPossibleTransforms = possibleBlockTransformations.reduce((accumulator, item) => { 56994 const { 56995 name 56996 } = item; 56997 if (priorityTextTransformsNames.includes(name)) { 56998 accumulator.priorityTextTransformations.push(item); 56999 } else { 57000 accumulator.restTransformations.push(item); 57001 } 57002 return accumulator; 57003 }, { 57004 priorityTextTransformations: [], 57005 restTransformations: [] 57006 }); 57007 /** 57008 * If there is only one priority text transformation and it's a Quote, 57009 * is should move to the rest transformations. This is because Quote can 57010 * be a container for any block type, so in multi-block selection it will 57011 * always be suggested, even for non-text blocks. 57012 */ 57013 if (groupedPossibleTransforms.priorityTextTransformations.length === 1 && groupedPossibleTransforms.priorityTextTransformations[0].name === 'core/quote') { 57014 const singleQuote = groupedPossibleTransforms.priorityTextTransformations.pop(); 57015 groupedPossibleTransforms.restTransformations.push(singleQuote); 57016 } 57017 return groupedPossibleTransforms; 57018 }, [possibleBlockTransformations]); 57019 57020 // Order the priority text transformations. 57021 transformations.priorityTextTransformations.sort(({ 57022 name: currentName 57023 }, { 57024 name: nextName 57025 }) => { 57026 return priorityContentTransformationBlocks[currentName] < priorityContentTransformationBlocks[nextName] ? -1 : 1; 57027 }); 57028 return transformations; 57029 } 57030 const BlockTransformationsMenu = ({ 57031 className, 57032 possibleBlockTransformations, 57033 possibleBlockVariationTransformations, 57034 onSelect, 57035 onSelectVariation, 57036 blocks 57037 }) => { 57038 const [hoveredTransformItemName, setHoveredTransformItemName] = (0,external_wp_element_namespaceObject.useState)(); 57039 const { 57040 priorityTextTransformations, 57041 restTransformations 57042 } = useGroupedTransforms(possibleBlockTransformations); 57043 // We have to check if both content transformations(priority and rest) are set 57044 // in order to create a separate MenuGroup for them. 57045 const hasBothContentTransformations = priorityTextTransformations.length && restTransformations.length; 57046 const restTransformItems = !!restTransformations.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RestTransformationItems, { 57047 restTransformations: restTransformations, 57048 onSelect: onSelect, 57049 setHoveredTransformItemName: setHoveredTransformItemName 57050 }); 57051 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 57052 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 57053 label: (0,external_wp_i18n_namespaceObject.__)('Transform to'), 57054 className: className, 57055 children: [hoveredTransformItemName && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreviewBlockPopover, { 57056 blocks: (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, hoveredTransformItemName) 57057 }), !!possibleBlockVariationTransformations?.length && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_variation_transformations, { 57058 transformations: possibleBlockVariationTransformations, 57059 blocks: blocks, 57060 onSelect: onSelectVariation 57061 }), priorityTextTransformations.map(item => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTransformationItem, { 57062 item: item, 57063 onSelect: onSelect, 57064 setHoveredTransformItemName: setHoveredTransformItemName 57065 }, item.name)), !hasBothContentTransformations && restTransformItems] 57066 }), !!hasBothContentTransformations && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 57067 className: className, 57068 children: restTransformItems 57069 })] 57070 }); 57071 }; 57072 function RestTransformationItems({ 57073 restTransformations, 57074 onSelect, 57075 setHoveredTransformItemName 57076 }) { 57077 return restTransformations.map(item => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTransformationItem, { 57078 item: item, 57079 onSelect: onSelect, 57080 setHoveredTransformItemName: setHoveredTransformItemName 57081 }, item.name)); 57082 } 57083 function BlockTransformationItem({ 57084 item, 57085 onSelect, 57086 setHoveredTransformItemName 57087 }) { 57088 const { 57089 name, 57090 icon, 57091 title, 57092 isDisabled 57093 } = item; 57094 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuItem, { 57095 className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(name), 57096 onClick: event => { 57097 event.preventDefault(); 57098 onSelect(name); 57099 }, 57100 disabled: isDisabled, 57101 onMouseLeave: () => setHoveredTransformItemName(null), 57102 onMouseEnter: () => setHoveredTransformItemName(name), 57103 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 57104 icon: icon, 57105 showColors: true 57106 }), title] 57107 }); 57108 } 57109 /* harmony default export */ const block_transformations_menu = (BlockTransformationsMenu); 57110 57111 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-styles/utils.js 57112 /** 57113 * WordPress dependencies 57114 */ 57115 57116 57117 57118 /** 57119 * Returns the active style from the given className. 57120 * 57121 * @param {Array} styles Block styles. 57122 * @param {string} className Class name 57123 * 57124 * @return {?Object} The active style. 57125 */ 57126 function getActiveStyle(styles, className) { 57127 for (const style of new (external_wp_tokenList_default())(className).values()) { 57128 if (style.indexOf('is-style-') === -1) { 57129 continue; 57130 } 57131 const potentialStyleName = style.substring(9); 57132 const activeStyle = styles?.find(({ 57133 name 57134 }) => name === potentialStyleName); 57135 if (activeStyle) { 57136 return activeStyle; 57137 } 57138 } 57139 return getDefaultStyle(styles); 57140 } 57141 57142 /** 57143 * Replaces the active style in the block's className. 57144 * 57145 * @param {string} className Class name. 57146 * @param {?Object} activeStyle The replaced style. 57147 * @param {Object} newStyle The replacing style. 57148 * 57149 * @return {string} The updated className. 57150 */ 57151 function replaceActiveStyle(className, activeStyle, newStyle) { 57152 const list = new (external_wp_tokenList_default())(className); 57153 if (activeStyle) { 57154 list.remove('is-style-' + activeStyle.name); 57155 } 57156 list.add('is-style-' + newStyle.name); 57157 return list.value; 57158 } 57159 57160 /** 57161 * Returns a collection of styles that can be represented on the frontend. 57162 * The function checks a style collection for a default style. If none is found, it adds one to 57163 * act as a fallback for when there is no active style applied to a block. The default item also serves 57164 * as a switch on the frontend to deactivate non-default styles. 57165 * 57166 * @param {Array} styles Block styles. 57167 * 57168 * @return {Array<Object?>} The style collection. 57169 */ 57170 function getRenderedStyles(styles) { 57171 if (!styles || styles.length === 0) { 57172 return []; 57173 } 57174 return getDefaultStyle(styles) ? styles : [{ 57175 name: 'default', 57176 label: (0,external_wp_i18n_namespaceObject._x)('Default', 'block style'), 57177 isDefault: true 57178 }, ...styles]; 57179 } 57180 57181 /** 57182 * Returns a style object from a collection of styles where that style object is the default block style. 57183 * 57184 * @param {Array} styles Block styles. 57185 * 57186 * @return {?Object} The default style object, if found. 57187 */ 57188 function getDefaultStyle(styles) { 57189 return styles?.find(style => style.isDefault); 57190 } 57191 57192 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-styles/use-styles-for-block.js 57193 /** 57194 * WordPress dependencies 57195 */ 57196 57197 57198 57199 57200 /** 57201 * Internal dependencies 57202 */ 57203 57204 57205 57206 /** 57207 * 57208 * @param {WPBlock} block Block object. 57209 * @param {WPBlockType} type Block type settings. 57210 * @return {WPBlock} A generic block ready for styles preview. 57211 */ 57212 function useGenericPreviewBlock(block, type) { 57213 return (0,external_wp_element_namespaceObject.useMemo)(() => { 57214 const example = type?.example; 57215 const blockName = type?.name; 57216 if (example && blockName) { 57217 return (0,external_wp_blocks_namespaceObject.getBlockFromExample)(blockName, { 57218 attributes: example.attributes, 57219 innerBlocks: example.innerBlocks 57220 }); 57221 } 57222 if (block) { 57223 return (0,external_wp_blocks_namespaceObject.cloneBlock)(block); 57224 } 57225 }, [type?.example ? block?.name : block, type]); 57226 } 57227 57228 /** 57229 * @typedef useStylesForBlocksArguments 57230 * @property {string} clientId Block client ID. 57231 * @property {() => void} onSwitch Block style switch callback function. 57232 */ 57233 57234 /** 57235 * 57236 * @param {useStylesForBlocksArguments} useStylesForBlocks arguments. 57237 * @return {Object} Results of the select methods. 57238 */ 57239 function useStylesForBlocks({ 57240 clientId, 57241 onSwitch 57242 }) { 57243 const selector = select => { 57244 const { 57245 getBlock 57246 } = select(store); 57247 const block = getBlock(clientId); 57248 if (!block) { 57249 return {}; 57250 } 57251 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(block.name); 57252 const { 57253 getBlockStyles 57254 } = select(external_wp_blocks_namespaceObject.store); 57255 return { 57256 block, 57257 blockType, 57258 styles: getBlockStyles(block.name), 57259 className: block.attributes.className || '' 57260 }; 57261 }; 57262 const { 57263 styles, 57264 block, 57265 blockType, 57266 className 57267 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId]); 57268 const { 57269 updateBlockAttributes 57270 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 57271 const stylesToRender = getRenderedStyles(styles); 57272 const activeStyle = getActiveStyle(stylesToRender, className); 57273 const genericPreviewBlock = useGenericPreviewBlock(block, blockType); 57274 const onSelect = style => { 57275 const styleClassName = replaceActiveStyle(className, activeStyle, style); 57276 updateBlockAttributes(clientId, { 57277 className: styleClassName 57278 }); 57279 onSwitch(); 57280 }; 57281 return { 57282 onSelect, 57283 stylesToRender, 57284 activeStyle, 57285 genericPreviewBlock, 57286 className 57287 }; 57288 } 57289 57290 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-styles/menu-items.js 57291 /** 57292 * WordPress dependencies 57293 */ 57294 57295 57296 57297 /** 57298 * Internal dependencies 57299 */ 57300 57301 57302 const menu_items_noop = () => {}; 57303 function BlockStylesMenuItems({ 57304 clientId, 57305 onSwitch = menu_items_noop 57306 }) { 57307 const { 57308 onSelect, 57309 stylesToRender, 57310 activeStyle 57311 } = useStylesForBlocks({ 57312 clientId, 57313 onSwitch 57314 }); 57315 if (!stylesToRender || stylesToRender.length === 0) { 57316 return null; 57317 } 57318 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 57319 children: stylesToRender.map(style => { 57320 const menuItemText = style.label || style.name; 57321 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 57322 icon: activeStyle.name === style.name ? library_check : null, 57323 onClick: () => onSelect(style), 57324 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 57325 as: "span", 57326 limit: 18, 57327 ellipsizeMode: "tail", 57328 truncate: true, 57329 children: menuItemText 57330 }) 57331 }, style.name); 57332 }) 57333 }); 57334 } 57335 57336 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/block-styles-menu.js 57337 /** 57338 * WordPress dependencies 57339 */ 57340 57341 57342 57343 /** 57344 * Internal dependencies 57345 */ 57346 57347 57348 function BlockStylesMenu({ 57349 hoveredBlock, 57350 onSwitch 57351 }) { 57352 const { 57353 clientId 57354 } = hoveredBlock; 57355 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 57356 label: (0,external_wp_i18n_namespaceObject.__)('Styles'), 57357 className: "block-editor-block-switcher__styles__menugroup", 57358 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockStylesMenuItems, { 57359 clientId: clientId, 57360 onSwitch: onSwitch 57361 }) 57362 }); 57363 } 57364 57365 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/utils.js 57366 /** 57367 * WordPress dependencies 57368 */ 57369 57370 57371 /** 57372 * Try to find a matching block by a block's name in a provided 57373 * block. We recurse through InnerBlocks and return the reference 57374 * of the matched block (it could be an InnerBlock). 57375 * If no match is found return nothing. 57376 * 57377 * @param {WPBlock} block The block to try to find a match. 57378 * @param {string} selectedBlockName The block's name to use for matching condition. 57379 * @param {Set} consumedBlocks A set holding the previously matched/consumed blocks. 57380 * 57381 * @return {WPBlock | undefined} The matched block if found or nothing(`undefined`). 57382 */ 57383 const getMatchingBlockByName = (block, selectedBlockName, consumedBlocks = new Set()) => { 57384 const { 57385 clientId, 57386 name, 57387 innerBlocks = [] 57388 } = block; 57389 // Check if block has been consumed already. 57390 if (consumedBlocks.has(clientId)) { 57391 return; 57392 } 57393 if (name === selectedBlockName) { 57394 return block; 57395 } 57396 // Try to find a matching block from InnerBlocks recursively. 57397 for (const innerBlock of innerBlocks) { 57398 const match = getMatchingBlockByName(innerBlock, selectedBlockName, consumedBlocks); 57399 if (match) { 57400 return match; 57401 } 57402 } 57403 }; 57404 57405 /** 57406 * Find and return the block attributes to retain through 57407 * the transformation, based on Block Type's `role:content` 57408 * attributes. If no `role:content` attributes exist, 57409 * return selected block's attributes. 57410 * 57411 * @param {string} name Block type's namespaced name. 57412 * @param {Object} attributes Selected block's attributes. 57413 * @return {Object} The block's attributes to retain. 57414 */ 57415 const getRetainedBlockAttributes = (name, attributes) => { 57416 const contentAttributes = (0,external_wp_blocks_namespaceObject.getBlockAttributesNamesByRole)(name, 'content'); 57417 if (!contentAttributes?.length) { 57418 return attributes; 57419 } 57420 return contentAttributes.reduce((_accumulator, attribute) => { 57421 if (attributes[attribute]) { 57422 _accumulator[attribute] = attributes[attribute]; 57423 } 57424 return _accumulator; 57425 }, {}); 57426 }; 57427 57428 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/use-transformed-patterns.js 57429 /** 57430 * WordPress dependencies 57431 */ 57432 57433 57434 57435 /** 57436 * Internal dependencies 57437 */ 57438 57439 57440 /** 57441 * Mutate the matched block's attributes by getting 57442 * which block type's attributes to retain and prioritize 57443 * them in the merging of the attributes. 57444 * 57445 * @param {WPBlock} match The matched block. 57446 * @param {WPBlock} selectedBlock The selected block. 57447 * @return {void} 57448 */ 57449 const transformMatchingBlock = (match, selectedBlock) => { 57450 // Get the block attributes to retain through the transformation. 57451 const retainedBlockAttributes = getRetainedBlockAttributes(selectedBlock.name, selectedBlock.attributes); 57452 match.attributes = { 57453 ...match.attributes, 57454 ...retainedBlockAttributes 57455 }; 57456 }; 57457 57458 /** 57459 * By providing the selected blocks and pattern's blocks 57460 * find the matching blocks, transform them and return them. 57461 * If not all selected blocks are matched, return nothing. 57462 * 57463 * @param {WPBlock[]} selectedBlocks The selected blocks. 57464 * @param {WPBlock[]} patternBlocks The pattern's blocks. 57465 * @return {WPBlock[]|void} The transformed pattern's blocks or undefined if not all selected blocks have been matched. 57466 */ 57467 const getPatternTransformedBlocks = (selectedBlocks, patternBlocks) => { 57468 // Clone Pattern's blocks to produce new clientIds and be able to mutate the matches. 57469 const _patternBlocks = patternBlocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 57470 /** 57471 * Keep track of the consumed pattern blocks. 57472 * This is needed because we loop the selected blocks 57473 * and for example we may have selected two paragraphs and 57474 * the pattern's blocks could have more `paragraphs`. 57475 */ 57476 const consumedBlocks = new Set(); 57477 for (const selectedBlock of selectedBlocks) { 57478 let isMatch = false; 57479 for (const patternBlock of _patternBlocks) { 57480 const match = getMatchingBlockByName(patternBlock, selectedBlock.name, consumedBlocks); 57481 if (!match) { 57482 continue; 57483 } 57484 isMatch = true; 57485 consumedBlocks.add(match.clientId); 57486 // We update (mutate) the matching pattern block. 57487 transformMatchingBlock(match, selectedBlock); 57488 // No need to loop through other pattern's blocks. 57489 break; 57490 } 57491 // Bail early if a selected block has not been matched. 57492 if (!isMatch) { 57493 return; 57494 } 57495 } 57496 return _patternBlocks; 57497 }; 57498 57499 /** 57500 * @typedef {WPBlockPattern & {transformedBlocks: WPBlock[]}} TransformedBlockPattern 57501 */ 57502 57503 /** 57504 * Custom hook that accepts patterns from state and the selected 57505 * blocks and tries to match these with the pattern's blocks. 57506 * If all selected blocks are matched with a Pattern's block, 57507 * we transform them by retaining block's attributes with `role:content`. 57508 * The transformed pattern's blocks are set to a new pattern 57509 * property `transformedBlocks`. 57510 * 57511 * @param {WPBlockPattern[]} patterns Patterns from state. 57512 * @param {WPBlock[]} selectedBlocks The currently selected blocks. 57513 * @return {TransformedBlockPattern[]} Returns the eligible matched patterns with all the selected blocks. 57514 */ 57515 const useTransformedPatterns = (patterns, selectedBlocks) => { 57516 return (0,external_wp_element_namespaceObject.useMemo)(() => patterns.reduce((accumulator, _pattern) => { 57517 const transformedBlocks = getPatternTransformedBlocks(selectedBlocks, _pattern.blocks); 57518 if (transformedBlocks) { 57519 accumulator.push({ 57520 ..._pattern, 57521 transformedBlocks 57522 }); 57523 } 57524 return accumulator; 57525 }, []), [patterns, selectedBlocks]); 57526 }; 57527 /* harmony default export */ const use_transformed_patterns = (useTransformedPatterns); 57528 57529 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/pattern-transformations-menu.js 57530 /** 57531 * WordPress dependencies 57532 */ 57533 57534 57535 57536 57537 57538 57539 /** 57540 * Internal dependencies 57541 */ 57542 57543 57544 57545 function PatternTransformationsMenu({ 57546 blocks, 57547 patterns: statePatterns, 57548 onSelect 57549 }) { 57550 const [showTransforms, setShowTransforms] = (0,external_wp_element_namespaceObject.useState)(false); 57551 const patterns = use_transformed_patterns(statePatterns, blocks); 57552 if (!patterns.length) { 57553 return null; 57554 } 57555 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 57556 className: "block-editor-block-switcher__pattern__transforms__menugroup", 57557 children: [showTransforms && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PreviewPatternsPopover, { 57558 patterns: patterns, 57559 onSelect: onSelect 57560 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 57561 onClick: event => { 57562 event.preventDefault(); 57563 setShowTransforms(!showTransforms); 57564 }, 57565 icon: chevron_right, 57566 children: (0,external_wp_i18n_namespaceObject.__)('Patterns') 57567 })] 57568 }); 57569 } 57570 function PreviewPatternsPopover({ 57571 patterns, 57572 onSelect 57573 }) { 57574 const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 57575 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 57576 className: "block-editor-block-switcher__popover-preview-container", 57577 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 57578 className: "block-editor-block-switcher__popover-preview", 57579 placement: isMobile ? 'bottom' : 'right-start', 57580 offset: 16, 57581 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 57582 className: "block-editor-block-switcher__preview is-pattern-list-preview", 57583 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(pattern_transformations_menu_BlockPatternsList, { 57584 patterns: patterns, 57585 onSelect: onSelect 57586 }) 57587 }) 57588 }) 57589 }); 57590 } 57591 function pattern_transformations_menu_BlockPatternsList({ 57592 patterns, 57593 onSelect 57594 }) { 57595 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite, { 57596 role: "listbox", 57597 className: "block-editor-block-switcher__preview-patterns-container", 57598 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Patterns list'), 57599 children: patterns.map(pattern => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(pattern_transformations_menu_BlockPattern, { 57600 pattern: pattern, 57601 onSelect: onSelect 57602 }, pattern.name)) 57603 }); 57604 } 57605 function pattern_transformations_menu_BlockPattern({ 57606 pattern, 57607 onSelect 57608 }) { 57609 // TODO check pattern/preview width... 57610 const baseClassName = 'block-editor-block-switcher__preview-patterns-container'; 57611 const descriptionId = (0,external_wp_compose_namespaceObject.useInstanceId)(pattern_transformations_menu_BlockPattern, `$baseClassName}-list__item-description`); 57612 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 57613 className: `$baseClassName}-list__list-item`, 57614 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Composite.Item, { 57615 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 57616 role: "option", 57617 "aria-label": pattern.title, 57618 "aria-describedby": pattern.description ? descriptionId : undefined, 57619 className: `$baseClassName}-list__item` 57620 }), 57621 onClick: () => onSelect(pattern.transformedBlocks), 57622 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview, { 57623 blocks: pattern.transformedBlocks, 57624 viewportWidth: pattern.viewportWidth || 500 57625 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 57626 className: `$baseClassName}-list__item-title`, 57627 children: pattern.title 57628 })] 57629 }), !!pattern.description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 57630 id: descriptionId, 57631 children: pattern.description 57632 })] 57633 }); 57634 } 57635 /* harmony default export */ const pattern_transformations_menu = (PatternTransformationsMenu); 57636 57637 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-switcher/index.js 57638 /** 57639 * WordPress dependencies 57640 */ 57641 57642 57643 57644 57645 57646 57647 57648 /** 57649 * Internal dependencies 57650 */ 57651 57652 57653 57654 57655 57656 57657 57658 57659 function BlockSwitcherDropdownMenuContents({ 57660 onClose, 57661 clientIds, 57662 hasBlockStyles, 57663 canRemove 57664 }) { 57665 const { 57666 replaceBlocks, 57667 multiSelect, 57668 updateBlockAttributes 57669 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 57670 const { 57671 possibleBlockTransformations, 57672 patterns, 57673 blocks, 57674 isUsingBindings 57675 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 57676 const { 57677 getBlockAttributes, 57678 getBlocksByClientId, 57679 getBlockRootClientId, 57680 getBlockTransformItems, 57681 __experimentalGetPatternTransformItems 57682 } = select(store); 57683 const rootClientId = getBlockRootClientId(clientIds[0]); 57684 const _blocks = getBlocksByClientId(clientIds); 57685 return { 57686 blocks: _blocks, 57687 possibleBlockTransformations: getBlockTransformItems(_blocks, rootClientId), 57688 patterns: __experimentalGetPatternTransformItems(_blocks, rootClientId), 57689 isUsingBindings: clientIds.every(clientId => !!getBlockAttributes(clientId)?.metadata?.bindings) 57690 }; 57691 }, [clientIds]); 57692 const blockVariationTransformations = useBlockVariationTransforms({ 57693 clientIds, 57694 blocks 57695 }); 57696 function selectForMultipleBlocks(insertedBlocks) { 57697 if (insertedBlocks.length > 1) { 57698 multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId); 57699 } 57700 } 57701 // Simple block transformation based on the `Block Transforms` API. 57702 function onBlockTransform(name) { 57703 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, name); 57704 replaceBlocks(clientIds, newBlocks); 57705 selectForMultipleBlocks(newBlocks); 57706 } 57707 function onBlockVariationTransform(name) { 57708 updateBlockAttributes(blocks[0].clientId, { 57709 ...blockVariationTransformations.find(({ 57710 name: variationName 57711 }) => variationName === name).attributes 57712 }); 57713 } 57714 // Pattern transformation through the `Patterns` API. 57715 function onPatternTransform(transformedBlocks) { 57716 replaceBlocks(clientIds, transformedBlocks); 57717 selectForMultipleBlocks(transformedBlocks); 57718 } 57719 /** 57720 * The `isTemplate` check is a stopgap solution here. 57721 * Ideally, the Transforms API should handle this 57722 * by allowing to exclude blocks from wildcard transformations. 57723 */ 57724 const isSingleBlock = blocks.length === 1; 57725 const isTemplate = isSingleBlock && (0,external_wp_blocks_namespaceObject.isTemplatePart)(blocks[0]); 57726 const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate; 57727 const hasPossibleBlockVariationTransformations = !!blockVariationTransformations?.length; 57728 const hasPatternTransformation = !!patterns?.length && canRemove; 57729 const hasBlockOrBlockVariationTransforms = hasPossibleBlockTransformations || hasPossibleBlockVariationTransformations; 57730 const hasContents = hasBlockStyles || hasBlockOrBlockVariationTransforms || hasPatternTransformation; 57731 if (!hasContents) { 57732 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 57733 className: "block-editor-block-switcher__no-transforms", 57734 children: (0,external_wp_i18n_namespaceObject.__)('No transforms.') 57735 }); 57736 } 57737 const connectedBlockDescription = isSingleBlock ? (0,external_wp_i18n_namespaceObject._x)('This block is connected.', 'block toolbar button label and description') : (0,external_wp_i18n_namespaceObject._x)('These blocks are connected.', 'block toolbar button label and description'); 57738 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 57739 className: "block-editor-block-switcher__container", 57740 children: [hasPatternTransformation && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(pattern_transformations_menu, { 57741 blocks: blocks, 57742 patterns: patterns, 57743 onSelect: transformedBlocks => { 57744 onPatternTransform(transformedBlocks); 57745 onClose(); 57746 } 57747 }), hasBlockOrBlockVariationTransforms && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_transformations_menu, { 57748 className: "block-editor-block-switcher__transforms__menugroup", 57749 possibleBlockTransformations: possibleBlockTransformations, 57750 possibleBlockVariationTransformations: blockVariationTransformations, 57751 blocks: blocks, 57752 onSelect: name => { 57753 onBlockTransform(name); 57754 onClose(); 57755 }, 57756 onSelectVariation: name => { 57757 onBlockVariationTransform(name); 57758 onClose(); 57759 } 57760 }), hasBlockStyles && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockStylesMenu, { 57761 hoveredBlock: blocks[0], 57762 onSwitch: onClose 57763 }), isUsingBindings && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 57764 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 57765 className: "block-editor-block-switcher__binding-indicator", 57766 children: connectedBlockDescription 57767 }) 57768 })] 57769 }); 57770 } 57771 const BlockSwitcher = ({ 57772 clientIds 57773 }) => { 57774 const { 57775 hasContentOnlyLocking, 57776 canRemove, 57777 hasBlockStyles, 57778 icon, 57779 invalidBlocks, 57780 isReusable, 57781 isTemplate, 57782 isDisabled 57783 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 57784 const { 57785 getTemplateLock, 57786 getBlocksByClientId, 57787 getBlockAttributes, 57788 canRemoveBlocks, 57789 getBlockEditingMode 57790 } = select(store); 57791 const { 57792 getBlockStyles, 57793 getBlockType, 57794 getActiveBlockVariation 57795 } = select(external_wp_blocks_namespaceObject.store); 57796 const _blocks = getBlocksByClientId(clientIds); 57797 if (!_blocks.length || _blocks.some(block => !block)) { 57798 return { 57799 invalidBlocks: true 57800 }; 57801 } 57802 const [{ 57803 name: firstBlockName 57804 }] = _blocks; 57805 const _isSingleBlockSelected = _blocks.length === 1; 57806 const blockType = getBlockType(firstBlockName); 57807 const editingMode = getBlockEditingMode(clientIds[0]); 57808 let _icon; 57809 let _hasTemplateLock; 57810 if (_isSingleBlockSelected) { 57811 const match = getActiveBlockVariation(firstBlockName, getBlockAttributes(clientIds[0])); 57812 // Take into account active block variations. 57813 _icon = match?.icon || blockType.icon; 57814 _hasTemplateLock = getTemplateLock(clientIds[0]) === 'contentOnly'; 57815 } else { 57816 const isSelectionOfSameType = new Set(_blocks.map(({ 57817 name 57818 }) => name)).size === 1; 57819 _hasTemplateLock = clientIds.some(id => getTemplateLock(id) === 'contentOnly'); 57820 // When selection consists of blocks of multiple types, display an 57821 // appropriate icon to communicate the non-uniformity. 57822 _icon = isSelectionOfSameType ? blockType.icon : library_copy; 57823 } 57824 return { 57825 canRemove: canRemoveBlocks(clientIds), 57826 hasBlockStyles: _isSingleBlockSelected && !!getBlockStyles(firstBlockName)?.length, 57827 icon: _icon, 57828 isReusable: _isSingleBlockSelected && (0,external_wp_blocks_namespaceObject.isReusableBlock)(_blocks[0]), 57829 isTemplate: _isSingleBlockSelected && (0,external_wp_blocks_namespaceObject.isTemplatePart)(_blocks[0]), 57830 hasContentOnlyLocking: _hasTemplateLock, 57831 isDisabled: editingMode !== 'default' 57832 }; 57833 }, [clientIds]); 57834 const blockTitle = useBlockDisplayTitle({ 57835 clientId: clientIds?.[0], 57836 maximumLength: 35 57837 }); 57838 const showIconLabels = (0,external_wp_data_namespaceObject.useSelect)(select => select(external_wp_preferences_namespaceObject.store).get('core', 'showIconLabels'), []); 57839 if (invalidBlocks) { 57840 return null; 57841 } 57842 const isSingleBlock = clientIds.length === 1; 57843 const blockSwitcherLabel = isSingleBlock ? blockTitle : (0,external_wp_i18n_namespaceObject.__)('Multiple blocks selected'); 57844 const blockIndicatorText = (isReusable || isTemplate) && !showIconLabels && blockTitle ? blockTitle : undefined; 57845 const hideDropdown = isDisabled || !hasBlockStyles && !canRemove || hasContentOnlyLocking; 57846 if (hideDropdown) { 57847 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 57848 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 57849 disabled: true, 57850 className: "block-editor-block-switcher__no-switcher-icon", 57851 title: blockSwitcherLabel, 57852 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 57853 className: "block-editor-block-switcher__toggle", 57854 icon: icon, 57855 showColors: true 57856 }), 57857 text: blockIndicatorText 57858 }) 57859 }); 57860 } 57861 const blockSwitcherDescription = isSingleBlock ? (0,external_wp_i18n_namespaceObject.__)('Change block type or style') : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of blocks. */ 57862 (0,external_wp_i18n_namespaceObject._n)('Change type of %d block', 'Change type of %d blocks', clientIds.length), clientIds.length); 57863 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 57864 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarItem, { 57865 children: toggleProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 57866 className: "block-editor-block-switcher", 57867 label: blockSwitcherLabel, 57868 popoverProps: { 57869 placement: 'bottom-start', 57870 className: 'block-editor-block-switcher__popover' 57871 }, 57872 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 57873 className: "block-editor-block-switcher__toggle", 57874 icon: icon, 57875 showColors: true 57876 }), 57877 text: blockIndicatorText, 57878 toggleProps: { 57879 description: blockSwitcherDescription, 57880 ...toggleProps 57881 }, 57882 menuProps: { 57883 orientation: 'both' 57884 }, 57885 children: ({ 57886 onClose 57887 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockSwitcherDropdownMenuContents, { 57888 onClose: onClose, 57889 clientIds: clientIds, 57890 hasBlockStyles: hasBlockStyles, 57891 canRemove: canRemove 57892 }) 57893 }) 57894 }) 57895 }); 57896 }; 57897 /* harmony default export */ const block_switcher = (BlockSwitcher); 57898 57899 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/block-toolbar-last-item.js 57900 /** 57901 * WordPress dependencies 57902 */ 57903 57904 const { 57905 Fill: __unstableBlockToolbarLastItem, 57906 Slot: block_toolbar_last_item_Slot 57907 } = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableBlockToolbarLastItem'); 57908 __unstableBlockToolbarLastItem.Slot = block_toolbar_last_item_Slot; 57909 /* harmony default export */ const block_toolbar_last_item = (__unstableBlockToolbarLastItem); 57910 57911 ;// ./node_modules/@wordpress/block-editor/build-module/hooks/supports.js 57912 /** 57913 * WordPress dependencies 57914 */ 57915 57916 57917 const ALIGN_SUPPORT_KEY = 'align'; 57918 const ALIGN_WIDE_SUPPORT_KEY = 'alignWide'; 57919 const supports_BORDER_SUPPORT_KEY = '__experimentalBorder'; 57920 const supports_COLOR_SUPPORT_KEY = 'color'; 57921 const CUSTOM_CLASS_NAME_SUPPORT_KEY = 'customClassName'; 57922 const supports_FONT_FAMILY_SUPPORT_KEY = 'typography.__experimentalFontFamily'; 57923 const supports_FONT_SIZE_SUPPORT_KEY = 'typography.fontSize'; 57924 const supports_LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; 57925 /** 57926 * Key within block settings' support array indicating support for font style. 57927 */ 57928 const supports_FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle'; 57929 /** 57930 * Key within block settings' support array indicating support for font weight. 57931 */ 57932 const supports_FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight'; 57933 /** 57934 * Key within block settings' supports array indicating support for text 57935 * align e.g. settings found in `block.json`. 57936 */ 57937 const supports_TEXT_ALIGN_SUPPORT_KEY = 'typography.textAlign'; 57938 /** 57939 * Key within block settings' supports array indicating support for text 57940 * columns e.g. settings found in `block.json`. 57941 */ 57942 const supports_TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns'; 57943 /** 57944 * Key within block settings' supports array indicating support for text 57945 * decorations e.g. settings found in `block.json`. 57946 */ 57947 const supports_TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration'; 57948 /** 57949 * Key within block settings' supports array indicating support for writing mode 57950 * e.g. settings found in `block.json`. 57951 */ 57952 const supports_WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode'; 57953 /** 57954 * Key within block settings' supports array indicating support for text 57955 * transforms e.g. settings found in `block.json`. 57956 */ 57957 const supports_TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform'; 57958 57959 /** 57960 * Key within block settings' supports array indicating support for letter-spacing 57961 * e.g. settings found in `block.json`. 57962 */ 57963 const supports_LETTER_SPACING_SUPPORT_KEY = 'typography.__experimentalLetterSpacing'; 57964 const LAYOUT_SUPPORT_KEY = 'layout'; 57965 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_ALIGN_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]; 57966 const EFFECTS_SUPPORT_KEYS = ['shadow']; 57967 const supports_SPACING_SUPPORT_KEY = 'spacing'; 57968 const supports_styleSupportKeys = [...EFFECTS_SUPPORT_KEYS, ...supports_TYPOGRAPHY_SUPPORT_KEYS, supports_BORDER_SUPPORT_KEY, supports_COLOR_SUPPORT_KEY, supports_SPACING_SUPPORT_KEY]; 57969 57970 /** 57971 * Returns true if the block defines support for align. 57972 * 57973 * @param {string|Object} nameOrType Block name or type object. 57974 * @return {boolean} Whether the block supports the feature. 57975 */ 57976 const hasAlignSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, ALIGN_SUPPORT_KEY); 57977 57978 /** 57979 * Returns the block support value for align, if defined. 57980 * 57981 * @param {string|Object} nameOrType Block name or type object. 57982 * @return {unknown} The block support value. 57983 */ 57984 const getAlignSupport = nameOrType => getBlockSupport(nameOrType, ALIGN_SUPPORT_KEY); 57985 57986 /** 57987 * Returns true if the block defines support for align wide. 57988 * 57989 * @param {string|Object} nameOrType Block name or type object. 57990 * @return {boolean} Whether the block supports the feature. 57991 */ 57992 const hasAlignWideSupport = nameOrType => hasBlockSupport(nameOrType, ALIGN_WIDE_SUPPORT_KEY); 57993 57994 /** 57995 * Returns the block support value for align wide, if defined. 57996 * 57997 * @param {string|Object} nameOrType Block name or type object. 57998 * @return {unknown} The block support value. 57999 */ 58000 const getAlignWideSupport = nameOrType => getBlockSupport(nameOrType, ALIGN_WIDE_SUPPORT_KEY); 58001 58002 /** 58003 * Determine whether there is block support for border properties. 58004 * 58005 * @param {string|Object} nameOrType Block name or type object. 58006 * @param {string} feature Border feature to check support for. 58007 * 58008 * @return {boolean} Whether there is support. 58009 */ 58010 function supports_hasBorderSupport(nameOrType, feature = 'any') { 58011 if (external_wp_element_namespaceObject.Platform.OS !== 'web') { 58012 return false; 58013 } 58014 const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_BORDER_SUPPORT_KEY); 58015 if (support === true) { 58016 return true; 58017 } 58018 if (feature === 'any') { 58019 return !!(support?.color || support?.radius || support?.width || support?.style); 58020 } 58021 return !!support?.[feature]; 58022 } 58023 58024 /** 58025 * Get block support for border properties. 58026 * 58027 * @param {string|Object} nameOrType Block name or type object. 58028 * @param {string} feature Border feature to get. 58029 * 58030 * @return {unknown} The block support. 58031 */ 58032 const getBorderSupport = (nameOrType, feature) => getBlockSupport(nameOrType, [supports_BORDER_SUPPORT_KEY, feature]); 58033 58034 /** 58035 * Returns true if the block defines support for color. 58036 * 58037 * @param {string|Object} nameOrType Block name or type object. 58038 * @return {boolean} Whether the block supports the feature. 58039 */ 58040 const supports_hasColorSupport = nameOrType => { 58041 const colorSupport = getBlockSupport(nameOrType, supports_COLOR_SUPPORT_KEY); 58042 return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false); 58043 }; 58044 58045 /** 58046 * Returns true if the block defines support for link color. 58047 * 58048 * @param {string|Object} nameOrType Block name or type object. 58049 * @return {boolean} Whether the block supports the feature. 58050 */ 58051 const supports_hasLinkColorSupport = nameOrType => { 58052 if (Platform.OS !== 'web') { 58053 return false; 58054 } 58055 const colorSupport = getBlockSupport(nameOrType, supports_COLOR_SUPPORT_KEY); 58056 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link; 58057 }; 58058 58059 /** 58060 * Returns true if the block defines support for gradient color. 58061 * 58062 * @param {string|Object} nameOrType Block name or type object. 58063 * @return {boolean} Whether the block supports the feature. 58064 */ 58065 const supports_hasGradientSupport = nameOrType => { 58066 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_COLOR_SUPPORT_KEY); 58067 return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients; 58068 }; 58069 58070 /** 58071 * Returns true if the block defines support for background color. 58072 * 58073 * @param {string|Object} nameOrType Block name or type object. 58074 * @return {boolean} Whether the block supports the feature. 58075 */ 58076 const supports_hasBackgroundColorSupport = nameOrType => { 58077 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_COLOR_SUPPORT_KEY); 58078 return colorSupport && colorSupport.background !== false; 58079 }; 58080 58081 /** 58082 * Returns true if the block defines support for text-align. 58083 * 58084 * @param {string|Object} nameOrType Block name or type object. 58085 * @return {boolean} Whether the block supports the feature. 58086 */ 58087 const hasTextAlignSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, supports_TEXT_ALIGN_SUPPORT_KEY); 58088 58089 /** 58090 * Returns the block support value for text-align, if defined. 58091 * 58092 * @param {string|Object} nameOrType Block name or type object. 58093 * @return {unknown} The block support value. 58094 */ 58095 const getTextAlignSupport = nameOrType => getBlockSupport(nameOrType, supports_TEXT_ALIGN_SUPPORT_KEY); 58096 58097 /** 58098 * Returns true if the block defines support for background color. 58099 * 58100 * @param {string|Object} nameOrType Block name or type object. 58101 * @return {boolean} Whether the block supports the feature. 58102 */ 58103 const supports_hasTextColorSupport = nameOrType => { 58104 const colorSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(nameOrType, supports_COLOR_SUPPORT_KEY); 58105 return colorSupport && colorSupport.text !== false; 58106 }; 58107 58108 /** 58109 * Get block support for color properties. 58110 * 58111 * @param {string|Object} nameOrType Block name or type object. 58112 * @param {string} feature Color feature to get. 58113 * 58114 * @return {unknown} The block support. 58115 */ 58116 const getColorSupport = (nameOrType, feature) => getBlockSupport(nameOrType, [supports_COLOR_SUPPORT_KEY, feature]); 58117 58118 /** 58119 * Returns true if the block defines support for custom class name. 58120 * 58121 * @param {string|Object} nameOrType Block name or type object. 58122 * @return {boolean} Whether the block supports the feature. 58123 */ 58124 const hasCustomClassNameSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, CUSTOM_CLASS_NAME_SUPPORT_KEY, true); 58125 58126 /** 58127 * Returns the block support value for custom class name, if defined. 58128 * 58129 * @param {string|Object} nameOrType Block name or type object. 58130 * @return {unknown} The block support value. 58131 */ 58132 const getCustomClassNameSupport = nameOrType => getBlockSupport(nameOrType, CUSTOM_CLASS_NAME_SUPPORT_KEY, true); 58133 58134 /** 58135 * Returns true if the block defines support for font family. 58136 * 58137 * @param {string|Object} nameOrType Block name or type object. 58138 * @return {boolean} Whether the block supports the feature. 58139 */ 58140 const hasFontFamilySupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, supports_FONT_FAMILY_SUPPORT_KEY); 58141 58142 /** 58143 * Returns the block support value for font family, if defined. 58144 * 58145 * @param {string|Object} nameOrType Block name or type object. 58146 * @return {unknown} The block support value. 58147 */ 58148 const getFontFamilySupport = nameOrType => getBlockSupport(nameOrType, supports_FONT_FAMILY_SUPPORT_KEY); 58149 58150 /** 58151 * Returns true if the block defines support for font size. 58152 * 58153 * @param {string|Object} nameOrType Block name or type object. 58154 * @return {boolean} Whether the block supports the feature. 58155 */ 58156 const hasFontSizeSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, supports_FONT_SIZE_SUPPORT_KEY); 58157 58158 /** 58159 * Returns the block support value for font size, if defined. 58160 * 58161 * @param {string|Object} nameOrType Block name or type object. 58162 * @return {unknown} The block support value. 58163 */ 58164 const getFontSizeSupport = nameOrType => getBlockSupport(nameOrType, supports_FONT_SIZE_SUPPORT_KEY); 58165 58166 /** 58167 * Returns true if the block defines support for layout. 58168 * 58169 * @param {string|Object} nameOrType Block name or type object. 58170 * @return {boolean} Whether the block supports the feature. 58171 */ 58172 const hasLayoutSupport = nameOrType => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, LAYOUT_SUPPORT_KEY); 58173 58174 /** 58175 * Returns the block support value for layout, if defined. 58176 * 58177 * @param {string|Object} nameOrType Block name or type object. 58178 * @return {unknown} The block support value. 58179 */ 58180 const getLayoutSupport = nameOrType => getBlockSupport(nameOrType, LAYOUT_SUPPORT_KEY); 58181 58182 /** 58183 * Returns true if the block defines support for style. 58184 * 58185 * @param {string|Object} nameOrType Block name or type object. 58186 * @return {boolean} Whether the block supports the feature. 58187 */ 58188 const supports_hasStyleSupport = nameOrType => supports_styleSupportKeys.some(key => (0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, key)); 58189 58190 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-paste-styles/index.js 58191 /** 58192 * WordPress dependencies 58193 */ 58194 58195 58196 58197 58198 58199 58200 /** 58201 * Internal dependencies 58202 */ 58203 58204 58205 58206 /** 58207 * Determine if the copied text looks like serialized blocks or not. 58208 * Since plain text will always get parsed into a freeform block, 58209 * we check that if the parsed blocks is anything other than that. 58210 * 58211 * @param {string} text The copied text. 58212 * @return {boolean} True if the text looks like serialized blocks, false otherwise. 58213 */ 58214 function hasSerializedBlocks(text) { 58215 try { 58216 const blocks = (0,external_wp_blocks_namespaceObject.parse)(text, { 58217 __unstableSkipMigrationLogs: true, 58218 __unstableSkipAutop: true 58219 }); 58220 if (blocks.length === 1 && blocks[0].name === 'core/freeform') { 58221 // It's likely that the text is just plain text and not serialized blocks. 58222 return false; 58223 } 58224 return true; 58225 } catch (err) { 58226 // Parsing error, the text is not serialized blocks. 58227 // (Even though that it technically won't happen) 58228 return false; 58229 } 58230 } 58231 58232 /** 58233 * Style attributes are attributes being added in `block-editor/src/hooks/*`. 58234 * (Except for some unrelated to style like `anchor` or `settings`.) 58235 * They generally represent the default block supports. 58236 */ 58237 const STYLE_ATTRIBUTES = { 58238 align: hasAlignSupport, 58239 borderColor: nameOrType => supports_hasBorderSupport(nameOrType, 'color'), 58240 backgroundColor: supports_hasBackgroundColorSupport, 58241 textAlign: hasTextAlignSupport, 58242 textColor: supports_hasTextColorSupport, 58243 gradient: supports_hasGradientSupport, 58244 className: hasCustomClassNameSupport, 58245 fontFamily: hasFontFamilySupport, 58246 fontSize: hasFontSizeSupport, 58247 layout: hasLayoutSupport, 58248 style: supports_hasStyleSupport 58249 }; 58250 58251 /** 58252 * Get the "style attributes" from a given block to a target block. 58253 * 58254 * @param {WPBlock} sourceBlock The source block. 58255 * @param {WPBlock} targetBlock The target block. 58256 * @return {Object} the filtered attributes object. 58257 */ 58258 function getStyleAttributes(sourceBlock, targetBlock) { 58259 return Object.entries(STYLE_ATTRIBUTES).reduce((attributes, [attributeKey, hasSupport]) => { 58260 // Only apply the attribute if both blocks support it. 58261 if (hasSupport(sourceBlock.name) && hasSupport(targetBlock.name)) { 58262 // Override attributes that are not present in the block to their defaults. 58263 attributes[attributeKey] = sourceBlock.attributes[attributeKey]; 58264 } 58265 return attributes; 58266 }, {}); 58267 } 58268 58269 /** 58270 * Update the target blocks with style attributes recursively. 58271 * 58272 * @param {WPBlock[]} targetBlocks The target blocks to be updated. 58273 * @param {WPBlock[]} sourceBlocks The source blocks to get th style attributes from. 58274 * @param {Function} updateBlockAttributes The function to update the attributes. 58275 */ 58276 function recursivelyUpdateBlockAttributes(targetBlocks, sourceBlocks, updateBlockAttributes) { 58277 for (let index = 0; index < Math.min(sourceBlocks.length, targetBlocks.length); index += 1) { 58278 updateBlockAttributes(targetBlocks[index].clientId, getStyleAttributes(sourceBlocks[index], targetBlocks[index])); 58279 recursivelyUpdateBlockAttributes(targetBlocks[index].innerBlocks, sourceBlocks[index].innerBlocks, updateBlockAttributes); 58280 } 58281 } 58282 58283 /** 58284 * A hook to return a pasteStyles event function for handling pasting styles to blocks. 58285 * 58286 * @return {Function} A function to update the styles to the blocks. 58287 */ 58288 function usePasteStyles() { 58289 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 58290 const { 58291 updateBlockAttributes 58292 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58293 const { 58294 createSuccessNotice, 58295 createWarningNotice, 58296 createErrorNotice 58297 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 58298 return (0,external_wp_element_namespaceObject.useCallback)(async targetBlocks => { 58299 let html = ''; 58300 try { 58301 // `http:` sites won't have the clipboard property on navigator. 58302 // (with the exception of localhost.) 58303 if (!window.navigator.clipboard) { 58304 createErrorNotice((0,external_wp_i18n_namespaceObject.__)('Unable to paste styles. This feature is only available on secure (https) sites in supporting browsers.'), { 58305 type: 'snackbar' 58306 }); 58307 return; 58308 } 58309 html = await window.navigator.clipboard.readText(); 58310 } catch (error) { 58311 // Possibly the permission is denied. 58312 createErrorNotice((0,external_wp_i18n_namespaceObject.__)('Unable to paste styles. Please allow browser clipboard permissions before continuing.'), { 58313 type: 'snackbar' 58314 }); 58315 return; 58316 } 58317 58318 // Abort if the copied text is empty or doesn't look like serialized blocks. 58319 if (!html || !hasSerializedBlocks(html)) { 58320 createWarningNotice((0,external_wp_i18n_namespaceObject.__)("Unable to paste styles. Block styles couldn't be found within the copied content."), { 58321 type: 'snackbar' 58322 }); 58323 return; 58324 } 58325 const copiedBlocks = (0,external_wp_blocks_namespaceObject.parse)(html); 58326 if (copiedBlocks.length === 1) { 58327 // Apply styles of the block to all the target blocks. 58328 registry.batch(() => { 58329 recursivelyUpdateBlockAttributes(targetBlocks, targetBlocks.map(() => copiedBlocks[0]), updateBlockAttributes); 58330 }); 58331 } else { 58332 registry.batch(() => { 58333 recursivelyUpdateBlockAttributes(targetBlocks, copiedBlocks, updateBlockAttributes); 58334 }); 58335 } 58336 if (targetBlocks.length === 1) { 58337 const title = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlocks[0].name)?.title; 58338 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)( 58339 // Translators: Name of the block being pasted, e.g. "Paragraph". 58340 (0,external_wp_i18n_namespaceObject.__)('Pasted styles to %s.'), title), { 58341 type: 'snackbar' 58342 }); 58343 } else { 58344 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)( 58345 // Translators: The number of the blocks. 58346 (0,external_wp_i18n_namespaceObject.__)('Pasted styles to %d blocks.'), targetBlocks.length), { 58347 type: 'snackbar' 58348 }); 58349 } 58350 }, [registry.batch, updateBlockAttributes, createSuccessNotice, createWarningNotice, createErrorNotice]); 58351 } 58352 58353 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-actions/index.js 58354 /** 58355 * WordPress dependencies 58356 */ 58357 58358 58359 58360 /** 58361 * Internal dependencies 58362 */ 58363 58364 58365 function BlockActions({ 58366 clientIds, 58367 children, 58368 __experimentalUpdateSelection: updateSelection 58369 }) { 58370 const { 58371 getDefaultBlockName, 58372 getGroupingBlockName 58373 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 58374 const selected = (0,external_wp_data_namespaceObject.useSelect)(select => { 58375 const { 58376 canInsertBlockType, 58377 getBlockRootClientId, 58378 getBlocksByClientId, 58379 getDirectInsertBlock, 58380 canRemoveBlocks 58381 } = select(store); 58382 const blocks = getBlocksByClientId(clientIds); 58383 const rootClientId = getBlockRootClientId(clientIds[0]); 58384 const canInsertDefaultBlock = canInsertBlockType(getDefaultBlockName(), rootClientId); 58385 const directInsertBlock = rootClientId ? getDirectInsertBlock(rootClientId) : null; 58386 return { 58387 canRemove: canRemoveBlocks(clientIds), 58388 canInsertBlock: canInsertDefaultBlock || !!directInsertBlock, 58389 canCopyStyles: blocks.every(block => { 58390 return !!block && ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'color') || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'typography')); 58391 }), 58392 canDuplicate: blocks.every(block => { 58393 return !!block && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'multiple', true) && canInsertBlockType(block.name, rootClientId); 58394 }) 58395 }; 58396 }, [clientIds, getDefaultBlockName]); 58397 const { 58398 getBlocksByClientId, 58399 getBlocks 58400 } = (0,external_wp_data_namespaceObject.useSelect)(store); 58401 const { 58402 canRemove, 58403 canInsertBlock, 58404 canCopyStyles, 58405 canDuplicate 58406 } = selected; 58407 const { 58408 removeBlocks, 58409 replaceBlocks, 58410 duplicateBlocks, 58411 insertAfterBlock, 58412 insertBeforeBlock, 58413 flashBlock 58414 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58415 const pasteStyles = usePasteStyles(); 58416 return children({ 58417 canCopyStyles, 58418 canDuplicate, 58419 canInsertBlock, 58420 canRemove, 58421 onDuplicate() { 58422 return duplicateBlocks(clientIds, updateSelection); 58423 }, 58424 onRemove() { 58425 return removeBlocks(clientIds, updateSelection); 58426 }, 58427 onInsertBefore() { 58428 insertBeforeBlock(clientIds[0]); 58429 }, 58430 onInsertAfter() { 58431 insertAfterBlock(clientIds[clientIds.length - 1]); 58432 }, 58433 onGroup() { 58434 if (!clientIds.length) { 58435 return; 58436 } 58437 const groupingBlockName = getGroupingBlockName(); 58438 58439 // Activate the `transform` on `core/group` which does the conversion. 58440 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(getBlocksByClientId(clientIds), groupingBlockName); 58441 if (!newBlocks) { 58442 return; 58443 } 58444 replaceBlocks(clientIds, newBlocks); 58445 }, 58446 onUngroup() { 58447 if (!clientIds.length) { 58448 return; 58449 } 58450 const innerBlocks = getBlocks(clientIds[0]); 58451 if (!innerBlocks.length) { 58452 return; 58453 } 58454 replaceBlocks(clientIds, innerBlocks); 58455 }, 58456 onCopy() { 58457 if (clientIds.length === 1) { 58458 flashBlock(clientIds[0]); 58459 } 58460 }, 58461 async onPasteStyles() { 58462 await pasteStyles(getBlocksByClientId(clientIds)); 58463 } 58464 }); 58465 } 58466 58467 ;// ./node_modules/@wordpress/block-editor/build-module/components/collab/block-comment-icon-slot.js 58468 /** 58469 * WordPress dependencies 58470 */ 58471 58472 const CommentIconSlotFill = (0,external_wp_components_namespaceObject.createSlotFill)(Symbol('CommentIconSlotFill')); 58473 /* harmony default export */ const block_comment_icon_slot = (CommentIconSlotFill); 58474 58475 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-html-convert-button.js 58476 /** 58477 * WordPress dependencies 58478 */ 58479 58480 58481 58482 58483 58484 /** 58485 * Internal dependencies 58486 */ 58487 58488 58489 function BlockHTMLConvertButton({ 58490 clientId 58491 }) { 58492 const block = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlock(clientId), [clientId]); 58493 const { 58494 replaceBlocks 58495 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58496 if (!block || block.name !== 'core/html') { 58497 return null; 58498 } 58499 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 58500 onClick: () => replaceBlocks(clientId, (0,external_wp_blocks_namespaceObject.rawHandler)({ 58501 HTML: (0,external_wp_blocks_namespaceObject.getBlockContent)(block) 58502 })), 58503 children: (0,external_wp_i18n_namespaceObject.__)('Convert to Blocks') 58504 }); 58505 } 58506 /* harmony default export */ const block_html_convert_button = (BlockHTMLConvertButton); 58507 58508 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-settings-menu-first-item.js 58509 /** 58510 * WordPress dependencies 58511 */ 58512 58513 const { 58514 Fill: __unstableBlockSettingsMenuFirstItem, 58515 Slot: block_settings_menu_first_item_Slot 58516 } = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableBlockSettingsMenuFirstItem'); 58517 __unstableBlockSettingsMenuFirstItem.Slot = block_settings_menu_first_item_Slot; 58518 /* harmony default export */ const block_settings_menu_first_item = (__unstableBlockSettingsMenuFirstItem); 58519 58520 ;// ./node_modules/@wordpress/block-editor/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js 58521 /** 58522 * WordPress dependencies 58523 */ 58524 58525 58526 58527 /** 58528 * Internal dependencies 58529 */ 58530 58531 58532 /** 58533 * Contains the properties `ConvertToGroupButton` component needs. 58534 * 58535 * @typedef {Object} ConvertToGroupButtonProps 58536 * @property {string[]} clientIds An array of the selected client ids. 58537 * @property {boolean} isGroupable Indicates if the selected blocks can be grouped. 58538 * @property {boolean} isUngroupable Indicates if the selected blocks can be ungrouped. 58539 * @property {WPBlock[]} blocksSelection An array of the selected blocks. 58540 * @property {string} groupingBlockName The name of block used for handling grouping interactions. 58541 */ 58542 58543 /** 58544 * Returns the properties `ConvertToGroupButton` component needs to work properly. 58545 * It is used in `BlockSettingsMenuControls` to know if `ConvertToGroupButton` 58546 * should be rendered, to avoid ending up with an empty MenuGroup. 58547 * 58548 * @param {?string[]} selectedClientIds An optional array of clientIds to group. The selected blocks 58549 * from the block editor store are used if this is not provided. 58550 * 58551 * @return {ConvertToGroupButtonProps} Returns the properties needed by `ConvertToGroupButton`. 58552 */ 58553 function useConvertToGroupButtonProps(selectedClientIds) { 58554 return (0,external_wp_data_namespaceObject.useSelect)(select => { 58555 const { 58556 getBlocksByClientId, 58557 getSelectedBlockClientIds, 58558 isUngroupable, 58559 isGroupable 58560 } = select(store); 58561 const { 58562 getGroupingBlockName, 58563 getBlockType 58564 } = select(external_wp_blocks_namespaceObject.store); 58565 const clientIds = selectedClientIds?.length ? selectedClientIds : getSelectedBlockClientIds(); 58566 const blocksSelection = getBlocksByClientId(clientIds); 58567 const [firstSelectedBlock] = blocksSelection; 58568 const _isUngroupable = clientIds.length === 1 && isUngroupable(clientIds[0]); 58569 return { 58570 clientIds, 58571 isGroupable: isGroupable(clientIds), 58572 isUngroupable: _isUngroupable, 58573 blocksSelection, 58574 groupingBlockName: getGroupingBlockName(), 58575 onUngroup: _isUngroupable && getBlockType(firstSelectedBlock.name)?.transforms?.ungroup 58576 }; 58577 }, [selectedClientIds]); 58578 } 58579 58580 ;// ./node_modules/@wordpress/block-editor/build-module/components/convert-to-group-buttons/index.js 58581 /** 58582 * WordPress dependencies 58583 */ 58584 58585 58586 58587 58588 58589 58590 /** 58591 * Internal dependencies 58592 */ 58593 58594 58595 58596 58597 function ConvertToGroupButton({ 58598 clientIds, 58599 isGroupable, 58600 isUngroupable, 58601 onUngroup, 58602 blocksSelection, 58603 groupingBlockName, 58604 onClose = () => {} 58605 }) { 58606 const { 58607 getSelectedBlockClientIds 58608 } = (0,external_wp_data_namespaceObject.useSelect)(store); 58609 const { 58610 replaceBlocks 58611 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58612 const onConvertToGroup = () => { 58613 // Activate the `transform` on the Grouping Block which does the conversion. 58614 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocksSelection, groupingBlockName); 58615 if (newBlocks) { 58616 replaceBlocks(clientIds, newBlocks); 58617 } 58618 }; 58619 const onConvertFromGroup = () => { 58620 let innerBlocks = blocksSelection[0].innerBlocks; 58621 if (!innerBlocks.length) { 58622 return; 58623 } 58624 if (onUngroup) { 58625 innerBlocks = onUngroup(blocksSelection[0].attributes, blocksSelection[0].innerBlocks); 58626 } 58627 replaceBlocks(clientIds, innerBlocks); 58628 }; 58629 if (!isGroupable && !isUngroupable) { 58630 return null; 58631 } 58632 const selectedBlockClientIds = getSelectedBlockClientIds(); 58633 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 58634 children: [isGroupable && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 58635 shortcut: selectedBlockClientIds.length > 1 ? external_wp_keycodes_namespaceObject.displayShortcut.primary('g') : undefined, 58636 onClick: () => { 58637 onConvertToGroup(); 58638 onClose(); 58639 }, 58640 children: (0,external_wp_i18n_namespaceObject._x)('Group', 'verb') 58641 }), isUngroupable && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 58642 onClick: () => { 58643 onConvertFromGroup(); 58644 onClose(); 58645 }, 58646 children: (0,external_wp_i18n_namespaceObject._x)('Ungroup', 'Ungrouping blocks from within a grouping block back into individual blocks within the Editor') 58647 })] 58648 }); 58649 } 58650 58651 58652 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-lock/use-block-lock.js 58653 /** 58654 * WordPress dependencies 58655 */ 58656 58657 58658 /** 58659 * Internal dependencies 58660 */ 58661 58662 58663 /** 58664 * Return details about the block lock status. 58665 * 58666 * @param {string} clientId The block client Id. 58667 * 58668 * @return {Object} Block lock status 58669 */ 58670 function useBlockLock(clientId) { 58671 return (0,external_wp_data_namespaceObject.useSelect)(select => { 58672 const { 58673 canEditBlock, 58674 canMoveBlock, 58675 canRemoveBlock, 58676 canLockBlockType, 58677 getBlockName, 58678 getTemplateLock 58679 } = select(store); 58680 const canEdit = canEditBlock(clientId); 58681 const canMove = canMoveBlock(clientId); 58682 const canRemove = canRemoveBlock(clientId); 58683 return { 58684 canEdit, 58685 canMove, 58686 canRemove, 58687 canLock: canLockBlockType(getBlockName(clientId)), 58688 isContentLocked: getTemplateLock(clientId) === 'contentOnly', 58689 isLocked: !canEdit || !canMove || !canRemove 58690 }; 58691 }, [clientId]); 58692 } 58693 58694 ;// ./node_modules/@wordpress/icons/build-module/library/unlock.js 58695 /** 58696 * WordPress dependencies 58697 */ 58698 58699 58700 const unlock_unlock = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 58701 viewBox: "0 0 24 24", 58702 xmlns: "http://www.w3.org/2000/svg", 58703 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 58704 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" 58705 }) 58706 }); 58707 /* harmony default export */ const library_unlock = (unlock_unlock); 58708 58709 ;// ./node_modules/@wordpress/icons/build-module/library/lock-outline.js 58710 /** 58711 * WordPress dependencies 58712 */ 58713 58714 58715 const lockOutline = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 58716 viewBox: "0 0 24 24", 58717 xmlns: "http://www.w3.org/2000/svg", 58718 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 58719 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" 58720 }) 58721 }); 58722 /* harmony default export */ const lock_outline = (lockOutline); 58723 58724 ;// ./node_modules/@wordpress/icons/build-module/library/lock.js 58725 /** 58726 * WordPress dependencies 58727 */ 58728 58729 58730 const lock_lock = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 58731 viewBox: "0 0 24 24", 58732 xmlns: "http://www.w3.org/2000/svg", 58733 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 58734 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" 58735 }) 58736 }); 58737 /* harmony default export */ const library_lock = (lock_lock); 58738 58739 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-lock/modal.js 58740 /** 58741 * WordPress dependencies 58742 */ 58743 58744 58745 58746 58747 58748 58749 58750 /** 58751 * Internal dependencies 58752 */ 58753 58754 58755 58756 58757 // Entity based blocks which allow edit locking 58758 58759 const ALLOWS_EDIT_LOCKING = ['core/navigation']; 58760 function getTemplateLockValue(lock) { 58761 // Prevents all operations. 58762 if (lock.remove && lock.move) { 58763 return 'all'; 58764 } 58765 58766 // Prevents inserting or removing blocks, but allows moving existing blocks. 58767 if (lock.remove && !lock.move) { 58768 return 'insert'; 58769 } 58770 return false; 58771 } 58772 function BlockLockModal({ 58773 clientId, 58774 onClose 58775 }) { 58776 const [lock, setLock] = (0,external_wp_element_namespaceObject.useState)({ 58777 move: false, 58778 remove: false 58779 }); 58780 const { 58781 canEdit, 58782 canMove, 58783 canRemove 58784 } = useBlockLock(clientId); 58785 const { 58786 allowsEditLocking, 58787 templateLock, 58788 hasTemplateLock 58789 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 58790 const { 58791 getBlockName, 58792 getBlockAttributes 58793 } = select(store); 58794 const blockName = getBlockName(clientId); 58795 const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName); 58796 return { 58797 allowsEditLocking: ALLOWS_EDIT_LOCKING.includes(blockName), 58798 templateLock: getBlockAttributes(clientId)?.templateLock, 58799 hasTemplateLock: !!blockType?.attributes?.templateLock 58800 }; 58801 }, [clientId]); 58802 const [applyTemplateLock, setApplyTemplateLock] = (0,external_wp_element_namespaceObject.useState)(!!templateLock); 58803 const { 58804 updateBlockAttributes 58805 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 58806 const blockInformation = useBlockDisplayInformation(clientId); 58807 (0,external_wp_element_namespaceObject.useEffect)(() => { 58808 setLock({ 58809 move: !canMove, 58810 remove: !canRemove, 58811 ...(allowsEditLocking ? { 58812 edit: !canEdit 58813 } : {}) 58814 }); 58815 }, [canEdit, canMove, canRemove, allowsEditLocking]); 58816 const isAllChecked = Object.values(lock).every(Boolean); 58817 const isMixed = Object.values(lock).some(Boolean) && !isAllChecked; 58818 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Modal, { 58819 title: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Name of the block. */ 58820 (0,external_wp_i18n_namespaceObject.__)('Lock %s'), blockInformation.title), 58821 overlayClassName: "block-editor-block-lock-modal", 58822 onRequestClose: onClose, 58823 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("form", { 58824 onSubmit: event => { 58825 event.preventDefault(); 58826 updateBlockAttributes([clientId], { 58827 lock, 58828 templateLock: applyTemplateLock ? getTemplateLockValue(lock) : undefined 58829 }); 58830 onClose(); 58831 }, 58832 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 58833 className: "block-editor-block-lock-modal__options", 58834 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("legend", { 58835 children: (0,external_wp_i18n_namespaceObject.__)('Select the features you want to lock') 58836 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("ul", { 58837 role: "list", 58838 className: "block-editor-block-lock-modal__checklist", 58839 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 58840 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 58841 __nextHasNoMarginBottom: true, 58842 className: "block-editor-block-lock-modal__options-all", 58843 label: (0,external_wp_i18n_namespaceObject.__)('Lock all'), 58844 checked: isAllChecked, 58845 indeterminate: isMixed, 58846 onChange: newValue => setLock({ 58847 move: newValue, 58848 remove: newValue, 58849 ...(allowsEditLocking ? { 58850 edit: newValue 58851 } : {}) 58852 }) 58853 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("ul", { 58854 role: "list", 58855 className: "block-editor-block-lock-modal__checklist", 58856 children: [allowsEditLocking && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 58857 className: "block-editor-block-lock-modal__checklist-item", 58858 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 58859 __nextHasNoMarginBottom: true, 58860 label: (0,external_wp_i18n_namespaceObject.__)('Lock editing'), 58861 checked: !!lock.edit, 58862 onChange: edit => setLock(prevLock => ({ 58863 ...prevLock, 58864 edit 58865 })) 58866 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 58867 className: "block-editor-block-lock-modal__lock-icon", 58868 icon: lock.edit ? library_lock : library_unlock 58869 })] 58870 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 58871 className: "block-editor-block-lock-modal__checklist-item", 58872 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 58873 __nextHasNoMarginBottom: true, 58874 label: (0,external_wp_i18n_namespaceObject.__)('Lock movement'), 58875 checked: lock.move, 58876 onChange: move => setLock(prevLock => ({ 58877 ...prevLock, 58878 move 58879 })) 58880 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 58881 className: "block-editor-block-lock-modal__lock-icon", 58882 icon: lock.move ? library_lock : library_unlock 58883 })] 58884 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 58885 className: "block-editor-block-lock-modal__checklist-item", 58886 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 58887 __nextHasNoMarginBottom: true, 58888 label: (0,external_wp_i18n_namespaceObject.__)('Lock removal'), 58889 checked: lock.remove, 58890 onChange: remove => setLock(prevLock => ({ 58891 ...prevLock, 58892 remove 58893 })) 58894 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 58895 className: "block-editor-block-lock-modal__lock-icon", 58896 icon: lock.remove ? library_lock : library_unlock 58897 })] 58898 })] 58899 })] 58900 }) 58901 }), hasTemplateLock && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 58902 __nextHasNoMarginBottom: true, 58903 className: "block-editor-block-lock-modal__template-lock", 58904 label: (0,external_wp_i18n_namespaceObject.__)('Apply to all blocks inside'), 58905 checked: applyTemplateLock, 58906 disabled: lock.move && !lock.remove, 58907 onChange: () => setApplyTemplateLock(!applyTemplateLock) 58908 })] 58909 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 58910 className: "block-editor-block-lock-modal__actions", 58911 justify: "flex-end", 58912 expanded: false, 58913 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 58914 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 58915 variant: "tertiary", 58916 onClick: onClose, 58917 __next40pxDefaultSize: true, 58918 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 58919 }) 58920 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 58921 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 58922 variant: "primary", 58923 type: "submit", 58924 __next40pxDefaultSize: true, 58925 children: (0,external_wp_i18n_namespaceObject.__)('Apply') 58926 }) 58927 })] 58928 })] 58929 }) 58930 }); 58931 } 58932 58933 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-lock/menu-item.js 58934 /** 58935 * WordPress dependencies 58936 */ 58937 58938 58939 58940 58941 58942 /** 58943 * Internal dependencies 58944 */ 58945 58946 58947 58948 function BlockLockMenuItem({ 58949 clientId 58950 }) { 58951 const { 58952 canLock, 58953 isLocked 58954 } = useBlockLock(clientId); 58955 const [isModalOpen, toggleModal] = (0,external_wp_element_namespaceObject.useReducer)(isActive => !isActive, false); 58956 if (!canLock) { 58957 return null; 58958 } 58959 const label = isLocked ? (0,external_wp_i18n_namespaceObject.__)('Unlock') : (0,external_wp_i18n_namespaceObject.__)('Lock'); 58960 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 58961 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 58962 icon: isLocked ? library_unlock : lock_outline, 58963 onClick: toggleModal, 58964 "aria-expanded": isModalOpen, 58965 "aria-haspopup": "dialog", 58966 children: label 58967 }), isModalOpen && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockLockModal, { 58968 clientId: clientId, 58969 onClose: toggleModal 58970 })] 58971 }); 58972 } 58973 58974 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-mode-toggle.js 58975 /** 58976 * WordPress dependencies 58977 */ 58978 58979 58980 58981 58982 58983 /** 58984 * Internal dependencies 58985 */ 58986 58987 58988 const block_mode_toggle_noop = () => {}; 58989 function BlockModeToggle({ 58990 clientId, 58991 onToggle = block_mode_toggle_noop 58992 }) { 58993 const { 58994 blockType, 58995 mode, 58996 isCodeEditingEnabled 58997 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 58998 const { 58999 getBlock, 59000 getBlockMode, 59001 getSettings 59002 } = select(store); 59003 const block = getBlock(clientId); 59004 return { 59005 mode: getBlockMode(clientId), 59006 blockType: block ? (0,external_wp_blocks_namespaceObject.getBlockType)(block.name) : null, 59007 isCodeEditingEnabled: getSettings().codeEditingEnabled 59008 }; 59009 }, [clientId]); 59010 const { 59011 toggleBlockMode 59012 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59013 if (!blockType || !(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'html', true) || !isCodeEditingEnabled) { 59014 return null; 59015 } 59016 const label = mode === 'visual' ? (0,external_wp_i18n_namespaceObject.__)('Edit as HTML') : (0,external_wp_i18n_namespaceObject.__)('Edit visually'); 59017 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59018 onClick: () => { 59019 toggleBlockMode(clientId); 59020 onToggle(); 59021 }, 59022 children: label 59023 }); 59024 } 59025 59026 ;// ./node_modules/@wordpress/block-editor/build-module/components/content-lock/modify-content-lock-menu-item.js 59027 /** 59028 * WordPress dependencies 59029 */ 59030 59031 59032 59033 59034 /** 59035 * Internal dependencies 59036 */ 59037 59038 59039 59040 // The implementation of content locking is mainly in this file, although the mechanism 59041 // to stop temporarily editing as blocks when an outside block is selected is on component StopEditingAsBlocksOnOutsideSelect 59042 // at block-editor/src/components/block-list/index.js. 59043 // Besides the components on this file and the file referenced above the implementation 59044 // also includes artifacts on the store (actions, reducers, and selector). 59045 59046 function ModifyContentLockMenuItem({ 59047 clientId, 59048 onClose 59049 }) { 59050 const { 59051 templateLock, 59052 isLockedByParent, 59053 isEditingAsBlocks 59054 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 59055 const { 59056 getContentLockingParent, 59057 getTemplateLock, 59058 getTemporarilyEditingAsBlocks 59059 } = unlock(select(store)); 59060 return { 59061 templateLock: getTemplateLock(clientId), 59062 isLockedByParent: !!getContentLockingParent(clientId), 59063 isEditingAsBlocks: getTemporarilyEditingAsBlocks() === clientId 59064 }; 59065 }, [clientId]); 59066 const blockEditorActions = (0,external_wp_data_namespaceObject.useDispatch)(store); 59067 const isContentLocked = !isLockedByParent && templateLock === 'contentOnly'; 59068 if (!isContentLocked && !isEditingAsBlocks) { 59069 return null; 59070 } 59071 const { 59072 modifyContentLockBlock 59073 } = unlock(blockEditorActions); 59074 const showStartEditingAsBlocks = !isEditingAsBlocks && isContentLocked; 59075 return showStartEditingAsBlocks && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59076 onClick: () => { 59077 modifyContentLockBlock(clientId); 59078 onClose(); 59079 }, 59080 children: (0,external_wp_i18n_namespaceObject._x)('Modify', 'Unlock content locked blocks') 59081 }); 59082 } 59083 59084 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-rename/use-block-rename.js 59085 /** 59086 * WordPress dependencies 59087 */ 59088 59089 function useBlockRename(name) { 59090 return { 59091 canRename: (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'renaming', true) 59092 }; 59093 } 59094 59095 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-rename/is-empty-string.js 59096 function isEmptyString(testString) { 59097 return testString?.trim()?.length === 0; 59098 } 59099 59100 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-rename/modal.js 59101 /** 59102 * WordPress dependencies 59103 */ 59104 59105 59106 59107 59108 59109 59110 /** 59111 * Internal dependencies 59112 */ 59113 59114 59115 59116 59117 function BlockRenameModal({ 59118 clientId, 59119 onClose 59120 }) { 59121 const [editedBlockName, setEditedBlockName] = (0,external_wp_element_namespaceObject.useState)(); 59122 const blockInformation = useBlockDisplayInformation(clientId); 59123 const { 59124 metadata 59125 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 59126 const { 59127 getBlockAttributes 59128 } = select(store); 59129 return { 59130 metadata: getBlockAttributes(clientId)?.metadata 59131 }; 59132 }, [clientId]); 59133 const { 59134 updateBlockAttributes 59135 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59136 const blockName = metadata?.name || ''; 59137 const originalBlockName = blockInformation?.title; 59138 // Pattern Overrides is a WordPress-only feature but it also uses the Block Binding API. 59139 // Ideally this should not be inside the block editor package, but we keep it here for simplicity. 59140 const hasOverridesWarning = !!blockName && !!metadata?.bindings && Object.values(metadata.bindings).some(binding => binding.source === 'core/pattern-overrides'); 59141 const nameHasChanged = editedBlockName !== undefined && editedBlockName !== blockName; 59142 const nameIsOriginal = editedBlockName === originalBlockName; 59143 const nameIsEmpty = isEmptyString(editedBlockName); 59144 const isNameValid = nameHasChanged || nameIsOriginal; 59145 const autoSelectInputText = event => event.target.select(); 59146 const handleSubmit = () => { 59147 const newName = nameIsOriginal || nameIsEmpty ? undefined : editedBlockName; 59148 const message = nameIsOriginal || nameIsEmpty ? (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: new name/label for the block */ 59149 (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 */ 59150 (0,external_wp_i18n_namespaceObject.__)('Block name changed to: "%s".'), editedBlockName); 59151 59152 // Must be assertive to immediately announce change. 59153 (0,external_wp_a11y_namespaceObject.speak)(message, 'assertive'); 59154 updateBlockAttributes([clientId], { 59155 metadata: { 59156 ...metadata, 59157 name: newName 59158 } 59159 }); 59160 59161 // Immediate close avoids ability to hit save multiple times. 59162 onClose(); 59163 }; 59164 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Modal, { 59165 title: (0,external_wp_i18n_namespaceObject.__)('Rename'), 59166 onRequestClose: onClose, 59167 overlayClassName: "block-editor-block-rename-modal", 59168 focusOnMount: "firstContentElement", 59169 size: "small", 59170 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("form", { 59171 onSubmit: e => { 59172 e.preventDefault(); 59173 if (!isNameValid) { 59174 return; 59175 } 59176 handleSubmit(); 59177 }, 59178 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 59179 spacing: "3", 59180 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 59181 __nextHasNoMarginBottom: true, 59182 __next40pxDefaultSize: true, 59183 value: editedBlockName !== null && editedBlockName !== void 0 ? editedBlockName : blockName, 59184 label: (0,external_wp_i18n_namespaceObject.__)('Name'), 59185 help: hasOverridesWarning ? (0,external_wp_i18n_namespaceObject.__)('This block allows overrides. Changing the name can cause problems with content entered into instances of this pattern.') : undefined, 59186 placeholder: originalBlockName, 59187 onChange: setEditedBlockName, 59188 onFocus: autoSelectInputText 59189 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 59190 justify: "right", 59191 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 59192 __next40pxDefaultSize: true, 59193 variant: "tertiary", 59194 onClick: onClose, 59195 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 59196 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 59197 __next40pxDefaultSize: true, 59198 accessibleWhenDisabled: true, 59199 disabled: !isNameValid, 59200 variant: "primary", 59201 type: "submit", 59202 children: (0,external_wp_i18n_namespaceObject.__)('Save') 59203 })] 59204 })] 59205 }) 59206 }) 59207 }); 59208 } 59209 59210 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-rename/rename-control.js 59211 /** 59212 * WordPress dependencies 59213 */ 59214 59215 59216 59217 59218 /** 59219 * Internal dependencies 59220 */ 59221 59222 59223 function BlockRenameControl({ 59224 clientId 59225 }) { 59226 const [renamingBlock, setRenamingBlock] = (0,external_wp_element_namespaceObject.useState)(false); 59227 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 59228 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59229 onClick: () => { 59230 setRenamingBlock(true); 59231 }, 59232 "aria-expanded": renamingBlock, 59233 "aria-haspopup": "dialog", 59234 children: (0,external_wp_i18n_namespaceObject.__)('Rename') 59235 }), renamingBlock && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockRenameModal, { 59236 clientId: clientId, 59237 onClose: () => setRenamingBlock(false) 59238 })] 59239 }); 59240 } 59241 59242 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu-controls/index.js 59243 /** 59244 * WordPress dependencies 59245 */ 59246 59247 59248 59249 /** 59250 * Internal dependencies 59251 */ 59252 59253 59254 59255 59256 59257 59258 59259 const { 59260 Fill, 59261 Slot: block_settings_menu_controls_Slot 59262 } = (0,external_wp_components_namespaceObject.createSlotFill)('BlockSettingsMenuControls'); 59263 const BlockSettingsMenuControlsSlot = ({ 59264 fillProps, 59265 clientIds = null 59266 }) => { 59267 const { 59268 selectedBlocks, 59269 selectedClientIds, 59270 isContentOnly 59271 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 59272 const { 59273 getBlockNamesByClientId, 59274 getSelectedBlockClientIds, 59275 getBlockEditingMode 59276 } = select(store); 59277 const ids = clientIds !== null ? clientIds : getSelectedBlockClientIds(); 59278 return { 59279 selectedBlocks: getBlockNamesByClientId(ids), 59280 selectedClientIds: ids, 59281 isContentOnly: getBlockEditingMode(ids[0]) === 'contentOnly' 59282 }; 59283 }, [clientIds]); 59284 const { 59285 canLock 59286 } = useBlockLock(selectedClientIds[0]); 59287 const { 59288 canRename 59289 } = useBlockRename(selectedBlocks[0]); 59290 const showLockButton = selectedClientIds.length === 1 && canLock && !isContentOnly; 59291 const showRenameButton = selectedClientIds.length === 1 && canRename && !isContentOnly; 59292 59293 // Check if current selection of blocks is Groupable or Ungroupable 59294 // and pass this props down to ConvertToGroupButton. 59295 const convertToGroupButtonProps = useConvertToGroupButtonProps(selectedClientIds); 59296 const { 59297 isGroupable, 59298 isUngroupable 59299 } = convertToGroupButtonProps; 59300 const showConvertToGroupButton = (isGroupable || isUngroupable) && !isContentOnly; 59301 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_settings_menu_controls_Slot, { 59302 fillProps: { 59303 ...fillProps, 59304 selectedBlocks, 59305 selectedClientIds 59306 }, 59307 children: fills => { 59308 if (!fills?.length > 0 && !showConvertToGroupButton && !showLockButton) { 59309 return null; 59310 } 59311 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 59312 children: [showConvertToGroupButton && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ConvertToGroupButton, { 59313 ...convertToGroupButtonProps, 59314 onClose: fillProps?.onClose 59315 }), showLockButton && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockLockMenuItem, { 59316 clientId: selectedClientIds[0] 59317 }), showRenameButton && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockRenameControl, { 59318 clientId: selectedClientIds[0] 59319 }), fills, selectedClientIds.length === 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ModifyContentLockMenuItem, { 59320 clientId: selectedClientIds[0], 59321 onClose: fillProps?.onClose 59322 }), fillProps?.count === 1 && !isContentOnly && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockModeToggle, { 59323 clientId: fillProps?.firstBlockClientId, 59324 onToggle: fillProps?.onClose 59325 })] 59326 }); 59327 } 59328 }); 59329 }; 59330 59331 /** 59332 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-settings-menu-controls/README.md 59333 * 59334 * @param {Object} props Fill props. 59335 * @return {Element} Element. 59336 */ 59337 function BlockSettingsMenuControls({ 59338 ...props 59339 }) { 59340 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalStyleProvider, { 59341 document: document, 59342 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Fill, { 59343 ...props 59344 }) 59345 }); 59346 } 59347 BlockSettingsMenuControls.Slot = BlockSettingsMenuControlsSlot; 59348 /* harmony default export */ const block_settings_menu_controls = (BlockSettingsMenuControls); 59349 59350 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-parent-selector-menu-item.js 59351 /** 59352 * WordPress dependencies 59353 */ 59354 59355 59356 59357 59358 59359 59360 /** 59361 * Internal dependencies 59362 */ 59363 59364 59365 59366 59367 function BlockParentSelectorMenuItem({ 59368 parentClientId, 59369 parentBlockType 59370 }) { 59371 const isSmallViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 59372 const { 59373 selectBlock 59374 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59375 59376 // Allows highlighting the parent block outline when focusing or hovering 59377 // the parent block selector within the child. 59378 const menuItemRef = (0,external_wp_element_namespaceObject.useRef)(); 59379 const gesturesProps = useShowHoveredOrFocusedGestures({ 59380 ref: menuItemRef, 59381 highlightParent: true 59382 }); 59383 if (!isSmallViewport) { 59384 return null; 59385 } 59386 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59387 ...gesturesProps, 59388 ref: menuItemRef, 59389 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 59390 icon: parentBlockType.icon 59391 }), 59392 onClick: () => selectBlock(parentClientId), 59393 children: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Name of the block's parent. */ 59394 (0,external_wp_i18n_namespaceObject.__)('Select parent block (%s)'), parentBlockType.title) 59395 }); 59396 } 59397 59398 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/block-settings-dropdown.js 59399 /** 59400 * WordPress dependencies 59401 */ 59402 59403 59404 59405 59406 59407 59408 59409 59410 59411 /** 59412 * Internal dependencies 59413 */ 59414 59415 59416 59417 59418 59419 59420 59421 59422 59423 59424 const block_settings_dropdown_POPOVER_PROPS = { 59425 className: 'block-editor-block-settings-menu__popover', 59426 placement: 'bottom-start' 59427 }; 59428 function CopyMenuItem({ 59429 clientIds, 59430 onCopy, 59431 label, 59432 shortcut, 59433 eventType = 'copy', 59434 __experimentalUpdateSelection: updateSelection = false 59435 }) { 59436 const { 59437 getBlocksByClientId 59438 } = (0,external_wp_data_namespaceObject.useSelect)(store); 59439 const { 59440 removeBlocks 59441 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59442 const notifyCopy = useNotifyCopy(); 59443 const ref = (0,external_wp_compose_namespaceObject.useCopyToClipboard)(() => (0,external_wp_blocks_namespaceObject.serialize)(getBlocksByClientId(clientIds)), () => { 59444 switch (eventType) { 59445 case 'copy': 59446 case 'copyStyles': 59447 onCopy(); 59448 notifyCopy(eventType, clientIds); 59449 break; 59450 case 'cut': 59451 notifyCopy(eventType, clientIds); 59452 removeBlocks(clientIds, updateSelection); 59453 break; 59454 default: 59455 break; 59456 } 59457 }); 59458 const copyMenuItemLabel = label ? label : (0,external_wp_i18n_namespaceObject.__)('Copy'); 59459 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59460 ref: ref, 59461 shortcut: shortcut, 59462 children: copyMenuItemLabel 59463 }); 59464 } 59465 function BlockSettingsDropdown({ 59466 block, 59467 clientIds, 59468 children, 59469 __experimentalSelectBlock, 59470 ...props 59471 }) { 59472 // Get the client id of the current block for this menu, if one is set. 59473 const currentClientId = block?.clientId; 59474 const count = clientIds.length; 59475 const firstBlockClientId = clientIds[0]; 59476 const { 59477 firstParentClientId, 59478 parentBlockType, 59479 previousBlockClientId, 59480 selectedBlockClientIds, 59481 openedBlockSettingsMenu, 59482 isContentOnly 59483 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 59484 const { 59485 getBlockName, 59486 getBlockRootClientId, 59487 getPreviousBlockClientId, 59488 getSelectedBlockClientIds, 59489 getBlockAttributes, 59490 getOpenedBlockSettingsMenu, 59491 getBlockEditingMode 59492 } = unlock(select(store)); 59493 const { 59494 getActiveBlockVariation 59495 } = select(external_wp_blocks_namespaceObject.store); 59496 const _firstParentClientId = getBlockRootClientId(firstBlockClientId); 59497 const parentBlockName = _firstParentClientId && getBlockName(_firstParentClientId); 59498 return { 59499 firstParentClientId: _firstParentClientId, 59500 parentBlockType: _firstParentClientId && (getActiveBlockVariation(parentBlockName, getBlockAttributes(_firstParentClientId)) || (0,external_wp_blocks_namespaceObject.getBlockType)(parentBlockName)), 59501 previousBlockClientId: getPreviousBlockClientId(firstBlockClientId), 59502 selectedBlockClientIds: getSelectedBlockClientIds(), 59503 openedBlockSettingsMenu: getOpenedBlockSettingsMenu(), 59504 isContentOnly: getBlockEditingMode(firstBlockClientId) === 'contentOnly' 59505 }; 59506 }, [firstBlockClientId]); 59507 const { 59508 getBlockOrder, 59509 getSelectedBlockClientIds 59510 } = (0,external_wp_data_namespaceObject.useSelect)(store); 59511 const { 59512 setOpenedBlockSettingsMenu 59513 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 59514 const shortcuts = (0,external_wp_data_namespaceObject.useSelect)(select => { 59515 const { 59516 getShortcutRepresentation 59517 } = select(external_wp_keyboardShortcuts_namespaceObject.store); 59518 return { 59519 copy: getShortcutRepresentation('core/block-editor/copy'), 59520 cut: getShortcutRepresentation('core/block-editor/cut'), 59521 duplicate: getShortcutRepresentation('core/block-editor/duplicate'), 59522 remove: getShortcutRepresentation('core/block-editor/remove'), 59523 insertAfter: getShortcutRepresentation('core/block-editor/insert-after'), 59524 insertBefore: getShortcutRepresentation('core/block-editor/insert-before') 59525 }; 59526 }, []); 59527 const hasSelectedBlocks = selectedBlockClientIds.length > 0; 59528 async function updateSelectionAfterDuplicate(clientIdsPromise) { 59529 if (!__experimentalSelectBlock) { 59530 return; 59531 } 59532 const ids = await clientIdsPromise; 59533 if (ids && ids[0]) { 59534 __experimentalSelectBlock(ids[0], false); 59535 } 59536 } 59537 function updateSelectionAfterRemove() { 59538 if (!__experimentalSelectBlock) { 59539 return; 59540 } 59541 let blockToFocus = previousBlockClientId || firstParentClientId; 59542 59543 // Focus the first block if there's no previous block nor parent block. 59544 if (!blockToFocus) { 59545 blockToFocus = getBlockOrder()[0]; 59546 } 59547 59548 // Only update the selection if the original selection is removed. 59549 const shouldUpdateSelection = hasSelectedBlocks && getSelectedBlockClientIds().length === 0; 59550 __experimentalSelectBlock(blockToFocus, shouldUpdateSelection); 59551 } 59552 59553 // This can occur when the selected block (the parent) 59554 // displays child blocks within a List View. 59555 const parentBlockIsSelected = selectedBlockClientIds?.includes(firstParentClientId); 59556 59557 // When a currentClientId is in use, treat the menu as a controlled component. 59558 // This ensures that only one block settings menu is open at a time. 59559 // This is a temporary solution to work around an issue with `onFocusOutside` 59560 // where it does not allow a dropdown to be closed if focus was never within 59561 // the dropdown to begin with. Examples include a user either CMD+Clicking or 59562 // right clicking into an inactive window. 59563 // See: https://github.com/WordPress/gutenberg/pull/54083 59564 const open = !currentClientId ? undefined : openedBlockSettingsMenu === currentClientId || false; 59565 function onToggle(localOpen) { 59566 if (localOpen && openedBlockSettingsMenu !== currentClientId) { 59567 setOpenedBlockSettingsMenu(currentClientId); 59568 } else if (!localOpen && openedBlockSettingsMenu && openedBlockSettingsMenu === currentClientId) { 59569 setOpenedBlockSettingsMenu(undefined); 59570 } 59571 } 59572 const shouldShowBlockParentMenuItem = !parentBlockIsSelected && !!firstParentClientId; 59573 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockActions, { 59574 clientIds: clientIds, 59575 __experimentalUpdateSelection: !__experimentalSelectBlock, 59576 children: ({ 59577 canCopyStyles, 59578 canDuplicate, 59579 canInsertBlock, 59580 canRemove, 59581 onDuplicate, 59582 onInsertAfter, 59583 onInsertBefore, 59584 onRemove, 59585 onCopy, 59586 onPasteStyles 59587 }) => { 59588 // It is possible that some plugins register fills for this menu 59589 // even if Core doesn't render anything in the block settings menu. 59590 // in which case, we may want to render the menu anyway. 59591 // That said for now, we can start more conservative. 59592 const isEmpty = !canRemove && !canDuplicate && !canInsertBlock && isContentOnly; 59593 if (isEmpty) { 59594 return null; 59595 } 59596 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 59597 icon: more_vertical, 59598 label: (0,external_wp_i18n_namespaceObject.__)('Options'), 59599 className: "block-editor-block-settings-menu", 59600 popoverProps: block_settings_dropdown_POPOVER_PROPS, 59601 open: open, 59602 onToggle: onToggle, 59603 noIcons: true, 59604 ...props, 59605 children: ({ 59606 onClose 59607 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 59608 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 59609 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_settings_menu_first_item.Slot, { 59610 fillProps: { 59611 onClose 59612 } 59613 }), shouldShowBlockParentMenuItem && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockParentSelectorMenuItem, { 59614 parentClientId: firstParentClientId, 59615 parentBlockType: parentBlockType 59616 }), count === 1 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_html_convert_button, { 59617 clientId: firstBlockClientId 59618 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CopyMenuItem, { 59619 clientIds: clientIds, 59620 onCopy: onCopy, 59621 shortcut: shortcuts.copy 59622 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CopyMenuItem, { 59623 clientIds: clientIds, 59624 label: (0,external_wp_i18n_namespaceObject.__)('Cut'), 59625 eventType: "cut", 59626 shortcut: shortcuts.cut, 59627 __experimentalUpdateSelection: !__experimentalSelectBlock 59628 }), canDuplicate && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59629 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onDuplicate, updateSelectionAfterDuplicate), 59630 shortcut: shortcuts.duplicate, 59631 children: (0,external_wp_i18n_namespaceObject.__)('Duplicate') 59632 }), canInsertBlock && !isContentOnly && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 59633 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59634 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onInsertBefore), 59635 shortcut: shortcuts.insertBefore, 59636 children: (0,external_wp_i18n_namespaceObject.__)('Add before') 59637 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59638 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onInsertAfter), 59639 shortcut: shortcuts.insertAfter, 59640 children: (0,external_wp_i18n_namespaceObject.__)('Add after') 59641 })] 59642 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_comment_icon_slot.Slot, { 59643 fillProps: { 59644 onClose 59645 } 59646 })] 59647 }), canCopyStyles && !isContentOnly && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.MenuGroup, { 59648 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CopyMenuItem, { 59649 clientIds: clientIds, 59650 onCopy: onCopy, 59651 label: (0,external_wp_i18n_namespaceObject.__)('Copy styles'), 59652 eventType: "copyStyles" 59653 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59654 onClick: onPasteStyles, 59655 children: (0,external_wp_i18n_namespaceObject.__)('Paste styles') 59656 })] 59657 }), !isContentOnly && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_settings_menu_controls.Slot, { 59658 fillProps: { 59659 onClose, 59660 count, 59661 firstBlockClientId 59662 }, 59663 clientIds: clientIds 59664 }), typeof children === 'function' ? children({ 59665 onClose 59666 }) : external_wp_element_namespaceObject.Children.map(child => (0,external_wp_element_namespaceObject.cloneElement)(child, { 59667 onClose 59668 })), canRemove && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 59669 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 59670 onClick: (0,external_wp_compose_namespaceObject.pipe)(onClose, onRemove, updateSelectionAfterRemove), 59671 shortcut: shortcuts.remove, 59672 children: (0,external_wp_i18n_namespaceObject.__)('Delete') 59673 }) 59674 })] 59675 }) 59676 }); 59677 } 59678 }); 59679 } 59680 /* harmony default export */ const block_settings_dropdown = (BlockSettingsDropdown); 59681 59682 ;// ./node_modules/@wordpress/block-editor/build-module/components/collab/block-comment-icon-toolbar-slot.js 59683 /** 59684 * WordPress dependencies 59685 */ 59686 59687 const CommentIconToolbarSlotFill = (0,external_wp_components_namespaceObject.createSlotFill)(Symbol('CommentIconToolbarSlotFill')); 59688 /* harmony default export */ const block_comment_icon_toolbar_slot = (CommentIconToolbarSlotFill); 59689 59690 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-settings-menu/index.js 59691 /** 59692 * WordPress dependencies 59693 */ 59694 59695 59696 /** 59697 * Internal dependencies 59698 */ 59699 59700 59701 59702 function BlockSettingsMenu({ 59703 clientIds, 59704 ...props 59705 }) { 59706 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.ToolbarGroup, { 59707 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_comment_icon_toolbar_slot.Slot, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarItem, { 59708 children: toggleProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_settings_dropdown, { 59709 clientIds: clientIds, 59710 toggleProps: toggleProps, 59711 ...props 59712 }) 59713 })] 59714 }); 59715 } 59716 /* harmony default export */ const block_settings_menu = (BlockSettingsMenu); 59717 59718 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-lock/toolbar.js 59719 /** 59720 * WordPress dependencies 59721 */ 59722 59723 59724 59725 59726 59727 /** 59728 * Internal dependencies 59729 */ 59730 59731 59732 59733 function BlockLockToolbar({ 59734 clientId 59735 }) { 59736 const { 59737 canLock, 59738 isLocked 59739 } = useBlockLock(clientId); 59740 const [isModalOpen, toggleModal] = (0,external_wp_element_namespaceObject.useReducer)(isActive => !isActive, false); 59741 const hasLockButtonShownRef = (0,external_wp_element_namespaceObject.useRef)(false); 59742 59743 // If the block lock button has been shown, we don't want to remove it 59744 // from the toolbar until the toolbar is rendered again without it. 59745 // Removing it beforehand can cause focus loss issues, such as when 59746 // unlocking the block from the modal. It needs to return focus from 59747 // whence it came, and to do that, we need to leave the button in the toolbar. 59748 (0,external_wp_element_namespaceObject.useEffect)(() => { 59749 if (isLocked) { 59750 hasLockButtonShownRef.current = true; 59751 } 59752 }, [isLocked]); 59753 if (!isLocked && !hasLockButtonShownRef.current) { 59754 return null; 59755 } 59756 let label = isLocked ? (0,external_wp_i18n_namespaceObject.__)('Unlock') : (0,external_wp_i18n_namespaceObject.__)('Lock'); 59757 if (!canLock && isLocked) { 59758 label = (0,external_wp_i18n_namespaceObject.__)('Locked'); 59759 } 59760 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 59761 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 59762 className: "block-editor-block-lock-toolbar", 59763 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 59764 disabled: !canLock, 59765 icon: isLocked ? library_lock : library_unlock, 59766 label: label, 59767 onClick: toggleModal, 59768 "aria-expanded": isModalOpen, 59769 "aria-haspopup": "dialog" 59770 }) 59771 }), isModalOpen && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockLockModal, { 59772 clientId: clientId, 59773 onClose: toggleModal 59774 })] 59775 }); 59776 } 59777 59778 ;// ./node_modules/@wordpress/icons/build-module/library/group.js 59779 /** 59780 * WordPress dependencies 59781 */ 59782 59783 59784 const group_group = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 59785 viewBox: "0 0 24 24", 59786 xmlns: "http://www.w3.org/2000/svg", 59787 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 59788 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" 59789 }) 59790 }); 59791 /* harmony default export */ const library_group = (group_group); 59792 59793 ;// ./node_modules/@wordpress/icons/build-module/library/row.js 59794 /** 59795 * WordPress dependencies 59796 */ 59797 59798 59799 const row = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 59800 xmlns: "http://www.w3.org/2000/svg", 59801 viewBox: "0 0 24 24", 59802 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 59803 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" 59804 }) 59805 }); 59806 /* harmony default export */ const library_row = (row); 59807 59808 ;// ./node_modules/@wordpress/icons/build-module/library/stack.js 59809 /** 59810 * WordPress dependencies 59811 */ 59812 59813 59814 const stack = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 59815 xmlns: "http://www.w3.org/2000/svg", 59816 viewBox: "0 0 24 24", 59817 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 59818 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" 59819 }) 59820 }); 59821 /* harmony default export */ const library_stack = (stack); 59822 59823 ;// ./node_modules/@wordpress/icons/build-module/library/grid.js 59824 /** 59825 * WordPress dependencies 59826 */ 59827 59828 59829 const grid_grid = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 59830 xmlns: "http://www.w3.org/2000/svg", 59831 viewBox: "0 0 24 24", 59832 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 59833 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", 59834 fillRule: "evenodd", 59835 clipRule: "evenodd" 59836 }) 59837 }); 59838 /* harmony default export */ const library_grid = (grid_grid); 59839 59840 ;// ./node_modules/@wordpress/block-editor/build-module/components/convert-to-group-buttons/toolbar.js 59841 /** 59842 * WordPress dependencies 59843 */ 59844 59845 59846 59847 59848 59849 59850 /** 59851 * Internal dependencies 59852 */ 59853 59854 59855 59856 const layouts = { 59857 group: { 59858 type: 'constrained' 59859 }, 59860 row: { 59861 type: 'flex', 59862 flexWrap: 'nowrap' 59863 }, 59864 stack: { 59865 type: 'flex', 59866 orientation: 'vertical' 59867 }, 59868 grid: { 59869 type: 'grid' 59870 } 59871 }; 59872 function BlockGroupToolbar() { 59873 const { 59874 blocksSelection, 59875 clientIds, 59876 groupingBlockName, 59877 isGroupable 59878 } = useConvertToGroupButtonProps(); 59879 const { 59880 replaceBlocks 59881 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59882 const { 59883 canRemove, 59884 variations 59885 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 59886 const { 59887 canRemoveBlocks 59888 } = select(store); 59889 const { 59890 getBlockVariations 59891 } = select(external_wp_blocks_namespaceObject.store); 59892 return { 59893 canRemove: canRemoveBlocks(clientIds), 59894 variations: getBlockVariations(groupingBlockName, 'transform') 59895 }; 59896 }, [clientIds, groupingBlockName]); 59897 const onConvertToGroup = layout => { 59898 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocksSelection, groupingBlockName); 59899 if (typeof layout !== 'string') { 59900 layout = 'group'; 59901 } 59902 if (newBlocks && newBlocks.length > 0) { 59903 // Because the block is not in the store yet we can't use 59904 // updateBlockAttributes so need to manually update attributes. 59905 newBlocks[0].attributes.layout = layouts[layout]; 59906 replaceBlocks(clientIds, newBlocks); 59907 } 59908 }; 59909 const onConvertToRow = () => onConvertToGroup('row'); 59910 const onConvertToStack = () => onConvertToGroup('stack'); 59911 const onConvertToGrid = () => onConvertToGroup('grid'); 59912 59913 // Don't render the button if the current selection cannot be grouped. 59914 // A good example is selecting multiple button blocks within a Buttons block: 59915 // The group block is not a valid child of Buttons, so we should not show the button. 59916 // Any blocks that are locked against removal also cannot be grouped. 59917 if (!isGroupable || !canRemove) { 59918 return null; 59919 } 59920 const canInsertRow = !!variations.find(({ 59921 name 59922 }) => name === 'group-row'); 59923 const canInsertStack = !!variations.find(({ 59924 name 59925 }) => name === 'group-stack'); 59926 const canInsertGrid = !!variations.find(({ 59927 name 59928 }) => name === 'group-grid'); 59929 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.ToolbarGroup, { 59930 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 59931 icon: library_group, 59932 label: (0,external_wp_i18n_namespaceObject._x)('Group', 'action: convert blocks to group'), 59933 onClick: onConvertToGroup 59934 }), canInsertRow && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 59935 icon: library_row, 59936 label: (0,external_wp_i18n_namespaceObject._x)('Row', 'action: convert blocks to row'), 59937 onClick: onConvertToRow 59938 }), canInsertStack && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 59939 icon: library_stack, 59940 label: (0,external_wp_i18n_namespaceObject._x)('Stack', 'action: convert blocks to stack'), 59941 onClick: onConvertToStack 59942 }), canInsertGrid && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 59943 icon: library_grid, 59944 label: (0,external_wp_i18n_namespaceObject._x)('Grid', 'action: convert blocks to grid'), 59945 onClick: onConvertToGrid 59946 })] 59947 }); 59948 } 59949 /* harmony default export */ const toolbar = (BlockGroupToolbar); 59950 59951 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-edit-visually-button/index.js 59952 /** 59953 * WordPress dependencies 59954 */ 59955 59956 59957 59958 59959 /** 59960 * Internal dependencies 59961 */ 59962 59963 59964 function BlockEditVisuallyButton({ 59965 clientIds 59966 }) { 59967 // Edit visually only works for single block selection. 59968 const clientId = clientIds.length === 1 ? clientIds[0] : undefined; 59969 const canEditVisually = (0,external_wp_data_namespaceObject.useSelect)(select => !!clientId && select(store).getBlockMode(clientId) === 'html', [clientId]); 59970 const { 59971 toggleBlockMode 59972 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 59973 if (!canEditVisually) { 59974 return null; 59975 } 59976 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 59977 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 59978 onClick: () => { 59979 toggleBlockMode(clientId); 59980 }, 59981 children: (0,external_wp_i18n_namespaceObject.__)('Edit visually') 59982 }) 59983 }); 59984 } 59985 59986 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/block-name-context.js 59987 /** 59988 * WordPress dependencies 59989 */ 59990 59991 const __unstableBlockNameContext = (0,external_wp_element_namespaceObject.createContext)(''); 59992 /* harmony default export */ const block_name_context = (__unstableBlockNameContext); 59993 59994 ;// ./node_modules/@wordpress/block-editor/build-module/components/navigable-toolbar/index.js 59995 /** 59996 * WordPress dependencies 59997 */ 59998 59999 60000 60001 60002 60003 60004 60005 60006 /** 60007 * Internal dependencies 60008 */ 60009 60010 60011 60012 function hasOnlyToolbarItem(elements) { 60013 const dataProp = 'toolbarItem'; 60014 return !elements.some(element => !(dataProp in element.dataset)); 60015 } 60016 function getAllFocusableToolbarItemsIn(container) { 60017 return Array.from(container.querySelectorAll('[data-toolbar-item]:not([disabled])')); 60018 } 60019 function hasFocusWithin(container) { 60020 return container.contains(container.ownerDocument.activeElement); 60021 } 60022 function focusFirstTabbableIn(container) { 60023 const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container); 60024 if (firstTabbable) { 60025 firstTabbable.focus({ 60026 // When focusing newly mounted toolbars, 60027 // the position of the popover is often not right on the first render 60028 // This prevents the layout shifts when focusing the dialogs. 60029 preventScroll: true 60030 }); 60031 } 60032 } 60033 function useIsAccessibleToolbar(toolbarRef) { 60034 /* 60035 * By default, we'll assume the starting accessible state of the Toolbar 60036 * is true, as it seems to be the most common case. 60037 * 60038 * Transitioning from an (initial) false to true state causes the 60039 * <Toolbar /> component to mount twice, which is causing undesired 60040 * side-effects. These side-effects appear to only affect certain 60041 * E2E tests. 60042 * 60043 * This was initial discovered in this pull-request: 60044 * https://github.com/WordPress/gutenberg/pull/23425 60045 */ 60046 const initialAccessibleToolbarState = true; 60047 60048 // By default, it's gonna render NavigableMenu. If all the tabbable elements 60049 // inside the toolbar are ToolbarItem components (or derived components like 60050 // ToolbarButton), then we can wrap them with the accessible Toolbar 60051 // component. 60052 const [isAccessibleToolbar, setIsAccessibleToolbar] = (0,external_wp_element_namespaceObject.useState)(initialAccessibleToolbarState); 60053 const determineIsAccessibleToolbar = (0,external_wp_element_namespaceObject.useCallback)(() => { 60054 const tabbables = external_wp_dom_namespaceObject.focus.tabbable.find(toolbarRef.current); 60055 const onlyToolbarItem = hasOnlyToolbarItem(tabbables); 60056 if (!onlyToolbarItem) { 60057 external_wp_deprecated_default()('Using custom components as toolbar controls', { 60058 since: '5.6', 60059 alternative: 'ToolbarItem, ToolbarButton or ToolbarDropdownMenu components', 60060 link: 'https://developer.wordpress.org/block-editor/components/toolbar-button/#inside-blockcontrols' 60061 }); 60062 } 60063 setIsAccessibleToolbar(onlyToolbarItem); 60064 }, [toolbarRef]); 60065 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 60066 // Toolbar buttons may be rendered asynchronously, so we use 60067 // MutationObserver to check if the toolbar subtree has been modified. 60068 const observer = new window.MutationObserver(determineIsAccessibleToolbar); 60069 observer.observe(toolbarRef.current, { 60070 childList: true, 60071 subtree: true 60072 }); 60073 return () => observer.disconnect(); 60074 }, [determineIsAccessibleToolbar, isAccessibleToolbar, toolbarRef]); 60075 return isAccessibleToolbar; 60076 } 60077 function useToolbarFocus({ 60078 toolbarRef, 60079 focusOnMount, 60080 isAccessibleToolbar, 60081 defaultIndex, 60082 onIndexChange, 60083 shouldUseKeyboardFocusShortcut, 60084 focusEditorOnEscape 60085 }) { 60086 // Make sure we don't use modified versions of this prop. 60087 const [initialFocusOnMount] = (0,external_wp_element_namespaceObject.useState)(focusOnMount); 60088 const [initialIndex] = (0,external_wp_element_namespaceObject.useState)(defaultIndex); 60089 const focusToolbar = (0,external_wp_element_namespaceObject.useCallback)(() => { 60090 focusFirstTabbableIn(toolbarRef.current); 60091 }, [toolbarRef]); 60092 const focusToolbarViaShortcut = () => { 60093 if (shouldUseKeyboardFocusShortcut) { 60094 focusToolbar(); 60095 } 60096 }; 60097 60098 // Focus on toolbar when pressing alt+F10 when the toolbar is visible. 60099 (0,external_wp_keyboardShortcuts_namespaceObject.useShortcut)('core/block-editor/focus-toolbar', focusToolbarViaShortcut); 60100 (0,external_wp_element_namespaceObject.useEffect)(() => { 60101 if (initialFocusOnMount) { 60102 focusToolbar(); 60103 } 60104 }, [isAccessibleToolbar, initialFocusOnMount, focusToolbar]); 60105 (0,external_wp_element_namespaceObject.useEffect)(() => { 60106 // Store ref so we have access on useEffect cleanup: https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#effect-cleanup-timing 60107 const navigableToolbarRef = toolbarRef.current; 60108 // If initialIndex is passed, we focus on that toolbar item when the 60109 // toolbar gets mounted and initial focus is not forced. 60110 // We have to wait for the next browser paint because block controls aren't 60111 // rendered right away when the toolbar gets mounted. 60112 let raf = 0; 60113 60114 // If the toolbar already had focus before the render, we don't want to move it. 60115 // https://github.com/WordPress/gutenberg/issues/58511 60116 if (!initialFocusOnMount && !hasFocusWithin(navigableToolbarRef)) { 60117 raf = window.requestAnimationFrame(() => { 60118 const items = getAllFocusableToolbarItemsIn(navigableToolbarRef); 60119 const index = initialIndex || 0; 60120 if (items[index] && hasFocusWithin(navigableToolbarRef)) { 60121 items[index].focus({ 60122 // When focusing newly mounted toolbars, 60123 // the position of the popover is often not right on the first render 60124 // This prevents the layout shifts when focusing the dialogs. 60125 preventScroll: true 60126 }); 60127 } 60128 }); 60129 } 60130 return () => { 60131 window.cancelAnimationFrame(raf); 60132 if (!onIndexChange || !navigableToolbarRef) { 60133 return; 60134 } 60135 // When the toolbar element is unmounted and onIndexChange is passed, we 60136 // pass the focused toolbar item index so it can be hydrated later. 60137 const items = getAllFocusableToolbarItemsIn(navigableToolbarRef); 60138 const index = items.findIndex(item => item.tabIndex === 0); 60139 onIndexChange(index); 60140 }; 60141 }, [initialIndex, initialFocusOnMount, onIndexChange, toolbarRef]); 60142 const { 60143 getLastFocus 60144 } = unlock((0,external_wp_data_namespaceObject.useSelect)(store)); 60145 /** 60146 * Handles returning focus to the block editor canvas when pressing escape. 60147 */ 60148 (0,external_wp_element_namespaceObject.useEffect)(() => { 60149 const navigableToolbarRef = toolbarRef.current; 60150 if (focusEditorOnEscape) { 60151 const handleKeyDown = event => { 60152 const lastFocus = getLastFocus(); 60153 if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && lastFocus?.current) { 60154 // Focus the last focused element when pressing escape. 60155 event.preventDefault(); 60156 lastFocus.current.focus(); 60157 } 60158 }; 60159 navigableToolbarRef.addEventListener('keydown', handleKeyDown); 60160 return () => { 60161 navigableToolbarRef.removeEventListener('keydown', handleKeyDown); 60162 }; 60163 } 60164 }, [focusEditorOnEscape, getLastFocus, toolbarRef]); 60165 } 60166 function NavigableToolbar({ 60167 children, 60168 focusOnMount, 60169 focusEditorOnEscape = false, 60170 shouldUseKeyboardFocusShortcut = true, 60171 __experimentalInitialIndex: initialIndex, 60172 __experimentalOnIndexChange: onIndexChange, 60173 orientation = 'horizontal', 60174 ...props 60175 }) { 60176 const toolbarRef = (0,external_wp_element_namespaceObject.useRef)(); 60177 const isAccessibleToolbar = useIsAccessibleToolbar(toolbarRef); 60178 useToolbarFocus({ 60179 toolbarRef, 60180 focusOnMount, 60181 defaultIndex: initialIndex, 60182 onIndexChange, 60183 isAccessibleToolbar, 60184 shouldUseKeyboardFocusShortcut, 60185 focusEditorOnEscape 60186 }); 60187 if (isAccessibleToolbar) { 60188 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Toolbar, { 60189 label: props['aria-label'], 60190 ref: toolbarRef, 60191 orientation: orientation, 60192 ...props, 60193 children: children 60194 }); 60195 } 60196 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.NavigableMenu, { 60197 orientation: orientation, 60198 role: "toolbar", 60199 ref: toolbarRef, 60200 ...props, 60201 children: children 60202 }); 60203 } 60204 60205 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/use-has-block-toolbar.js 60206 /** 60207 * WordPress dependencies 60208 */ 60209 60210 60211 /** 60212 * Internal dependencies 60213 */ 60214 60215 60216 /** 60217 * Returns true if the block toolbar should be shown. 60218 * 60219 * @return {boolean} Whether the block toolbar component will be rendered. 60220 */ 60221 function useHasBlockToolbar() { 60222 const { 60223 isToolbarEnabled, 60224 isBlockDisabled 60225 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 60226 const { 60227 getBlockEditingMode, 60228 getBlockName, 60229 getBlockSelectionStart 60230 } = select(store); 60231 60232 // we only care about the 1st selected block 60233 // for the toolbar, so we use getBlockSelectionStart 60234 // instead of getSelectedBlockClientIds 60235 const selectedBlockClientId = getBlockSelectionStart(); 60236 const blockType = selectedBlockClientId && (0,external_wp_blocks_namespaceObject.getBlockType)(getBlockName(selectedBlockClientId)); 60237 return { 60238 isToolbarEnabled: blockType && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, '__experimentalToolbar', true), 60239 isBlockDisabled: getBlockEditingMode(selectedBlockClientId) === 'disabled' 60240 }; 60241 }, []); 60242 if (!isToolbarEnabled || isBlockDisabled) { 60243 return false; 60244 } 60245 return true; 60246 } 60247 60248 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/change-design.js 60249 /** 60250 * WordPress dependencies 60251 */ 60252 60253 60254 60255 60256 60257 60258 /** 60259 * Internal dependencies 60260 */ 60261 60262 60263 60264 const change_design_EMPTY_ARRAY = []; 60265 const MAX_PATTERNS_TO_SHOW = 6; 60266 const change_design_POPOVER_PROPS = { 60267 placement: 'bottom-start' 60268 }; 60269 function ChangeDesign({ 60270 clientId 60271 }) { 60272 const { 60273 categories, 60274 currentPatternName, 60275 patterns 60276 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 60277 const { 60278 getBlockAttributes, 60279 getBlockRootClientId, 60280 __experimentalGetAllowedPatterns 60281 } = select(store); 60282 const attributes = getBlockAttributes(clientId); 60283 const _categories = attributes?.metadata?.categories || change_design_EMPTY_ARRAY; 60284 const rootBlock = getBlockRootClientId(clientId); 60285 60286 // Calling `__experimentalGetAllowedPatterns` is expensive. 60287 // Checking if the block can be changed prevents unnecessary selector calls. 60288 // See: https://github.com/WordPress/gutenberg/pull/64736. 60289 const _patterns = _categories.length > 0 ? __experimentalGetAllowedPatterns(rootBlock) : change_design_EMPTY_ARRAY; 60290 return { 60291 categories: _categories, 60292 currentPatternName: attributes?.metadata?.patternName, 60293 patterns: _patterns 60294 }; 60295 }, [clientId]); 60296 const { 60297 replaceBlocks 60298 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 60299 const sameCategoryPatternsWithSingleWrapper = (0,external_wp_element_namespaceObject.useMemo)(() => { 60300 if (categories.length === 0 || !patterns || patterns.length === 0) { 60301 return change_design_EMPTY_ARRAY; 60302 } 60303 return patterns.filter(pattern => { 60304 const isCorePattern = pattern.source === 'core' || pattern.source?.startsWith('pattern-directory') && pattern.source !== 'pattern-directory/theme'; 60305 return ( 60306 // Check if the pattern has only one top level block, 60307 // otherwise we may switch to a pattern that doesn't have replacement suggestions. 60308 pattern.blocks.length === 1 && 60309 // We exclude the core patterns and pattern directory patterns that are not theme patterns. 60310 !isCorePattern && 60311 // Exclude current pattern. 60312 currentPatternName !== pattern.name && pattern.categories?.some(category => { 60313 return categories.includes(category); 60314 }) && ( 60315 // Check if the pattern is not a synced pattern. 60316 pattern.syncStatus === 'unsynced' || !pattern.id) 60317 ); 60318 }).slice(0, MAX_PATTERNS_TO_SHOW); 60319 }, [categories, currentPatternName, patterns]); 60320 if (sameCategoryPatternsWithSingleWrapper.length < 2) { 60321 return null; 60322 } 60323 const onClickPattern = pattern => { 60324 var _pattern$blocks; 60325 const newBlocks = ((_pattern$blocks = pattern.blocks) !== null && _pattern$blocks !== void 0 ? _pattern$blocks : []).map(block => { 60326 return (0,external_wp_blocks_namespaceObject.cloneBlock)(block); 60327 }); 60328 newBlocks[0].attributes.metadata = { 60329 ...newBlocks[0].attributes.metadata, 60330 categories 60331 }; 60332 replaceBlocks(clientId, newBlocks); 60333 }; 60334 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 60335 popoverProps: change_design_POPOVER_PROPS, 60336 renderToggle: ({ 60337 onToggle, 60338 isOpen 60339 }) => { 60340 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 60341 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 60342 onClick: () => onToggle(!isOpen), 60343 "aria-expanded": isOpen, 60344 children: (0,external_wp_i18n_namespaceObject.__)('Change design') 60345 }) 60346 }); 60347 }, 60348 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 60349 className: "block-editor-block-toolbar-change-design-content-wrapper", 60350 paddingSize: "none", 60351 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_patterns_list, { 60352 blockPatterns: sameCategoryPatternsWithSingleWrapper, 60353 onClickPattern: onClickPattern, 60354 showTitlesAsTooltip: true 60355 }) 60356 }) 60357 }); 60358 } 60359 60360 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/switch-section-style.js 60361 /** 60362 * WordPress dependencies 60363 */ 60364 60365 60366 60367 60368 60369 /** 60370 * Internal dependencies 60371 */ 60372 60373 60374 60375 60376 60377 60378 60379 const styleIcon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.SVG, { 60380 viewBox: "0 0 24 24", 60381 xmlns: "http://www.w3.org/2000/svg", 60382 width: "24", 60383 height: "24", 60384 "aria-hidden": "true", 60385 focusable: "false", 60386 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Path, { 60387 d: "M17.2 10.9c-.5-1-1.2-2.1-2.1-3.2-.6-.9-1.3-1.7-2.1-2.6L12 4l-1 1.1c-.6.9-1.3 1.7-2 2.6-.8 1.2-1.5 2.3-2 3.2-.6 1.2-1 2.2-1 3 0 3.4 2.7 6.1 6.1 6.1s6.1-2.7 6.1-6.1c0-.8-.3-1.8-1-3z" 60388 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Path, { 60389 stroke: "currentColor", 60390 strokeWidth: "1.5", 60391 d: "M17.2 10.9c-.5-1-1.2-2.1-2.1-3.2-.6-.9-1.3-1.7-2.1-2.6L12 4l-1 1.1c-.6.9-1.3 1.7-2 2.6-.8 1.2-1.5 2.3-2 3.2-.6 1.2-1 2.2-1 3 0 3.4 2.7 6.1 6.1 6.1s6.1-2.7 6.1-6.1c0-.8-.3-1.8-1-3z" 60392 })] 60393 }); 60394 function SwitchSectionStyle({ 60395 clientId 60396 }) { 60397 var _mergedConfig$setting, _mergedConfig$styles; 60398 const { 60399 stylesToRender, 60400 activeStyle, 60401 className 60402 } = useStylesForBlocks({ 60403 clientId 60404 }); 60405 const { 60406 updateBlockAttributes 60407 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 60408 60409 // Get global styles data 60410 const { 60411 merged: mergedConfig 60412 } = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext); 60413 const { 60414 globalSettings, 60415 globalStyles, 60416 blockName 60417 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 60418 const settings = select(store).getSettings(); 60419 return { 60420 globalSettings: settings.__experimentalFeatures, 60421 globalStyles: settings[globalStylesDataKey], 60422 blockName: select(store).getBlockName(clientId) 60423 }; 60424 }, [clientId]); 60425 60426 // Get the background color for the active style 60427 const activeStyleBackground = activeStyle?.name ? getVariationStylesWithRefValues({ 60428 settings: (_mergedConfig$setting = mergedConfig?.settings) !== null && _mergedConfig$setting !== void 0 ? _mergedConfig$setting : globalSettings, 60429 styles: (_mergedConfig$styles = mergedConfig?.styles) !== null && _mergedConfig$styles !== void 0 ? _mergedConfig$styles : globalStyles 60430 }, blockName, activeStyle.name)?.color?.background : undefined; 60431 if (!stylesToRender || stylesToRender.length === 0) { 60432 return null; 60433 } 60434 const handleStyleSwitch = () => { 60435 const currentIndex = stylesToRender.findIndex(style => style.name === activeStyle.name); 60436 const nextIndex = (currentIndex + 1) % stylesToRender.length; 60437 const nextStyle = stylesToRender[nextIndex]; 60438 const styleClassName = replaceActiveStyle(className, activeStyle, nextStyle); 60439 updateBlockAttributes(clientId, { 60440 className: styleClassName 60441 }); 60442 }; 60443 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 60444 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 60445 onClick: handleStyleSwitch, 60446 label: (0,external_wp_i18n_namespaceObject.__)('Shuffle styles'), 60447 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 60448 icon: styleIcon, 60449 style: { 60450 fill: activeStyleBackground || 'transparent' 60451 } 60452 }) 60453 }) 60454 }); 60455 } 60456 /* harmony default export */ const switch_section_style = (SwitchSectionStyle); 60457 60458 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/index.js 60459 /** 60460 * External dependencies 60461 */ 60462 60463 60464 /** 60465 * WordPress dependencies 60466 */ 60467 60468 60469 60470 60471 60472 60473 60474 /** 60475 * Internal dependencies 60476 */ 60477 60478 60479 60480 60481 60482 60483 60484 60485 60486 60487 60488 60489 60490 60491 60492 60493 60494 60495 /** 60496 * Renders the block toolbar. 60497 * 60498 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md 60499 * 60500 * @param {Object} props Components props. 60501 * @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality. 60502 * @param {boolean} props.focusOnMount Focus the toolbar when mounted. 60503 * @param {number} props.__experimentalInitialIndex The initial index of the toolbar item to focus. 60504 * @param {Function} props.__experimentalOnIndexChange Callback function to be called when the index of the focused toolbar item changes. 60505 * @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons. 60506 */ 60507 60508 function PrivateBlockToolbar({ 60509 hideDragHandle, 60510 focusOnMount, 60511 __experimentalInitialIndex, 60512 __experimentalOnIndexChange, 60513 variant = 'unstyled' 60514 }) { 60515 const { 60516 blockClientId, 60517 blockClientIds, 60518 isDefaultEditingMode, 60519 blockType, 60520 toolbarKey, 60521 shouldShowVisualToolbar, 60522 showParentSelector, 60523 isUsingBindings, 60524 hasParentPattern, 60525 hasContentOnlyLocking, 60526 showShuffleButton, 60527 showSlots, 60528 showGroupButtons, 60529 showLockButtons, 60530 showSwitchSectionStyleButton, 60531 hasFixedToolbar, 60532 isNavigationMode 60533 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 60534 const { 60535 getBlockName, 60536 getBlockMode, 60537 getBlockParents, 60538 getSelectedBlockClientIds, 60539 isBlockValid, 60540 getBlockEditingMode, 60541 getBlockAttributes, 60542 getBlockParentsByBlockName, 60543 getTemplateLock, 60544 getSettings, 60545 getParentSectionBlock, 60546 isZoomOut, 60547 isNavigationMode: _isNavigationMode 60548 } = unlock(select(store)); 60549 const selectedBlockClientIds = getSelectedBlockClientIds(); 60550 const selectedBlockClientId = selectedBlockClientIds[0]; 60551 const parents = getBlockParents(selectedBlockClientId); 60552 const parentSection = getParentSectionBlock(selectedBlockClientId); 60553 const parentClientId = parentSection !== null && parentSection !== void 0 ? parentSection : parents[parents.length - 1]; 60554 const parentBlockName = getBlockName(parentClientId); 60555 const parentBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(parentBlockName); 60556 const editingMode = getBlockEditingMode(selectedBlockClientId); 60557 const _isDefaultEditingMode = editingMode === 'default'; 60558 const _blockName = getBlockName(selectedBlockClientId); 60559 const isValid = selectedBlockClientIds.every(id => isBlockValid(id)); 60560 const isVisual = selectedBlockClientIds.every(id => getBlockMode(id) === 'visual'); 60561 const _isUsingBindings = selectedBlockClientIds.every(clientId => !!getBlockAttributes(clientId)?.metadata?.bindings); 60562 const _hasParentPattern = selectedBlockClientIds.every(clientId => getBlockParentsByBlockName(clientId, 'core/block', true).length > 0); 60563 60564 // If one or more selected blocks are locked, do not show the BlockGroupToolbar. 60565 const _hasTemplateLock = selectedBlockClientIds.some(id => getTemplateLock(id) === 'contentOnly'); 60566 const _isZoomOut = isZoomOut(); 60567 return { 60568 blockClientId: selectedBlockClientId, 60569 blockClientIds: selectedBlockClientIds, 60570 isDefaultEditingMode: _isDefaultEditingMode, 60571 blockType: selectedBlockClientId && (0,external_wp_blocks_namespaceObject.getBlockType)(_blockName), 60572 shouldShowVisualToolbar: isValid && isVisual, 60573 toolbarKey: `$selectedBlockClientId}$parentClientId}`, 60574 showParentSelector: !_isZoomOut && parentBlockType && editingMode !== 'contentOnly' && getBlockEditingMode(parentClientId) !== 'disabled' && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(parentBlockType, '__experimentalParentSelector', true) && selectedBlockClientIds.length === 1, 60575 isUsingBindings: _isUsingBindings, 60576 hasParentPattern: _hasParentPattern, 60577 hasContentOnlyLocking: _hasTemplateLock, 60578 showShuffleButton: _isZoomOut, 60579 showSlots: !_isZoomOut, 60580 showGroupButtons: !_isZoomOut, 60581 showLockButtons: !_isZoomOut, 60582 showSwitchSectionStyleButton: _isZoomOut, 60583 hasFixedToolbar: getSettings().hasFixedToolbar, 60584 isNavigationMode: _isNavigationMode() 60585 }; 60586 }, []); 60587 const toolbarWrapperRef = (0,external_wp_element_namespaceObject.useRef)(null); 60588 60589 // Handles highlighting the current block outline on hover or focus of the 60590 // block type toolbar area. 60591 const nodeRef = (0,external_wp_element_namespaceObject.useRef)(); 60592 const showHoveredOrFocusedGestures = useShowHoveredOrFocusedGestures({ 60593 ref: nodeRef 60594 }); 60595 const isLargeViewport = !(0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 60596 const hasBlockToolbar = useHasBlockToolbar(); 60597 if (!hasBlockToolbar) { 60598 return null; 60599 } 60600 const isMultiToolbar = blockClientIds.length > 1; 60601 const isSynced = (0,external_wp_blocks_namespaceObject.isReusableBlock)(blockType) || (0,external_wp_blocks_namespaceObject.isTemplatePart)(blockType); 60602 60603 // Shifts the toolbar to make room for the parent block selector. 60604 const classes = dist_clsx('block-editor-block-contextual-toolbar', { 60605 'has-parent': showParentSelector, 60606 'is-inverted-toolbar': isNavigationMode && !hasFixedToolbar 60607 }); 60608 const innerClasses = dist_clsx('block-editor-block-toolbar', { 60609 'is-synced': isSynced, 60610 'is-connected': isUsingBindings 60611 }); 60612 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(NavigableToolbar, { 60613 focusEditorOnEscape: true, 60614 className: classes 60615 /* translators: accessibility text for the block toolbar */, 60616 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block tools') 60617 // The variant is applied as "toolbar" when undefined, which is the black border style of the dropdown from the toolbar popover. 60618 , 60619 variant: variant === 'toolbar' ? undefined : variant, 60620 focusOnMount: focusOnMount, 60621 __experimentalInitialIndex: __experimentalInitialIndex, 60622 __experimentalOnIndexChange: __experimentalOnIndexChange 60623 // Resets the index whenever the active block changes so 60624 // this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169 60625 , 60626 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 60627 ref: toolbarWrapperRef, 60628 className: innerClasses, 60629 children: [showParentSelector && !isMultiToolbar && isLargeViewport && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockParentSelector, {}), (shouldShowVisualToolbar || isMultiToolbar) && !hasParentPattern && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 60630 ref: nodeRef, 60631 ...showHoveredOrFocusedGestures, 60632 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.ToolbarGroup, { 60633 className: "block-editor-block-toolbar__block-controls", 60634 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_switcher, { 60635 clientIds: blockClientIds 60636 }), !isMultiToolbar && isDefaultEditingMode && showLockButtons && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockLockToolbar, { 60637 clientId: blockClientId 60638 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_mover, { 60639 clientIds: blockClientIds, 60640 hideDragHandle: hideDragHandle 60641 })] 60642 }) 60643 }), !hasContentOnlyLocking && shouldShowVisualToolbar && isMultiToolbar && showGroupButtons && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(toolbar, {}), showShuffleButton && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ChangeDesign, { 60644 clientId: blockClientIds[0] 60645 }), showSwitchSectionStyleButton && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(switch_section_style, { 60646 clientId: blockClientIds[0] 60647 }), shouldShowVisualToolbar && showSlots && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 60648 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls.Slot, { 60649 group: "parent", 60650 className: "block-editor-block-toolbar__slot" 60651 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls.Slot, { 60652 group: "block", 60653 className: "block-editor-block-toolbar__slot" 60654 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls.Slot, { 60655 className: "block-editor-block-toolbar__slot" 60656 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls.Slot, { 60657 group: "inline", 60658 className: "block-editor-block-toolbar__slot" 60659 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls.Slot, { 60660 group: "other", 60661 className: "block-editor-block-toolbar__slot" 60662 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_name_context.Provider, { 60663 value: blockType?.name, 60664 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_toolbar_last_item.Slot, {}) 60665 })] 60666 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockEditVisuallyButton, { 60667 clientIds: blockClientIds 60668 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_settings_menu, { 60669 clientIds: blockClientIds 60670 })] 60671 }) 60672 }, toolbarKey); 60673 } 60674 60675 /** 60676 * Renders the block toolbar. 60677 * 60678 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md 60679 * 60680 * @param {Object} props Components props. 60681 * @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality. 60682 * @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons. 60683 */ 60684 function BlockToolbar({ 60685 hideDragHandle, 60686 variant 60687 }) { 60688 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockToolbar, { 60689 hideDragHandle: hideDragHandle, 60690 variant: variant, 60691 focusOnMount: undefined, 60692 __experimentalInitialIndex: undefined, 60693 __experimentalOnIndexChange: undefined 60694 }); 60695 } 60696 60697 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/block-toolbar-popover.js 60698 /** 60699 * External dependencies 60700 */ 60701 60702 /** 60703 * WordPress dependencies 60704 */ 60705 60706 60707 60708 /** 60709 * Internal dependencies 60710 */ 60711 60712 60713 60714 60715 60716 60717 function BlockToolbarPopover({ 60718 clientId, 60719 isTyping, 60720 __unstableContentRef 60721 }) { 60722 const { 60723 capturingClientId, 60724 isInsertionPointVisible, 60725 lastClientId 60726 } = useSelectedBlockToolProps(clientId); 60727 60728 // Stores the active toolbar item index so the block toolbar can return focus 60729 // to it when re-mounting. 60730 const initialToolbarItemIndexRef = (0,external_wp_element_namespaceObject.useRef)(); 60731 (0,external_wp_element_namespaceObject.useEffect)(() => { 60732 // Resets the index whenever the active block changes so this is not 60733 // persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169 60734 initialToolbarItemIndexRef.current = undefined; 60735 }, [clientId]); 60736 const { 60737 stopTyping 60738 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 60739 const isToolbarForcedRef = (0,external_wp_element_namespaceObject.useRef)(false); 60740 (0,external_wp_keyboardShortcuts_namespaceObject.useShortcut)('core/block-editor/focus-toolbar', () => { 60741 isToolbarForcedRef.current = true; 60742 stopTyping(true); 60743 }); 60744 (0,external_wp_element_namespaceObject.useEffect)(() => { 60745 isToolbarForcedRef.current = false; 60746 }); 60747 60748 // If the block has a parent with __experimentalCaptureToolbars enabled, 60749 // the toolbar should be positioned over the topmost capturing parent. 60750 const clientIdToPositionOver = capturingClientId || clientId; 60751 const popoverProps = useBlockToolbarPopoverProps({ 60752 contentElement: __unstableContentRef?.current, 60753 clientId: clientIdToPositionOver 60754 }); 60755 return !isTyping && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockPopover, { 60756 clientId: clientIdToPositionOver, 60757 bottomClientId: lastClientId, 60758 className: dist_clsx('block-editor-block-list__block-popover', { 60759 'is-insertion-point-visible': isInsertionPointVisible 60760 }), 60761 resize: false, 60762 ...popoverProps, 60763 __unstableContentRef: __unstableContentRef, 60764 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateBlockToolbar 60765 // If the toolbar is being shown because of being forced 60766 // it should focus the toolbar right after the mount. 60767 , { 60768 focusOnMount: isToolbarForcedRef.current, 60769 __experimentalInitialIndex: initialToolbarItemIndexRef.current, 60770 __experimentalOnIndexChange: index => { 60771 initialToolbarItemIndexRef.current = index; 60772 }, 60773 variant: "toolbar" 60774 }) 60775 }); 60776 } 60777 60778 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/zoom-out-mode-inserter-button.js 60779 /** 60780 * External dependencies 60781 */ 60782 60783 60784 /** 60785 * WordPress dependencies 60786 */ 60787 60788 60789 60790 60791 function ZoomOutModeInserterButton({ 60792 onClick 60793 }) { 60794 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 60795 variant: "primary", 60796 icon: library_plus, 60797 size: "compact", 60798 className: dist_clsx('block-editor-button-pattern-inserter__button', 'block-editor-block-tools__zoom-out-mode-inserter-button'), 60799 onClick: onClick, 60800 label: (0,external_wp_i18n_namespaceObject._x)('Add pattern', 'Generic label for pattern inserter button') 60801 }); 60802 } 60803 /* harmony default export */ const zoom_out_mode_inserter_button = (ZoomOutModeInserterButton); 60804 60805 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/zoom-out-mode-inserters.js 60806 /** 60807 * WordPress dependencies 60808 */ 60809 60810 60811 60812 /** 60813 * Internal dependencies 60814 */ 60815 60816 60817 60818 60819 60820 function ZoomOutModeInserters() { 60821 const [isReady, setIsReady] = (0,external_wp_element_namespaceObject.useState)(false); 60822 const { 60823 hasSelection, 60824 blockOrder, 60825 setInserterIsOpened, 60826 sectionRootClientId, 60827 selectedBlockClientId, 60828 blockInsertionPoint, 60829 insertionPointVisible 60830 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 60831 const { 60832 getSettings, 60833 getBlockOrder, 60834 getSelectionStart, 60835 getSelectedBlockClientId, 60836 getSectionRootClientId, 60837 getBlockInsertionPoint, 60838 isBlockInsertionPointVisible 60839 } = unlock(select(store)); 60840 const root = getSectionRootClientId(); 60841 return { 60842 hasSelection: !!getSelectionStart().clientId, 60843 blockOrder: getBlockOrder(root), 60844 sectionRootClientId: root, 60845 setInserterIsOpened: getSettings().__experimentalSetIsInserterOpened, 60846 selectedBlockClientId: getSelectedBlockClientId(), 60847 blockInsertionPoint: getBlockInsertionPoint(), 60848 insertionPointVisible: isBlockInsertionPointVisible() 60849 }; 60850 }, []); 60851 60852 // eslint-disable-next-line @wordpress/no-unused-vars-before-return 60853 const { 60854 showInsertionPoint 60855 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 60856 60857 // Defer the initial rendering to avoid the jumps due to the animation. 60858 (0,external_wp_element_namespaceObject.useEffect)(() => { 60859 const timeout = setTimeout(() => { 60860 setIsReady(true); 60861 }, 500); 60862 return () => { 60863 clearTimeout(timeout); 60864 }; 60865 }, []); 60866 if (!isReady || !hasSelection) { 60867 return null; 60868 } 60869 const previousClientId = selectedBlockClientId; 60870 const index = blockOrder.findIndex(clientId => selectedBlockClientId === clientId); 60871 const insertionIndex = index + 1; 60872 const nextClientId = blockOrder[insertionIndex]; 60873 60874 // If the block insertion point is visible, and the insertion 60875 // Indices match then we don't need to render the inserter. 60876 if (insertionPointVisible && blockInsertionPoint?.index === insertionIndex) { 60877 return null; 60878 } 60879 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inbetween, { 60880 previousClientId: previousClientId, 60881 nextClientId: nextClientId, 60882 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(zoom_out_mode_inserter_button, { 60883 onClick: () => { 60884 setInserterIsOpened({ 60885 rootClientId: sectionRootClientId, 60886 insertionIndex, 60887 tab: 'patterns', 60888 category: 'all' 60889 }); 60890 showInsertionPoint(sectionRootClientId, insertionIndex, { 60891 operation: 'insert' 60892 }); 60893 } 60894 }) 60895 }); 60896 } 60897 /* harmony default export */ const zoom_out_mode_inserters = (ZoomOutModeInserters); 60898 60899 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/use-show-block-tools.js 60900 /** 60901 * WordPress dependencies 60902 */ 60903 60904 60905 60906 /** 60907 * Internal dependencies 60908 */ 60909 60910 60911 60912 /** 60913 * Source of truth for which block tools are showing in the block editor. 60914 * 60915 * @return {Object} Object of which block tools will be shown. 60916 */ 60917 function useShowBlockTools() { 60918 return (0,external_wp_data_namespaceObject.useSelect)(select => { 60919 const { 60920 getSelectedBlockClientId, 60921 getFirstMultiSelectedBlockClientId, 60922 getBlock, 60923 getBlockMode, 60924 getSettings, 60925 __unstableGetEditorMode, 60926 isTyping 60927 } = unlock(select(store)); 60928 const clientId = getSelectedBlockClientId() || getFirstMultiSelectedBlockClientId(); 60929 const block = getBlock(clientId); 60930 const editorMode = __unstableGetEditorMode(); 60931 const hasSelectedBlock = !!clientId && !!block; 60932 const isEmptyDefaultBlock = hasSelectedBlock && (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(block) && getBlockMode(clientId) !== 'html'; 60933 const _showEmptyBlockSideInserter = clientId && !isTyping() && 60934 // Hide the block inserter on the navigation mode. 60935 // See https://github.com/WordPress/gutenberg/pull/66636#discussion_r1824728483. 60936 editorMode !== 'navigation' && isEmptyDefaultBlock; 60937 const _showBlockToolbarPopover = !getSettings().hasFixedToolbar && !_showEmptyBlockSideInserter && hasSelectedBlock && !isEmptyDefaultBlock; 60938 return { 60939 showEmptyBlockSideInserter: _showEmptyBlockSideInserter, 60940 showBlockToolbarPopover: _showBlockToolbarPopover 60941 }; 60942 }, []); 60943 } 60944 60945 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-tools/index.js 60946 /** 60947 * WordPress dependencies 60948 */ 60949 60950 60951 60952 60953 60954 60955 60956 60957 60958 /** 60959 * Internal dependencies 60960 */ 60961 60962 60963 60964 60965 60966 60967 60968 60969 60970 function block_tools_selector(select) { 60971 const { 60972 getSelectedBlockClientId, 60973 getFirstMultiSelectedBlockClientId, 60974 getSettings, 60975 isTyping, 60976 isDragging, 60977 isZoomOut 60978 } = unlock(select(store)); 60979 const clientId = getSelectedBlockClientId() || getFirstMultiSelectedBlockClientId(); 60980 return { 60981 clientId, 60982 hasFixedToolbar: getSettings().hasFixedToolbar, 60983 isTyping: isTyping(), 60984 isZoomOutMode: isZoomOut(), 60985 isDragging: isDragging() 60986 }; 60987 } 60988 60989 /** 60990 * Renders block tools (the block toolbar, select/navigation mode toolbar, the 60991 * insertion point and a slot for the inline rich text toolbar). Must be wrapped 60992 * around the block content and editor styles wrapper or iframe. 60993 * 60994 * @param {Object} $0 Props. 60995 * @param {Object} $0.children The block content and style container. 60996 * @param {Object} $0.__unstableContentRef Ref holding the content scroll container. 60997 */ 60998 function BlockTools({ 60999 children, 61000 __unstableContentRef, 61001 ...props 61002 }) { 61003 const { 61004 clientId, 61005 hasFixedToolbar, 61006 isTyping, 61007 isZoomOutMode, 61008 isDragging 61009 } = (0,external_wp_data_namespaceObject.useSelect)(block_tools_selector, []); 61010 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 61011 const { 61012 getBlocksByClientId, 61013 getSelectedBlockClientIds, 61014 getBlockRootClientId, 61015 isGroupable 61016 } = (0,external_wp_data_namespaceObject.useSelect)(store); 61017 const { 61018 getGroupingBlockName 61019 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 61020 const { 61021 showEmptyBlockSideInserter, 61022 showBlockToolbarPopover 61023 } = useShowBlockTools(); 61024 const { 61025 duplicateBlocks, 61026 removeBlocks, 61027 replaceBlocks, 61028 insertAfterBlock, 61029 insertBeforeBlock, 61030 selectBlock, 61031 moveBlocksUp, 61032 moveBlocksDown, 61033 expandBlock 61034 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 61035 function onKeyDown(event) { 61036 if (event.defaultPrevented) { 61037 return; 61038 } 61039 if (isMatch('core/block-editor/move-up', event) || isMatch('core/block-editor/move-down', event)) { 61040 const clientIds = getSelectedBlockClientIds(); 61041 if (clientIds.length) { 61042 event.preventDefault(); 61043 const rootClientId = getBlockRootClientId(clientIds[0]); 61044 const direction = isMatch('core/block-editor/move-up', event) ? 'up' : 'down'; 61045 if (direction === 'up') { 61046 moveBlocksUp(clientIds, rootClientId); 61047 } else { 61048 moveBlocksDown(clientIds, rootClientId); 61049 } 61050 const blockLength = Array.isArray(clientIds) ? clientIds.length : 1; 61051 const message = (0,external_wp_i18n_namespaceObject.sprintf)( 61052 // translators: %d: the name of the block that has been moved 61053 (0,external_wp_i18n_namespaceObject._n)('%d block moved.', '%d blocks moved.', clientIds.length), blockLength); 61054 (0,external_wp_a11y_namespaceObject.speak)(message); 61055 } 61056 } else if (isMatch('core/block-editor/duplicate', event)) { 61057 const clientIds = getSelectedBlockClientIds(); 61058 if (clientIds.length) { 61059 event.preventDefault(); 61060 duplicateBlocks(clientIds); 61061 } 61062 } else if (isMatch('core/block-editor/remove', event)) { 61063 const clientIds = getSelectedBlockClientIds(); 61064 if (clientIds.length) { 61065 event.preventDefault(); 61066 removeBlocks(clientIds); 61067 } 61068 } else if (isMatch('core/block-editor/insert-after', event)) { 61069 const clientIds = getSelectedBlockClientIds(); 61070 if (clientIds.length) { 61071 event.preventDefault(); 61072 insertAfterBlock(clientIds[clientIds.length - 1]); 61073 } 61074 } else if (isMatch('core/block-editor/insert-before', event)) { 61075 const clientIds = getSelectedBlockClientIds(); 61076 if (clientIds.length) { 61077 event.preventDefault(); 61078 insertBeforeBlock(clientIds[0]); 61079 } 61080 } else if (isMatch('core/block-editor/unselect', event)) { 61081 if (event.target.closest('[role=toolbar]')) { 61082 // This shouldn't be necessary, but we have a combination of a few things all combining to create a situation where: 61083 // - 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 61084 // - Since we can't use the React tree, we use the DOM tree which _should_ handle the event bubbling correctly from a `createPortal` element. 61085 // - This bubbles via the React tree, which hits this `unselect` escape keypress before the block toolbar DOM event listener has access to it. 61086 // 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. 61087 return; 61088 } 61089 const clientIds = getSelectedBlockClientIds(); 61090 if (clientIds.length > 1) { 61091 event.preventDefault(); 61092 // If there is more than one block selected, select the first 61093 // block so that focus is directed back to the beginning of the selection. 61094 // In effect, to the user this feels like deselecting the multi-selection. 61095 selectBlock(clientIds[0]); 61096 } 61097 } else if (isMatch('core/block-editor/collapse-list-view', event)) { 61098 // If focus is currently within a text field, such as a rich text block or other editable field, 61099 // skip collapsing the list view, and allow the keyboard shortcut to be handled by the text field. 61100 // This condition checks for both the active element and the active element within an iframed editor. 61101 if ((0,external_wp_dom_namespaceObject.isTextField)(event.target) || (0,external_wp_dom_namespaceObject.isTextField)(event.target?.contentWindow?.document?.activeElement)) { 61102 return; 61103 } 61104 event.preventDefault(); 61105 expandBlock(clientId); 61106 } else if (isMatch('core/block-editor/group', event)) { 61107 const clientIds = getSelectedBlockClientIds(); 61108 if (clientIds.length > 1 && isGroupable(clientIds)) { 61109 event.preventDefault(); 61110 const blocks = getBlocksByClientId(clientIds); 61111 const groupingBlockName = getGroupingBlockName(); 61112 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, groupingBlockName); 61113 replaceBlocks(clientIds, newBlocks); 61114 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Selected blocks are grouped.')); 61115 } 61116 } 61117 } 61118 const blockToolbarRef = use_popover_scroll(__unstableContentRef); 61119 const blockToolbarAfterRef = use_popover_scroll(__unstableContentRef); 61120 return ( 61121 /*#__PURE__*/ 61122 // eslint-disable-next-line jsx-a11y/no-static-element-interactions 61123 (0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 61124 ...props, 61125 onKeyDown: onKeyDown, 61126 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(insertion_point_InsertionPointOpenRef.Provider, { 61127 value: (0,external_wp_element_namespaceObject.useRef)(false), 61128 children: [!isTyping && !isZoomOutMode && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InsertionPoint, { 61129 __unstableContentRef: __unstableContentRef 61130 }), showEmptyBlockSideInserter && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EmptyBlockInserter, { 61131 __unstableContentRef: __unstableContentRef, 61132 clientId: clientId 61133 }), showBlockToolbarPopover && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockToolbarPopover, { 61134 __unstableContentRef: __unstableContentRef, 61135 clientId: clientId, 61136 isTyping: isTyping 61137 }), !isZoomOutMode && !hasFixedToolbar && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover.Slot, { 61138 name: "block-toolbar", 61139 ref: blockToolbarRef 61140 }), children, /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover.Slot, { 61141 name: "__unstable-block-tools-after", 61142 ref: blockToolbarAfterRef 61143 }), isZoomOutMode && !isDragging && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(zoom_out_mode_inserters, { 61144 __unstableContentRef: __unstableContentRef 61145 })] 61146 }) 61147 }) 61148 ); 61149 } 61150 61151 ;// external ["wp","commands"] 61152 const external_wp_commands_namespaceObject = window["wp"]["commands"]; 61153 ;// ./node_modules/@wordpress/icons/build-module/library/ungroup.js 61154 /** 61155 * WordPress dependencies 61156 */ 61157 61158 61159 const ungroup = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 61160 xmlns: "http://www.w3.org/2000/svg", 61161 viewBox: "0 0 24 24", 61162 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 61163 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" 61164 }) 61165 }); 61166 /* harmony default export */ const library_ungroup = (ungroup); 61167 61168 ;// ./node_modules/@wordpress/icons/build-module/library/trash.js 61169 /** 61170 * WordPress dependencies 61171 */ 61172 61173 61174 const trash = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 61175 xmlns: "http://www.w3.org/2000/svg", 61176 viewBox: "0 0 24 24", 61177 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 61178 fillRule: "evenodd", 61179 clipRule: "evenodd", 61180 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" 61181 }) 61182 }); 61183 /* harmony default export */ const library_trash = (trash); 61184 61185 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-block-commands/index.js 61186 /** 61187 * WordPress dependencies 61188 */ 61189 61190 61191 61192 61193 61194 61195 /** 61196 * Internal dependencies 61197 */ 61198 61199 61200 61201 const getTransformCommands = () => function useTransformCommands() { 61202 const { 61203 replaceBlocks, 61204 multiSelect 61205 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 61206 const { 61207 blocks, 61208 clientIds, 61209 canRemove, 61210 possibleBlockTransformations, 61211 invalidSelection 61212 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 61213 const { 61214 getBlockRootClientId, 61215 getBlockTransformItems, 61216 getSelectedBlockClientIds, 61217 getBlocksByClientId, 61218 canRemoveBlocks 61219 } = select(store); 61220 const selectedBlockClientIds = getSelectedBlockClientIds(); 61221 const selectedBlocks = getBlocksByClientId(selectedBlockClientIds); 61222 61223 // selectedBlocks can have `null`s when something tries to call `selectBlock` with an inexistent clientId. 61224 // These nulls will cause fatal errors down the line. 61225 // In order to prevent discrepancies between selectedBlockClientIds and selectedBlocks, we effectively treat the entire selection as invalid. 61226 // @see https://github.com/WordPress/gutenberg/pull/59410#issuecomment-2006304536 61227 if (selectedBlocks.filter(block => !block).length > 0) { 61228 return { 61229 invalidSelection: true 61230 }; 61231 } 61232 const rootClientId = getBlockRootClientId(selectedBlockClientIds[0]); 61233 return { 61234 blocks: selectedBlocks, 61235 clientIds: selectedBlockClientIds, 61236 possibleBlockTransformations: getBlockTransformItems(selectedBlocks, rootClientId), 61237 canRemove: canRemoveBlocks(selectedBlockClientIds), 61238 invalidSelection: false 61239 }; 61240 }, []); 61241 if (invalidSelection) { 61242 return { 61243 isLoading: false, 61244 commands: [] 61245 }; 61246 } 61247 const isTemplate = blocks.length === 1 && (0,external_wp_blocks_namespaceObject.isTemplatePart)(blocks[0]); 61248 function selectForMultipleBlocks(insertedBlocks) { 61249 if (insertedBlocks.length > 1) { 61250 multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId); 61251 } 61252 } 61253 61254 // Simple block transformation based on the `Block Transforms` API. 61255 function onBlockTransform(name) { 61256 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, name); 61257 replaceBlocks(clientIds, newBlocks); 61258 selectForMultipleBlocks(newBlocks); 61259 } 61260 61261 /** 61262 * The `isTemplate` check is a stopgap solution here. 61263 * Ideally, the Transforms API should handle this 61264 * by allowing to exclude blocks from wildcard transformations. 61265 */ 61266 const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate; 61267 if (!clientIds || clientIds.length < 1 || !hasPossibleBlockTransformations) { 61268 return { 61269 isLoading: false, 61270 commands: [] 61271 }; 61272 } 61273 const commands = possibleBlockTransformations.map(transformation => { 61274 const { 61275 name, 61276 title, 61277 icon 61278 } = transformation; 61279 return { 61280 name: 'core/block-editor/transform-to-' + name.replace('/', '-'), 61281 /* translators: %s: Block or block variation name. */ 61282 label: (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Transform to %s'), title), 61283 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 61284 icon: icon 61285 }), 61286 callback: ({ 61287 close 61288 }) => { 61289 onBlockTransform(name); 61290 close(); 61291 } 61292 }; 61293 }); 61294 return { 61295 isLoading: false, 61296 commands 61297 }; 61298 }; 61299 const getQuickActionsCommands = () => function useQuickActionsCommands() { 61300 const { 61301 clientIds, 61302 isUngroupable, 61303 isGroupable 61304 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 61305 const { 61306 getSelectedBlockClientIds, 61307 isUngroupable: _isUngroupable, 61308 isGroupable: _isGroupable 61309 } = select(store); 61310 const selectedBlockClientIds = getSelectedBlockClientIds(); 61311 return { 61312 clientIds: selectedBlockClientIds, 61313 isUngroupable: _isUngroupable(), 61314 isGroupable: _isGroupable() 61315 }; 61316 }, []); 61317 const { 61318 canInsertBlockType, 61319 getBlockRootClientId, 61320 getBlocksByClientId, 61321 canRemoveBlocks 61322 } = (0,external_wp_data_namespaceObject.useSelect)(store); 61323 const { 61324 getDefaultBlockName, 61325 getGroupingBlockName 61326 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 61327 const blocks = getBlocksByClientId(clientIds); 61328 const { 61329 removeBlocks, 61330 replaceBlocks, 61331 duplicateBlocks, 61332 insertAfterBlock, 61333 insertBeforeBlock 61334 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 61335 const onGroup = () => { 61336 if (!blocks.length) { 61337 return; 61338 } 61339 const groupingBlockName = getGroupingBlockName(); 61340 61341 // Activate the `transform` on `core/group` which does the conversion. 61342 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, groupingBlockName); 61343 if (!newBlocks) { 61344 return; 61345 } 61346 replaceBlocks(clientIds, newBlocks); 61347 }; 61348 const onUngroup = () => { 61349 if (!blocks.length) { 61350 return; 61351 } 61352 const innerBlocks = blocks[0].innerBlocks; 61353 if (!innerBlocks.length) { 61354 return; 61355 } 61356 replaceBlocks(clientIds, innerBlocks); 61357 }; 61358 if (!clientIds || clientIds.length < 1) { 61359 return { 61360 isLoading: false, 61361 commands: [] 61362 }; 61363 } 61364 const rootClientId = getBlockRootClientId(clientIds[0]); 61365 const canInsertDefaultBlock = canInsertBlockType(getDefaultBlockName(), rootClientId); 61366 const canDuplicate = blocks.every(block => { 61367 return !!block && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'multiple', true) && canInsertBlockType(block.name, rootClientId); 61368 }); 61369 const canRemove = canRemoveBlocks(clientIds); 61370 const commands = []; 61371 if (canDuplicate) { 61372 commands.push({ 61373 name: 'duplicate', 61374 label: (0,external_wp_i18n_namespaceObject.__)('Duplicate'), 61375 callback: () => duplicateBlocks(clientIds, true), 61376 icon: library_copy 61377 }); 61378 } 61379 if (canInsertDefaultBlock) { 61380 commands.push({ 61381 name: 'add-before', 61382 label: (0,external_wp_i18n_namespaceObject.__)('Add before'), 61383 callback: () => { 61384 const clientId = Array.isArray(clientIds) ? clientIds[0] : clientId; 61385 insertBeforeBlock(clientId); 61386 }, 61387 icon: library_plus 61388 }, { 61389 name: 'add-after', 61390 label: (0,external_wp_i18n_namespaceObject.__)('Add after'), 61391 callback: () => { 61392 const clientId = Array.isArray(clientIds) ? clientIds[clientIds.length - 1] : clientId; 61393 insertAfterBlock(clientId); 61394 }, 61395 icon: library_plus 61396 }); 61397 } 61398 if (isGroupable) { 61399 commands.push({ 61400 name: 'Group', 61401 label: (0,external_wp_i18n_namespaceObject.__)('Group'), 61402 callback: onGroup, 61403 icon: library_group 61404 }); 61405 } 61406 if (isUngroupable) { 61407 commands.push({ 61408 name: 'ungroup', 61409 label: (0,external_wp_i18n_namespaceObject.__)('Ungroup'), 61410 callback: onUngroup, 61411 icon: library_ungroup 61412 }); 61413 } 61414 if (canRemove) { 61415 commands.push({ 61416 name: 'remove', 61417 label: (0,external_wp_i18n_namespaceObject.__)('Delete'), 61418 callback: () => removeBlocks(clientIds, true), 61419 icon: library_trash 61420 }); 61421 } 61422 return { 61423 isLoading: false, 61424 commands: commands.map(command => ({ 61425 ...command, 61426 name: 'core/block-editor/action-' + command.name, 61427 callback: ({ 61428 close 61429 }) => { 61430 command.callback(); 61431 close(); 61432 } 61433 })) 61434 }; 61435 }; 61436 const useBlockCommands = () => { 61437 (0,external_wp_commands_namespaceObject.useCommandLoader)({ 61438 name: 'core/block-editor/blockTransforms', 61439 hook: getTransformCommands() 61440 }); 61441 (0,external_wp_commands_namespaceObject.useCommandLoader)({ 61442 name: 'core/block-editor/blockQuickActions', 61443 hook: getQuickActionsCommands(), 61444 context: 'block-selection-edit' 61445 }); 61446 }; 61447 61448 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-canvas/index.js 61449 /** 61450 * WordPress dependencies 61451 */ 61452 61453 61454 61455 61456 /** 61457 * Internal dependencies 61458 */ 61459 61460 61461 61462 61463 61464 61465 61466 61467 61468 61469 61470 // EditorStyles is a memoized component, so avoid passing a new 61471 // object reference on each render. 61472 61473 const EDITOR_STYLE_TRANSFORM_OPTIONS = { 61474 // Don't transform selectors that already specify `.editor-styles-wrapper`. 61475 ignoredSelectors: [/\.editor-styles-wrapper/gi] 61476 }; 61477 function ExperimentalBlockCanvas({ 61478 shouldIframe = true, 61479 height = '300px', 61480 children = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockList, {}), 61481 styles, 61482 contentRef: contentRefProp, 61483 iframeProps 61484 }) { 61485 useBlockCommands(); 61486 const isTabletViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 61487 const resetTypingRef = useMouseMoveTypingReset(); 61488 const clearerRef = useBlockSelectionClearer(); 61489 const localRef = (0,external_wp_element_namespaceObject.useRef)(); 61490 const contentRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([contentRefProp, clearerRef, localRef]); 61491 const zoomLevel = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getZoomLevel(), []); 61492 const zoomOutIframeProps = zoomLevel !== 100 && !isTabletViewport ? { 61493 scale: zoomLevel, 61494 frameSize: '40px' 61495 } : {}; 61496 if (!shouldIframe) { 61497 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(BlockTools, { 61498 __unstableContentRef: localRef, 61499 className: "block-editor-block-canvas", 61500 style: { 61501 height 61502 }, 61503 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editor_styles, { 61504 styles: styles, 61505 scope: ":where(.editor-styles-wrapper)", 61506 transformOptions: EDITOR_STYLE_TRANSFORM_OPTIONS 61507 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(writing_flow, { 61508 ref: contentRef, 61509 className: "editor-styles-wrapper", 61510 tabIndex: -1, 61511 children: children 61512 })] 61513 }); 61514 } 61515 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockTools, { 61516 __unstableContentRef: localRef, 61517 className: "block-editor-block-canvas", 61518 style: { 61519 height, 61520 display: 'flex' 61521 }, 61522 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(iframe, { 61523 ...iframeProps, 61524 ...zoomOutIframeProps, 61525 ref: resetTypingRef, 61526 contentRef: contentRef, 61527 style: { 61528 ...iframeProps?.style 61529 }, 61530 name: "editor-canvas", 61531 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editor_styles, { 61532 styles: styles 61533 }), children] 61534 }) 61535 }); 61536 } 61537 61538 /** 61539 * BlockCanvas component is a component used to display the canvas of the block editor. 61540 * What we call the canvas is an iframe containing the block list that you can manipulate. 61541 * The component is also responsible of wiring up all the necessary hooks to enable 61542 * the keyboard navigation across blocks in the editor and inject content styles into the iframe. 61543 * 61544 * @example 61545 * 61546 * ```jsx 61547 * function MyBlockEditor() { 61548 * const [ blocks, updateBlocks ] = useState([]); 61549 * return ( 61550 * <BlockEditorProvider 61551 * value={ blocks } 61552 * onInput={ updateBlocks } 61553 * onChange={ persistBlocks } 61554 * > 61555 * <BlockCanvas height="400px" /> 61556 * </BlockEditorProvider> 61557 * ); 61558 * } 61559 * ``` 61560 * 61561 * @param {Object} props Component props. 61562 * @param {string} props.height Canvas height, defaults to 300px. 61563 * @param {Array} props.styles Content styles to inject into the iframe. 61564 * @param {Element} props.children Content of the canvas, defaults to the BlockList component. 61565 * @return {Element} Block Breadcrumb. 61566 */ 61567 function BlockCanvas({ 61568 children, 61569 height, 61570 styles 61571 }) { 61572 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ExperimentalBlockCanvas, { 61573 height: height, 61574 styles: styles, 61575 children: children 61576 }); 61577 } 61578 /* harmony default export */ const block_canvas = (BlockCanvas); 61579 61580 ;// ./node_modules/@wordpress/block-editor/build-module/components/color-style-selector/index.js 61581 /** 61582 * WordPress dependencies 61583 */ 61584 61585 61586 61587 61588 61589 const ColorSelectorSVGIcon = () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SVG, { 61590 xmlns: "http://www.w3.org/2000/svg", 61591 viewBox: "0 0 20 20", 61592 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Path, { 61593 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" 61594 }) 61595 }); 61596 61597 /** 61598 * Color Selector Icon component. 61599 * 61600 * @param {Object} props Component properties. 61601 * @param {Object} props.style Style object. 61602 * @param {string} props.className Class name for component. 61603 * 61604 * @return {*} React Icon component. 61605 */ 61606 const ColorSelectorIcon = ({ 61607 style, 61608 className 61609 }) => { 61610 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 61611 className: "block-library-colors-selector__icon-container", 61612 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 61613 className: `$className} block-library-colors-selector__state-selection`, 61614 style: style, 61615 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorSelectorSVGIcon, {}) 61616 }) 61617 }); 61618 }; 61619 61620 /** 61621 * Renders the Colors Selector Toolbar with the icon button. 61622 * 61623 * @param {Object} props Component properties. 61624 * @param {Object} props.TextColor Text color component that wraps icon. 61625 * @param {Object} props.BackgroundColor Background color component that wraps icon. 61626 * 61627 * @return {*} React toggle button component. 61628 */ 61629 const renderToggleComponent = ({ 61630 TextColor, 61631 BackgroundColor 61632 }) => ({ 61633 onToggle, 61634 isOpen 61635 }) => { 61636 const openOnArrowDown = event => { 61637 if (!isOpen && event.keyCode === external_wp_keycodes_namespaceObject.DOWN) { 61638 event.preventDefault(); 61639 onToggle(); 61640 } 61641 }; 61642 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 61643 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 61644 className: "components-toolbar__control block-library-colors-selector__toggle", 61645 label: (0,external_wp_i18n_namespaceObject.__)('Open Colors Selector'), 61646 onClick: onToggle, 61647 onKeyDown: openOnArrowDown, 61648 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BackgroundColor, { 61649 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TextColor, { 61650 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorSelectorIcon, {}) 61651 }) 61652 }) 61653 }) 61654 }); 61655 }; 61656 const BlockColorsStyleSelector = ({ 61657 children, 61658 ...other 61659 }) => { 61660 external_wp_deprecated_default()(`wp.blockEditor.BlockColorsStyleSelector`, { 61661 alternative: 'block supports API', 61662 since: '6.1', 61663 version: '6.3' 61664 }); 61665 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 61666 popoverProps: { 61667 placement: 'bottom-start' 61668 }, 61669 className: "block-library-colors-selector", 61670 contentClassName: "block-library-colors-selector__popover", 61671 renderToggle: renderToggleComponent(other), 61672 renderContent: () => children 61673 }); 61674 }; 61675 /* harmony default export */ const color_style_selector = (BlockColorsStyleSelector); 61676 61677 ;// ./node_modules/@wordpress/icons/build-module/library/list-view.js 61678 /** 61679 * WordPress dependencies 61680 */ 61681 61682 61683 const listView = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 61684 viewBox: "0 0 24 24", 61685 xmlns: "http://www.w3.org/2000/svg", 61686 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 61687 d: "M3 6h11v1.5H3V6Zm3.5 5.5h11V13h-11v-1.5ZM21 17H10v1.5h11V17Z" 61688 }) 61689 }); 61690 /* harmony default export */ const list_view = (listView); 61691 61692 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/context.js 61693 /** 61694 * WordPress dependencies 61695 */ 61696 61697 const ListViewContext = (0,external_wp_element_namespaceObject.createContext)({}); 61698 const useListViewContext = () => (0,external_wp_element_namespaceObject.useContext)(ListViewContext); 61699 61700 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/aria-referenced-text.js 61701 /** 61702 * WordPress dependencies 61703 */ 61704 61705 61706 /** 61707 * A component specifically designed to be used as an element referenced 61708 * by ARIA attributes such as `aria-labelledby` or `aria-describedby`. 61709 * 61710 * @param {Object} props Props. 61711 * @param {import('react').ReactNode} props.children 61712 */ 61713 61714 function AriaReferencedText({ 61715 children, 61716 ...props 61717 }) { 61718 const ref = (0,external_wp_element_namespaceObject.useRef)(); 61719 (0,external_wp_element_namespaceObject.useEffect)(() => { 61720 if (ref.current) { 61721 // This seems like a no-op, but it fixes a bug in Firefox where 61722 // it fails to recompute the text when only the text node changes. 61723 // @see https://github.com/WordPress/gutenberg/pull/51035 61724 ref.current.textContent = ref.current.textContent; 61725 } 61726 }, [children]); 61727 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 61728 hidden: true, 61729 ...props, 61730 ref: ref, 61731 children: children 61732 }); 61733 } 61734 61735 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/appender.js 61736 /** 61737 * WordPress dependencies 61738 */ 61739 61740 61741 61742 61743 61744 61745 /** 61746 * Internal dependencies 61747 */ 61748 61749 61750 61751 61752 61753 61754 61755 const Appender = (0,external_wp_element_namespaceObject.forwardRef)(({ 61756 nestingLevel, 61757 blockCount, 61758 clientId, 61759 ...props 61760 }, ref) => { 61761 const { 61762 insertedBlock, 61763 setInsertedBlock 61764 } = useListViewContext(); 61765 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(Appender); 61766 const hideInserter = (0,external_wp_data_namespaceObject.useSelect)(select => { 61767 const { 61768 getTemplateLock, 61769 isZoomOut 61770 } = unlock(select(store)); 61771 return !!getTemplateLock(clientId) || isZoomOut(); 61772 }, [clientId]); 61773 const blockTitle = useBlockDisplayTitle({ 61774 clientId, 61775 context: 'list-view' 61776 }); 61777 const insertedBlockTitle = useBlockDisplayTitle({ 61778 clientId: insertedBlock?.clientId, 61779 context: 'list-view' 61780 }); 61781 (0,external_wp_element_namespaceObject.useEffect)(() => { 61782 if (!insertedBlockTitle?.length) { 61783 return; 61784 } 61785 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)( 61786 // translators: %s: name of block being inserted (i.e. Paragraph, Image, Group etc) 61787 (0,external_wp_i18n_namespaceObject.__)('%s block inserted'), insertedBlockTitle), 'assertive'); 61788 }, [insertedBlockTitle]); 61789 if (hideInserter) { 61790 return null; 61791 } 61792 const descriptionId = `list-view-appender__$instanceId}`; 61793 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. */ 61794 (0,external_wp_i18n_namespaceObject.__)('Append to %1$s block at position %2$d, Level %3$d'), blockTitle, blockCount + 1, nestingLevel); 61795 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 61796 className: "list-view-appender", 61797 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inserter, { 61798 ref: ref, 61799 rootClientId: clientId, 61800 position: "bottom right", 61801 isAppender: true, 61802 selectBlockOnInsert: false, 61803 shouldDirectInsert: false, 61804 __experimentalIsQuick: true, 61805 ...props, 61806 toggleProps: { 61807 'aria-describedby': descriptionId 61808 }, 61809 onSelectOrClose: maybeInsertedBlock => { 61810 if (maybeInsertedBlock?.clientId) { 61811 setInsertedBlock(maybeInsertedBlock); 61812 } 61813 } 61814 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AriaReferencedText, { 61815 id: descriptionId, 61816 children: description 61817 })] 61818 }); 61819 }); 61820 61821 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/leaf.js 61822 /** 61823 * External dependencies 61824 */ 61825 61826 61827 61828 /** 61829 * WordPress dependencies 61830 */ 61831 61832 61833 61834 61835 /** 61836 * Internal dependencies 61837 */ 61838 61839 61840 const AnimatedTreeGridRow = dist_esm_it(external_wp_components_namespaceObject.__experimentalTreeGridRow); 61841 const ListViewLeaf = (0,external_wp_element_namespaceObject.forwardRef)(({ 61842 isDragged, 61843 isSelected, 61844 position, 61845 level, 61846 rowCount, 61847 children, 61848 className, 61849 path, 61850 ...props 61851 }, ref) => { 61852 const animationRef = use_moving_animation({ 61853 clientId: props['data-block'], 61854 enableAnimation: true, 61855 triggerAnimationOnChange: path 61856 }); 61857 const mergedRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, animationRef]); 61858 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AnimatedTreeGridRow, { 61859 ref: mergedRef, 61860 className: dist_clsx('block-editor-list-view-leaf', className), 61861 level: level, 61862 positionInSet: position, 61863 setSize: rowCount, 61864 isExpanded: undefined, 61865 ...props, 61866 children: children 61867 }); 61868 }); 61869 /* harmony default export */ const leaf = (ListViewLeaf); 61870 61871 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-scroll-into-view.js 61872 /** 61873 * WordPress dependencies 61874 */ 61875 61876 61877 function useListViewScrollIntoView({ 61878 isSelected, 61879 selectedClientIds, 61880 rowItemRef 61881 }) { 61882 const isSingleSelection = selectedClientIds.length === 1; 61883 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 61884 // Skip scrolling into view if this particular block isn't selected, 61885 // or if more than one block is selected overall. This is to avoid 61886 // scrolling the view in a multi selection where the user has intentionally 61887 // selected multiple blocks within the list view, but the initially 61888 // selected block may be out of view. 61889 if (!isSelected || !isSingleSelection || !rowItemRef.current) { 61890 return; 61891 } 61892 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(rowItemRef.current); 61893 const { 61894 ownerDocument 61895 } = rowItemRef.current; 61896 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 61897 61898 // If the there is no scroll container, of if the scroll container is the window, 61899 // do not scroll into view, as the block is already in view. 61900 if (windowScroll || !scrollContainer) { 61901 return; 61902 } 61903 const rowRect = rowItemRef.current.getBoundingClientRect(); 61904 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 61905 61906 // If the selected block is not currently visible, scroll to it. 61907 if (rowRect.top < scrollContainerRect.top || rowRect.bottom > scrollContainerRect.bottom) { 61908 rowItemRef.current.scrollIntoView(); 61909 } 61910 }, [isSelected, isSingleSelection, rowItemRef]); 61911 } 61912 61913 ;// ./node_modules/@wordpress/icons/build-module/library/pin-small.js 61914 /** 61915 * WordPress dependencies 61916 */ 61917 61918 61919 const pinSmall = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 61920 width: "24", 61921 height: "24", 61922 viewBox: "0 0 24 24", 61923 xmlns: "http://www.w3.org/2000/svg", 61924 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 61925 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" 61926 }) 61927 }); 61928 /* harmony default export */ const pin_small = (pinSmall); 61929 61930 ;// ./node_modules/@wordpress/icons/build-module/library/lock-small.js 61931 /** 61932 * WordPress dependencies 61933 */ 61934 61935 61936 const lockSmall = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 61937 viewBox: "0 0 24 24", 61938 xmlns: "http://www.w3.org/2000/svg", 61939 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 61940 fillRule: "evenodd", 61941 clipRule: "evenodd", 61942 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" 61943 }) 61944 }); 61945 /* harmony default export */ const lock_small = (lockSmall); 61946 61947 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/expander.js 61948 /** 61949 * WordPress dependencies 61950 */ 61951 61952 61953 61954 function ListViewExpander({ 61955 onClick 61956 }) { 61957 return ( 61958 /*#__PURE__*/ 61959 // Keyboard events are handled by TreeGrid see: components/src/tree-grid/index.js 61960 // 61961 // The expander component is implemented as a pseudo element in the w3 example 61962 // https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html 61963 // 61964 // We've mimicked this by adding an icon with aria-hidden set to true to hide this from the accessibility tree. 61965 // For the current tree grid implementation, please do not try to make this a button. 61966 // 61967 // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions 61968 (0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 61969 className: "block-editor-list-view__expander", 61970 onClick: event => onClick(event, { 61971 forceToggle: true 61972 }), 61973 "aria-hidden": "true", 61974 "data-testid": "list-view-expander", 61975 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 61976 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left_small : chevron_right_small 61977 }) 61978 }) 61979 ); 61980 } 61981 61982 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-images.js 61983 /** 61984 * WordPress dependencies 61985 */ 61986 61987 61988 61989 /** 61990 * Internal dependencies 61991 */ 61992 61993 61994 // Maximum number of images to display in a list view row. 61995 const MAX_IMAGES = 3; 61996 function getImage(block) { 61997 if (block.name !== 'core/image') { 61998 return; 61999 } 62000 if (block.attributes?.url) { 62001 return { 62002 url: block.attributes.url, 62003 alt: block.attributes.alt, 62004 clientId: block.clientId 62005 }; 62006 } 62007 } 62008 function getImagesFromGallery(block) { 62009 if (block.name !== 'core/gallery' || !block.innerBlocks) { 62010 return []; 62011 } 62012 const images = []; 62013 for (const innerBlock of block.innerBlocks) { 62014 const img = getImage(innerBlock); 62015 if (img) { 62016 images.push(img); 62017 } 62018 if (images.length >= MAX_IMAGES) { 62019 return images; 62020 } 62021 } 62022 return images; 62023 } 62024 function getImagesFromBlock(block, isExpanded) { 62025 const img = getImage(block); 62026 if (img) { 62027 return [img]; 62028 } 62029 return isExpanded ? [] : getImagesFromGallery(block); 62030 } 62031 62032 /** 62033 * Get a block's preview images for display within a list view row. 62034 * 62035 * TODO: Currently only supports images from the core/image and core/gallery 62036 * blocks. This should be expanded to support other blocks that have images, 62037 * potentially via an API that blocks can opt into / provide their own logic. 62038 * 62039 * @param {Object} props Hook properties. 62040 * @param {string} props.clientId The block's clientId. 62041 * @param {boolean} props.isExpanded Whether or not the block is expanded in the list view. 62042 * @return {Array} Images. 62043 */ 62044 function useListViewImages({ 62045 clientId, 62046 isExpanded 62047 }) { 62048 const { 62049 block 62050 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 62051 const _block = select(store).getBlock(clientId); 62052 return { 62053 block: _block 62054 }; 62055 }, [clientId]); 62056 const images = (0,external_wp_element_namespaceObject.useMemo)(() => { 62057 return getImagesFromBlock(block, isExpanded); 62058 }, [block, isExpanded]); 62059 return images; 62060 } 62061 62062 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/block-select-button.js 62063 /** 62064 * External dependencies 62065 */ 62066 62067 62068 /** 62069 * WordPress dependencies 62070 */ 62071 62072 62073 62074 62075 62076 62077 /** 62078 * Internal dependencies 62079 */ 62080 62081 62082 62083 62084 62085 62086 62087 62088 62089 const { 62090 Badge: block_select_button_Badge 62091 } = unlock(external_wp_components_namespaceObject.privateApis); 62092 function ListViewBlockSelectButton({ 62093 className, 62094 block: { 62095 clientId 62096 }, 62097 onClick, 62098 onContextMenu, 62099 onMouseDown, 62100 onToggleExpanded, 62101 tabIndex, 62102 onFocus, 62103 onDragStart, 62104 onDragEnd, 62105 draggable, 62106 isExpanded, 62107 ariaDescribedBy 62108 }, ref) { 62109 const blockInformation = useBlockDisplayInformation(clientId); 62110 const blockTitle = useBlockDisplayTitle({ 62111 clientId, 62112 context: 'list-view' 62113 }); 62114 const { 62115 isLocked 62116 } = useBlockLock(clientId); 62117 const { 62118 isContentOnly 62119 } = (0,external_wp_data_namespaceObject.useSelect)(select => ({ 62120 isContentOnly: select(store).getBlockEditingMode(clientId) === 'contentOnly' 62121 }), [clientId]); 62122 const shouldShowLockIcon = isLocked && !isContentOnly; 62123 const isSticky = blockInformation?.positionType === 'sticky'; 62124 const images = useListViewImages({ 62125 clientId, 62126 isExpanded 62127 }); 62128 62129 // The `href` attribute triggers the browser's native HTML drag operations. 62130 // When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html. 62131 // We need to clear any HTML drag data to prevent `pasteHandler` from firing 62132 // inside the `useOnBlockDrop` hook. 62133 const onDragStartHandler = event => { 62134 event.dataTransfer.clearData(); 62135 onDragStart?.(event); 62136 }; 62137 62138 /** 62139 * @param {KeyboardEvent} event 62140 */ 62141 function onKeyDown(event) { 62142 if (event.keyCode === external_wp_keycodes_namespaceObject.ENTER || event.keyCode === external_wp_keycodes_namespaceObject.SPACE) { 62143 onClick(event); 62144 } 62145 } 62146 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("a", { 62147 className: dist_clsx('block-editor-list-view-block-select-button', className), 62148 onClick: onClick, 62149 onContextMenu: onContextMenu, 62150 onKeyDown: onKeyDown, 62151 onMouseDown: onMouseDown, 62152 ref: ref, 62153 tabIndex: tabIndex, 62154 onFocus: onFocus, 62155 onDragStart: onDragStartHandler, 62156 onDragEnd: onDragEnd, 62157 draggable: draggable, 62158 href: `#block-$clientId}`, 62159 "aria-describedby": ariaDescribedBy, 62160 "aria-expanded": isExpanded, 62161 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListViewExpander, { 62162 onClick: onToggleExpanded 62163 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 62164 icon: blockInformation?.icon, 62165 showColors: true, 62166 context: "list-view" 62167 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 62168 alignment: "center", 62169 className: "block-editor-list-view-block-select-button__label-wrapper", 62170 justify: "flex-start", 62171 spacing: 1, 62172 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 62173 className: "block-editor-list-view-block-select-button__title", 62174 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 62175 ellipsizeMode: "auto", 62176 children: blockTitle 62177 }) 62178 }), blockInformation?.anchor && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 62179 className: "block-editor-list-view-block-select-button__anchor-wrapper", 62180 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_select_button_Badge, { 62181 className: "block-editor-list-view-block-select-button__anchor", 62182 children: blockInformation.anchor 62183 }) 62184 }), isSticky && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 62185 className: "block-editor-list-view-block-select-button__sticky", 62186 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 62187 icon: pin_small 62188 }) 62189 }), images.length ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 62190 className: "block-editor-list-view-block-select-button__images", 62191 "aria-hidden": true, 62192 children: images.map((image, index) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 62193 className: "block-editor-list-view-block-select-button__image", 62194 style: { 62195 backgroundImage: `url($image.url})`, 62196 zIndex: images.length - index // Ensure the first image is on top, and subsequent images are behind. 62197 } 62198 }, image.clientId)) 62199 }) : null, shouldShowLockIcon && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 62200 className: "block-editor-list-view-block-select-button__lock", 62201 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 62202 icon: lock_small 62203 }) 62204 })] 62205 })] 62206 }); 62207 } 62208 /* harmony default export */ const block_select_button = ((0,external_wp_element_namespaceObject.forwardRef)(ListViewBlockSelectButton)); 62209 62210 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/block-contents.js 62211 /** 62212 * WordPress dependencies 62213 */ 62214 62215 62216 /** 62217 * Internal dependencies 62218 */ 62219 62220 62221 62222 62223 const ListViewBlockContents = (0,external_wp_element_namespaceObject.forwardRef)(({ 62224 onClick, 62225 onToggleExpanded, 62226 block, 62227 isSelected, 62228 position, 62229 siblingBlockCount, 62230 level, 62231 isExpanded, 62232 selectedClientIds, 62233 ...props 62234 }, ref) => { 62235 const { 62236 clientId 62237 } = block; 62238 const { 62239 AdditionalBlockContent, 62240 insertedBlock, 62241 setInsertedBlock 62242 } = useListViewContext(); 62243 62244 // Only include all selected blocks if the currently clicked on block 62245 // is one of the selected blocks. This ensures that if a user attempts 62246 // to drag a block that isn't part of the selection, they're still able 62247 // to drag it and rearrange its position. 62248 const draggableClientIds = selectedClientIds.includes(clientId) ? selectedClientIds : [clientId]; 62249 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 62250 children: [AdditionalBlockContent && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AdditionalBlockContent, { 62251 block: block, 62252 insertedBlock: insertedBlock, 62253 setInsertedBlock: setInsertedBlock 62254 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_draggable, { 62255 appendToOwnerDocument: true, 62256 clientIds: draggableClientIds, 62257 cloneClassname: "block-editor-list-view-draggable-chip", 62258 children: ({ 62259 draggable, 62260 onDragStart, 62261 onDragEnd 62262 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_select_button, { 62263 ref: ref, 62264 className: "block-editor-list-view-block-contents", 62265 block: block, 62266 onClick: onClick, 62267 onToggleExpanded: onToggleExpanded, 62268 isSelected: isSelected, 62269 position: position, 62270 siblingBlockCount: siblingBlockCount, 62271 level: level, 62272 draggable: draggable, 62273 onDragStart: onDragStart, 62274 onDragEnd: onDragEnd, 62275 isExpanded: isExpanded, 62276 ...props 62277 }) 62278 })] 62279 }); 62280 }); 62281 /* harmony default export */ const block_contents = (ListViewBlockContents); 62282 62283 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/utils.js 62284 /** 62285 * WordPress dependencies 62286 */ 62287 62288 62289 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. */ 62290 (0,external_wp_i18n_namespaceObject.__)('Block %1$d of %2$d, Level %3$d.'), position, siblingCount, level); 62291 const getBlockPropertiesDescription = (blockInformation, isLocked) => [blockInformation?.positionLabel ? `${(0,external_wp_i18n_namespaceObject.sprintf)( 62292 // translators: %s: Position of selected block, e.g. "Sticky" or "Fixed". 62293 (0,external_wp_i18n_namespaceObject.__)('Position: %s'), blockInformation.positionLabel)}.` : undefined, isLocked ? (0,external_wp_i18n_namespaceObject.__)('This block is locked.') : undefined].filter(Boolean).join(' '); 62294 62295 /** 62296 * Returns true if the client ID occurs within the block selection or multi-selection, 62297 * or false otherwise. 62298 * 62299 * @param {string} clientId Block client ID. 62300 * @param {string|string[]} selectedBlockClientIds Selected block client ID, or an array of multi-selected blocks client IDs. 62301 * 62302 * @return {boolean} Whether the block is in multi-selection set. 62303 */ 62304 const isClientIdSelected = (clientId, selectedBlockClientIds) => Array.isArray(selectedBlockClientIds) && selectedBlockClientIds.length ? selectedBlockClientIds.indexOf(clientId) !== -1 : selectedBlockClientIds === clientId; 62305 62306 /** 62307 * From a start and end clientId of potentially different nesting levels, 62308 * return the nearest-depth ids that have a common level of depth in the 62309 * nesting hierarchy. For multiple block selection, this ensure that the 62310 * selection is always at the same nesting level, and not split across 62311 * separate levels. 62312 * 62313 * @param {string} startId The first id of a selection. 62314 * @param {string} endId The end id of a selection, usually one that has been clicked on. 62315 * @param {string[]} startParents An array of ancestor ids for the start id, in descending order. 62316 * @param {string[]} endParents An array of ancestor ids for the end id, in descending order. 62317 * @return {Object} An object containing the start and end ids. 62318 */ 62319 function getCommonDepthClientIds(startId, endId, startParents, endParents) { 62320 const startPath = [...startParents, startId]; 62321 const endPath = [...endParents, endId]; 62322 const depth = Math.min(startPath.length, endPath.length) - 1; 62323 const start = startPath[depth]; 62324 const end = endPath[depth]; 62325 return { 62326 start, 62327 end 62328 }; 62329 } 62330 62331 /** 62332 * Shift focus to the list view item associated with a particular clientId. 62333 * 62334 * @typedef {import('@wordpress/element').RefObject} RefObject 62335 * 62336 * @param {string} focusClientId The client ID of the block to focus. 62337 * @param {?HTMLElement} treeGridElement The container element to search within. 62338 */ 62339 function focusListItem(focusClientId, treeGridElement) { 62340 const getFocusElement = () => { 62341 const row = treeGridElement?.querySelector(`[role=row][data-block="$focusClientId}"]`); 62342 if (!row) { 62343 return null; 62344 } 62345 // Focus the first focusable in the row, which is the ListViewBlockSelectButton. 62346 return external_wp_dom_namespaceObject.focus.focusable.find(row)[0]; 62347 }; 62348 let focusElement = getFocusElement(); 62349 if (focusElement) { 62350 focusElement.focus(); 62351 } else { 62352 // The element hasn't been painted yet. Defer focusing on the next frame. 62353 // This could happen when all blocks have been deleted and the default block 62354 // hasn't been added to the editor yet. 62355 window.requestAnimationFrame(() => { 62356 focusElement = getFocusElement(); 62357 62358 // Ignore if the element still doesn't exist. 62359 if (focusElement) { 62360 focusElement.focus(); 62361 } 62362 }); 62363 } 62364 } 62365 62366 /** 62367 * Get values for the block that flag whether the block should be displaced up or down, 62368 * whether the block is being nested, and whether the block appears after the dragged 62369 * blocks. These values are used to determine the class names to apply to the block. 62370 * The list view rows are displaced visually via CSS rules. Displacement rules: 62371 * - `normal`: no displacement — used to apply a translateY of `0` so that the block 62372 * appears in its original position, and moves to that position smoothly when dragging 62373 * outside of the list view area. 62374 * - `up`: the block should be displaced up, creating room beneath the block for the drop indicator. 62375 * - `down`: the block should be displaced down, creating room above the block for the drop indicator. 62376 * 62377 * @param {Object} props 62378 * @param {Object} props.blockIndexes The indexes of all the blocks in the list view, keyed by clientId. 62379 * @param {number|null|undefined} props.blockDropTargetIndex The index of the block that the user is dropping to. 62380 * @param {?string} props.blockDropPosition The position relative to the block that the user is dropping to. 62381 * @param {string} props.clientId The client id for the current block. 62382 * @param {?number} props.firstDraggedBlockIndex The index of the first dragged block. 62383 * @param {?boolean} props.isDragged Whether the current block is being dragged. Dragged blocks skip displacement. 62384 * @return {Object} An object containing the `displacement`, `isAfterDraggedBlocks` and `isNesting` values. 62385 */ 62386 function getDragDisplacementValues({ 62387 blockIndexes, 62388 blockDropTargetIndex, 62389 blockDropPosition, 62390 clientId, 62391 firstDraggedBlockIndex, 62392 isDragged 62393 }) { 62394 let displacement; 62395 let isNesting; 62396 let isAfterDraggedBlocks; 62397 if (!isDragged) { 62398 isNesting = false; 62399 const thisBlockIndex = blockIndexes[clientId]; 62400 isAfterDraggedBlocks = thisBlockIndex > firstDraggedBlockIndex; 62401 62402 // Determine where to displace the position of the current block, relative 62403 // to the blocks being dragged (in their original position) and the drop target 62404 // (the position where a user is currently dragging the blocks to). 62405 if (blockDropTargetIndex !== undefined && blockDropTargetIndex !== null && firstDraggedBlockIndex !== undefined) { 62406 // If the block is being dragged and there is a valid drop target, 62407 // determine if the block being rendered should be displaced up or down. 62408 62409 if (thisBlockIndex !== undefined) { 62410 if (thisBlockIndex >= firstDraggedBlockIndex && thisBlockIndex < blockDropTargetIndex) { 62411 // If the current block appears after the set of dragged blocks 62412 // (in their original position), but is before the drop target, 62413 // then the current block should be displaced up. 62414 displacement = 'up'; 62415 } else if (thisBlockIndex < firstDraggedBlockIndex && thisBlockIndex >= blockDropTargetIndex) { 62416 // If the current block appears before the set of dragged blocks 62417 // (in their original position), but is after the drop target, 62418 // then the current block should be displaced down. 62419 displacement = 'down'; 62420 } else { 62421 displacement = 'normal'; 62422 } 62423 isNesting = typeof blockDropTargetIndex === 'number' && blockDropTargetIndex - 1 === thisBlockIndex && blockDropPosition === 'inside'; 62424 } 62425 } else if (blockDropTargetIndex === null && firstDraggedBlockIndex !== undefined) { 62426 // A `null` value for `blockDropTargetIndex` indicates that the 62427 // drop target is outside of the valid areas within the list view. 62428 // In this case, the drag is still active, but as there is no 62429 // valid drop target, we should remove the gap indicating where 62430 // the block would be inserted. 62431 if (thisBlockIndex !== undefined && thisBlockIndex >= firstDraggedBlockIndex) { 62432 displacement = 'up'; 62433 } else { 62434 displacement = 'normal'; 62435 } 62436 } else if (blockDropTargetIndex !== undefined && blockDropTargetIndex !== null && firstDraggedBlockIndex === undefined) { 62437 // If the blockdrop target is defined, but there are no dragged blocks, 62438 // then the block should be displaced relative to the drop target. 62439 if (thisBlockIndex !== undefined) { 62440 if (thisBlockIndex < blockDropTargetIndex) { 62441 displacement = 'normal'; 62442 } else { 62443 displacement = 'down'; 62444 } 62445 } 62446 } else if (blockDropTargetIndex === null) { 62447 displacement = 'normal'; 62448 } 62449 } 62450 return { 62451 displacement, 62452 isNesting, 62453 isAfterDraggedBlocks 62454 }; 62455 } 62456 62457 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/block.js 62458 /** 62459 * External dependencies 62460 */ 62461 62462 62463 /** 62464 * WordPress dependencies 62465 */ 62466 62467 62468 62469 62470 62471 62472 62473 62474 62475 62476 62477 62478 /** 62479 * Internal dependencies 62480 */ 62481 62482 62483 62484 62485 62486 62487 62488 62489 62490 62491 62492 62493 function ListViewBlock({ 62494 block: { 62495 clientId 62496 }, 62497 displacement, 62498 isAfterDraggedBlocks, 62499 isDragged, 62500 isNesting, 62501 isSelected, 62502 isBranchSelected, 62503 selectBlock, 62504 position, 62505 level, 62506 rowCount, 62507 siblingBlockCount, 62508 showBlockMovers, 62509 path, 62510 isExpanded, 62511 selectedClientIds, 62512 isSyncedBranch 62513 }) { 62514 const cellRef = (0,external_wp_element_namespaceObject.useRef)(null); 62515 const rowRef = (0,external_wp_element_namespaceObject.useRef)(null); 62516 const settingsRef = (0,external_wp_element_namespaceObject.useRef)(null); 62517 const [isHovered, setIsHovered] = (0,external_wp_element_namespaceObject.useState)(false); 62518 const [settingsAnchorRect, setSettingsAnchorRect] = (0,external_wp_element_namespaceObject.useState)(); 62519 const { 62520 isLocked, 62521 canEdit, 62522 canMove 62523 } = useBlockLock(clientId); 62524 const isFirstSelectedBlock = isSelected && selectedClientIds[0] === clientId; 62525 const isLastSelectedBlock = isSelected && selectedClientIds[selectedClientIds.length - 1] === clientId; 62526 const { 62527 toggleBlockHighlight, 62528 duplicateBlocks, 62529 multiSelect, 62530 replaceBlocks, 62531 removeBlocks, 62532 insertAfterBlock, 62533 insertBeforeBlock, 62534 setOpenedBlockSettingsMenu 62535 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 62536 const { 62537 canInsertBlockType, 62538 getSelectedBlockClientIds, 62539 getPreviousBlockClientId, 62540 getBlockRootClientId, 62541 getBlockOrder, 62542 getBlockParents, 62543 getBlocksByClientId, 62544 canRemoveBlocks, 62545 isGroupable 62546 } = (0,external_wp_data_namespaceObject.useSelect)(store); 62547 const { 62548 getGroupingBlockName 62549 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 62550 const blockInformation = useBlockDisplayInformation(clientId); 62551 const { 62552 block, 62553 blockName, 62554 allowRightClickOverrides 62555 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 62556 const { 62557 getBlock, 62558 getBlockName, 62559 getSettings 62560 } = select(store); 62561 return { 62562 block: getBlock(clientId), 62563 blockName: getBlockName(clientId), 62564 allowRightClickOverrides: getSettings().allowRightClickOverrides 62565 }; 62566 }, [clientId]); 62567 const showBlockActions = 62568 // When a block hides its toolbar it also hides the block settings menu, 62569 // since that menu is part of the toolbar in the editor canvas. 62570 // List View respects this by also hiding the block settings menu. 62571 (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, '__experimentalToolbar', true); 62572 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(ListViewBlock); 62573 const descriptionId = `list-view-block-select-button__description-$instanceId}`; 62574 const { 62575 expand, 62576 collapse, 62577 collapseAll, 62578 BlockSettingsMenu, 62579 listViewInstanceId, 62580 expandedState, 62581 setInsertedBlock, 62582 treeGridElementRef, 62583 rootClientId 62584 } = useListViewContext(); 62585 const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)(); 62586 62587 // Determine which blocks to update: 62588 // If the current (focused) block is part of the block selection, use the whole selection. 62589 // If the focused block is not part of the block selection, only update the focused block. 62590 function getBlocksToUpdate() { 62591 const selectedBlockClientIds = getSelectedBlockClientIds(); 62592 const isUpdatingSelectedBlocks = selectedBlockClientIds.includes(clientId); 62593 const firstBlockClientId = isUpdatingSelectedBlocks ? selectedBlockClientIds[0] : clientId; 62594 const firstBlockRootClientId = getBlockRootClientId(firstBlockClientId); 62595 const blocksToUpdate = isUpdatingSelectedBlocks ? selectedBlockClientIds : [clientId]; 62596 return { 62597 blocksToUpdate, 62598 firstBlockClientId, 62599 firstBlockRootClientId, 62600 selectedBlockClientIds 62601 }; 62602 } 62603 62604 /** 62605 * @param {KeyboardEvent} event 62606 */ 62607 async function onKeyDown(event) { 62608 if (event.defaultPrevented) { 62609 return; 62610 } 62611 62612 // Do not handle events if it comes from modals; 62613 // retain the default behavior for these keys. 62614 if (event.target.closest('[role=dialog]')) { 62615 return; 62616 } 62617 const isDeleteKey = [external_wp_keycodes_namespaceObject.BACKSPACE, external_wp_keycodes_namespaceObject.DELETE].includes(event.keyCode); 62618 62619 // If multiple blocks are selected, deselect all blocks when the user 62620 // presses the escape key. 62621 if (isMatch('core/block-editor/unselect', event) && selectedClientIds.length > 0) { 62622 event.stopPropagation(); 62623 event.preventDefault(); 62624 selectBlock(event, undefined); 62625 } else if (isDeleteKey || isMatch('core/block-editor/remove', event)) { 62626 var _getPreviousBlockClie; 62627 const { 62628 blocksToUpdate: blocksToDelete, 62629 firstBlockClientId, 62630 firstBlockRootClientId, 62631 selectedBlockClientIds 62632 } = getBlocksToUpdate(); 62633 62634 // Don't update the selection if the blocks cannot be deleted. 62635 if (!canRemoveBlocks(blocksToDelete)) { 62636 return; 62637 } 62638 let blockToFocus = (_getPreviousBlockClie = getPreviousBlockClientId(firstBlockClientId)) !== null && _getPreviousBlockClie !== void 0 ? _getPreviousBlockClie : 62639 // If the previous block is not found (when the first block is deleted), 62640 // fallback to focus the parent block. 62641 firstBlockRootClientId; 62642 removeBlocks(blocksToDelete, false); 62643 62644 // Update the selection if the original selection has been removed. 62645 const shouldUpdateSelection = selectedBlockClientIds.length > 0 && getSelectedBlockClientIds().length === 0; 62646 62647 // If there's no previous block nor parent block, focus the first block. 62648 if (!blockToFocus) { 62649 blockToFocus = getBlockOrder()[0]; 62650 } 62651 updateFocusAndSelection(blockToFocus, shouldUpdateSelection); 62652 } else if (isMatch('core/block-editor/duplicate', event)) { 62653 event.preventDefault(); 62654 const { 62655 blocksToUpdate, 62656 firstBlockRootClientId 62657 } = getBlocksToUpdate(); 62658 const canDuplicate = getBlocksByClientId(blocksToUpdate).every(blockToUpdate => { 62659 return !!blockToUpdate && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockToUpdate.name, 'multiple', true) && canInsertBlockType(blockToUpdate.name, firstBlockRootClientId); 62660 }); 62661 if (canDuplicate) { 62662 const updatedBlocks = await duplicateBlocks(blocksToUpdate, false); 62663 if (updatedBlocks?.length) { 62664 // If blocks have been duplicated, focus the first duplicated block. 62665 updateFocusAndSelection(updatedBlocks[0], false); 62666 } 62667 } 62668 } else if (isMatch('core/block-editor/insert-before', event)) { 62669 event.preventDefault(); 62670 const { 62671 blocksToUpdate 62672 } = getBlocksToUpdate(); 62673 await insertBeforeBlock(blocksToUpdate[0]); 62674 const newlySelectedBlocks = getSelectedBlockClientIds(); 62675 62676 // Focus the first block of the newly inserted blocks, to keep focus within the list view. 62677 setOpenedBlockSettingsMenu(undefined); 62678 updateFocusAndSelection(newlySelectedBlocks[0], false); 62679 } else if (isMatch('core/block-editor/insert-after', event)) { 62680 event.preventDefault(); 62681 const { 62682 blocksToUpdate 62683 } = getBlocksToUpdate(); 62684 await insertAfterBlock(blocksToUpdate.at(-1)); 62685 const newlySelectedBlocks = getSelectedBlockClientIds(); 62686 62687 // Focus the first block of the newly inserted blocks, to keep focus within the list view. 62688 setOpenedBlockSettingsMenu(undefined); 62689 updateFocusAndSelection(newlySelectedBlocks[0], false); 62690 } else if (isMatch('core/block-editor/select-all', event)) { 62691 event.preventDefault(); 62692 const { 62693 firstBlockRootClientId, 62694 selectedBlockClientIds 62695 } = getBlocksToUpdate(); 62696 const blockClientIds = getBlockOrder(firstBlockRootClientId); 62697 if (!blockClientIds.length) { 62698 return; 62699 } 62700 62701 // If we have selected all sibling nested blocks, try selecting up a level. 62702 // This is a similar implementation to that used by `useSelectAll`. 62703 // `isShallowEqual` is used for the list view instead of a length check, 62704 // as the array of siblings of the currently focused block may be a different 62705 // set of blocks from the current block selection if the user is focused 62706 // on a different part of the list view from the block selection. 62707 if (external_wp_isShallowEqual_default()(selectedBlockClientIds, blockClientIds)) { 62708 // Only select up a level if the first block is not the root block. 62709 // This ensures that the block selection can't break out of the root block 62710 // used by the list view, if the list view is only showing a partial hierarchy. 62711 if (firstBlockRootClientId && firstBlockRootClientId !== rootClientId) { 62712 updateFocusAndSelection(firstBlockRootClientId, true); 62713 return; 62714 } 62715 } 62716 62717 // Select all while passing `null` to skip focusing to the editor canvas, 62718 // and retain focus within the list view. 62719 multiSelect(blockClientIds[0], blockClientIds[blockClientIds.length - 1], null); 62720 } else if (isMatch('core/block-editor/collapse-list-view', event)) { 62721 event.preventDefault(); 62722 const { 62723 firstBlockClientId 62724 } = getBlocksToUpdate(); 62725 const blockParents = getBlockParents(firstBlockClientId, false); 62726 // Collapse all blocks. 62727 collapseAll(); 62728 // Expand all parents of the current block. 62729 expand(blockParents); 62730 } else if (isMatch('core/block-editor/group', event)) { 62731 const { 62732 blocksToUpdate 62733 } = getBlocksToUpdate(); 62734 if (blocksToUpdate.length > 1 && isGroupable(blocksToUpdate)) { 62735 event.preventDefault(); 62736 const blocks = getBlocksByClientId(blocksToUpdate); 62737 const groupingBlockName = getGroupingBlockName(); 62738 const newBlocks = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blocks, groupingBlockName); 62739 replaceBlocks(blocksToUpdate, newBlocks); 62740 (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Selected blocks are grouped.')); 62741 const newlySelectedBlocks = getSelectedBlockClientIds(); 62742 // Focus the first block of the newly inserted blocks, to keep focus within the list view. 62743 setOpenedBlockSettingsMenu(undefined); 62744 updateFocusAndSelection(newlySelectedBlocks[0], false); 62745 } 62746 } 62747 } 62748 const onMouseEnter = (0,external_wp_element_namespaceObject.useCallback)(() => { 62749 setIsHovered(true); 62750 toggleBlockHighlight(clientId, true); 62751 }, [clientId, setIsHovered, toggleBlockHighlight]); 62752 const onMouseLeave = (0,external_wp_element_namespaceObject.useCallback)(() => { 62753 setIsHovered(false); 62754 toggleBlockHighlight(clientId, false); 62755 }, [clientId, setIsHovered, toggleBlockHighlight]); 62756 const selectEditorBlock = (0,external_wp_element_namespaceObject.useCallback)(event => { 62757 selectBlock(event, clientId); 62758 event.preventDefault(); 62759 }, [clientId, selectBlock]); 62760 const updateFocusAndSelection = (0,external_wp_element_namespaceObject.useCallback)((focusClientId, shouldSelectBlock) => { 62761 if (shouldSelectBlock) { 62762 selectBlock(undefined, focusClientId, null, null); 62763 } 62764 focusListItem(focusClientId, treeGridElementRef?.current); 62765 }, [selectBlock, treeGridElementRef]); 62766 const toggleExpanded = (0,external_wp_element_namespaceObject.useCallback)(event => { 62767 // Prevent shift+click from opening link in a new window when toggling. 62768 event.preventDefault(); 62769 event.stopPropagation(); 62770 if (isExpanded === true) { 62771 collapse(clientId); 62772 } else if (isExpanded === false) { 62773 expand(clientId); 62774 } 62775 }, [clientId, expand, collapse, isExpanded]); 62776 62777 // Allow right-clicking an item in the List View to open up the block settings dropdown. 62778 const onContextMenu = (0,external_wp_element_namespaceObject.useCallback)(event => { 62779 if (showBlockActions && allowRightClickOverrides) { 62780 settingsRef.current?.click(); 62781 // Ensure the position of the settings dropdown is at the cursor. 62782 setSettingsAnchorRect(new window.DOMRect(event.clientX, event.clientY, 0, 0)); 62783 event.preventDefault(); 62784 } 62785 }, [allowRightClickOverrides, settingsRef, showBlockActions]); 62786 const onMouseDown = (0,external_wp_element_namespaceObject.useCallback)(event => { 62787 // Prevent right-click from focusing the block, 62788 // because focus will be handled when opening the block settings dropdown. 62789 if (allowRightClickOverrides && event.button === 2) { 62790 event.preventDefault(); 62791 } 62792 }, [allowRightClickOverrides]); 62793 const settingsPopoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 62794 const { 62795 ownerDocument 62796 } = rowRef?.current || {}; 62797 62798 // If no custom position is set, the settings dropdown will be anchored to the 62799 // DropdownMenu toggle button. 62800 if (!settingsAnchorRect || !ownerDocument) { 62801 return undefined; 62802 } 62803 62804 // Position the settings dropdown at the cursor when right-clicking a block. 62805 return { 62806 ownerDocument, 62807 getBoundingClientRect() { 62808 return settingsAnchorRect; 62809 } 62810 }; 62811 }, [settingsAnchorRect]); 62812 const clearSettingsAnchorRect = (0,external_wp_element_namespaceObject.useCallback)(() => { 62813 // Clear the custom position for the settings dropdown so that it is restored back 62814 // to being anchored to the DropdownMenu toggle button. 62815 setSettingsAnchorRect(undefined); 62816 }, [setSettingsAnchorRect]); 62817 62818 // Pass in a ref to the row, so that it can be scrolled 62819 // into view when selected. For long lists, the placeholder for the 62820 // selected block is also observed, within ListViewLeafPlaceholder. 62821 useListViewScrollIntoView({ 62822 isSelected, 62823 rowItemRef: rowRef, 62824 selectedClientIds 62825 }); 62826 62827 // When switching between rendering modes (such as template preview and content only), 62828 // it is possible for a block to temporarily be unavailable. In this case, we should not 62829 // render the leaf, to avoid errors further down the tree. 62830 if (!block) { 62831 return null; 62832 } 62833 const blockPositionDescription = getBlockPositionDescription(position, siblingBlockCount, level); 62834 const blockPropertiesDescription = getBlockPropertiesDescription(blockInformation, isLocked); 62835 const hasSiblings = siblingBlockCount > 0; 62836 const hasRenderedMovers = showBlockMovers && hasSiblings; 62837 const moverCellClassName = dist_clsx('block-editor-list-view-block__mover-cell', { 62838 'is-visible': isHovered || isSelected 62839 }); 62840 const listViewBlockSettingsClassName = dist_clsx('block-editor-list-view-block__menu-cell', { 62841 'is-visible': isHovered || isFirstSelectedBlock 62842 }); 62843 let colSpan; 62844 if (hasRenderedMovers) { 62845 colSpan = 2; 62846 } else if (!showBlockActions) { 62847 colSpan = 3; 62848 } 62849 const classes = dist_clsx({ 62850 'is-selected': isSelected, 62851 'is-first-selected': isFirstSelectedBlock, 62852 'is-last-selected': isLastSelectedBlock, 62853 'is-branch-selected': isBranchSelected, 62854 'is-synced-branch': isSyncedBranch, 62855 'is-dragging': isDragged, 62856 'has-single-cell': !showBlockActions, 62857 'is-synced': blockInformation?.isSynced, 62858 'is-draggable': canMove, 62859 'is-displacement-normal': displacement === 'normal', 62860 'is-displacement-up': displacement === 'up', 62861 'is-displacement-down': displacement === 'down', 62862 'is-after-dragged-blocks': isAfterDraggedBlocks, 62863 'is-nesting': isNesting 62864 }); 62865 62866 // Only include all selected blocks if the currently clicked on block 62867 // is one of the selected blocks. This ensures that if a user attempts 62868 // to alter a block that isn't part of the selection, they're still able 62869 // to do so. 62870 const dropdownClientIds = selectedClientIds.includes(clientId) ? selectedClientIds : [clientId]; 62871 62872 // Detect if there is a block in the canvas currently being edited and multi-selection is not happening. 62873 const currentlyEditingBlockInCanvas = isSelected && selectedClientIds.length === 1; 62874 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(leaf, { 62875 className: classes, 62876 isDragged: isDragged, 62877 onKeyDown: onKeyDown, 62878 onMouseEnter: onMouseEnter, 62879 onMouseLeave: onMouseLeave, 62880 onFocus: onMouseEnter, 62881 onBlur: onMouseLeave, 62882 level: level, 62883 position: position, 62884 rowCount: rowCount, 62885 path: path, 62886 id: `list-view-$listViewInstanceId}-block-$clientId}`, 62887 "data-block": clientId, 62888 "data-expanded": canEdit ? isExpanded : undefined, 62889 ref: rowRef, 62890 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 62891 className: "block-editor-list-view-block__contents-cell", 62892 colSpan: colSpan, 62893 ref: cellRef, 62894 "aria-selected": !!isSelected, 62895 children: ({ 62896 ref, 62897 tabIndex, 62898 onFocus 62899 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 62900 className: "block-editor-list-view-block__contents-container", 62901 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_contents, { 62902 block: block, 62903 onClick: selectEditorBlock, 62904 onContextMenu: onContextMenu, 62905 onMouseDown: onMouseDown, 62906 onToggleExpanded: toggleExpanded, 62907 isSelected: isSelected, 62908 position: position, 62909 siblingBlockCount: siblingBlockCount, 62910 level: level, 62911 ref: ref, 62912 tabIndex: currentlyEditingBlockInCanvas ? 0 : tabIndex, 62913 onFocus: onFocus, 62914 isExpanded: canEdit ? isExpanded : undefined, 62915 selectedClientIds: selectedClientIds, 62916 ariaDescribedBy: descriptionId 62917 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AriaReferencedText, { 62918 id: descriptionId, 62919 children: [blockPositionDescription, blockPropertiesDescription].filter(Boolean).join(' ') 62920 })] 62921 }) 62922 }), hasRenderedMovers && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 62923 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 62924 className: moverCellClassName, 62925 withoutGridItem: true, 62926 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGridItem, { 62927 children: ({ 62928 ref, 62929 tabIndex, 62930 onFocus 62931 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockMoverUpButton, { 62932 orientation: "vertical", 62933 clientIds: [clientId], 62934 ref: ref, 62935 tabIndex: tabIndex, 62936 onFocus: onFocus 62937 }) 62938 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGridItem, { 62939 children: ({ 62940 ref, 62941 tabIndex, 62942 onFocus 62943 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockMoverDownButton, { 62944 orientation: "vertical", 62945 clientIds: [clientId], 62946 ref: ref, 62947 tabIndex: tabIndex, 62948 onFocus: onFocus 62949 }) 62950 })] 62951 }) 62952 }), showBlockActions && BlockSettingsMenu && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 62953 className: listViewBlockSettingsClassName, 62954 "aria-selected": !!isSelected, 62955 ref: settingsRef, 62956 children: ({ 62957 ref, 62958 tabIndex, 62959 onFocus 62960 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockSettingsMenu, { 62961 clientIds: dropdownClientIds, 62962 block: block, 62963 icon: more_vertical, 62964 label: (0,external_wp_i18n_namespaceObject.__)('Options'), 62965 popoverProps: { 62966 anchor: settingsPopoverAnchor // Used to position the settings at the cursor on right-click. 62967 }, 62968 toggleProps: { 62969 ref, 62970 className: 'block-editor-list-view-block__menu', 62971 tabIndex, 62972 onClick: clearSettingsAnchorRect, 62973 onFocus 62974 }, 62975 disableOpenOnArrowDown: true, 62976 expand: expand, 62977 expandedState: expandedState, 62978 setInsertedBlock: setInsertedBlock, 62979 __experimentalSelectBlock: updateFocusAndSelection 62980 }) 62981 })] 62982 }); 62983 } 62984 /* harmony default export */ const list_view_block = ((0,external_wp_element_namespaceObject.memo)(ListViewBlock)); 62985 62986 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/branch.js 62987 /** 62988 * WordPress dependencies 62989 */ 62990 62991 62992 62993 62994 /** 62995 * Internal dependencies 62996 */ 62997 62998 62999 63000 63001 63002 63003 63004 /** 63005 * Given a block, returns the total number of blocks in that subtree. This is used to help determine 63006 * the list position of a block. 63007 * 63008 * When a block is collapsed, we do not count their children as part of that total. In the current drag 63009 * implementation dragged blocks and their children are not counted. 63010 * 63011 * @param {Object} block block tree 63012 * @param {Object} expandedState state that notes which branches are collapsed 63013 * @param {Array} draggedClientIds a list of dragged client ids 63014 * @param {boolean} isExpandedByDefault flag to determine the default fallback expanded state. 63015 * @return {number} block count 63016 */ 63017 63018 function countBlocks(block, expandedState, draggedClientIds, isExpandedByDefault) { 63019 var _expandedState$block$; 63020 const isDragged = draggedClientIds?.includes(block.clientId); 63021 if (isDragged) { 63022 return 0; 63023 } 63024 const isExpanded = (_expandedState$block$ = expandedState[block.clientId]) !== null && _expandedState$block$ !== void 0 ? _expandedState$block$ : isExpandedByDefault; 63025 if (isExpanded) { 63026 return 1 + block.innerBlocks.reduce(countReducer(expandedState, draggedClientIds, isExpandedByDefault), 0); 63027 } 63028 return 1; 63029 } 63030 const countReducer = (expandedState, draggedClientIds, isExpandedByDefault) => (count, block) => { 63031 var _expandedState$block$2; 63032 const isDragged = draggedClientIds?.includes(block.clientId); 63033 if (isDragged) { 63034 return count; 63035 } 63036 const isExpanded = (_expandedState$block$2 = expandedState[block.clientId]) !== null && _expandedState$block$2 !== void 0 ? _expandedState$block$2 : isExpandedByDefault; 63037 if (isExpanded && block.innerBlocks.length > 0) { 63038 return count + countBlocks(block, expandedState, draggedClientIds, isExpandedByDefault); 63039 } 63040 return count + 1; 63041 }; 63042 const branch_noop = () => {}; 63043 function ListViewBranch(props) { 63044 const { 63045 blocks, 63046 selectBlock = branch_noop, 63047 showBlockMovers, 63048 selectedClientIds, 63049 level = 1, 63050 path = '', 63051 isBranchSelected = false, 63052 listPosition = 0, 63053 fixedListWindow, 63054 isExpanded, 63055 parentId, 63056 shouldShowInnerBlocks = true, 63057 isSyncedBranch = false, 63058 showAppender: showAppenderProp = true 63059 } = props; 63060 const parentBlockInformation = useBlockDisplayInformation(parentId); 63061 const syncedBranch = isSyncedBranch || !!parentBlockInformation?.isSynced; 63062 const canParentExpand = (0,external_wp_data_namespaceObject.useSelect)(select => { 63063 if (!parentId) { 63064 return true; 63065 } 63066 return select(store).canEditBlock(parentId); 63067 }, [parentId]); 63068 const { 63069 blockDropPosition, 63070 blockDropTargetIndex, 63071 firstDraggedBlockIndex, 63072 blockIndexes, 63073 expandedState, 63074 draggedClientIds 63075 } = useListViewContext(); 63076 const nextPositionRef = (0,external_wp_element_namespaceObject.useRef)(); 63077 if (!canParentExpand) { 63078 return null; 63079 } 63080 63081 // Only show the appender at the first level. 63082 const showAppender = showAppenderProp && level === 1; 63083 const filteredBlocks = blocks.filter(Boolean); 63084 const blockCount = filteredBlocks.length; 63085 // The appender means an extra row in List View, so add 1 to the row count. 63086 const rowCount = showAppender ? blockCount + 1 : blockCount; 63087 nextPositionRef.current = listPosition; 63088 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 63089 children: [filteredBlocks.map((block, index) => { 63090 var _expandedState$client; 63091 const { 63092 clientId, 63093 innerBlocks 63094 } = block; 63095 if (index > 0) { 63096 nextPositionRef.current += countBlocks(filteredBlocks[index - 1], expandedState, draggedClientIds, isExpanded); 63097 } 63098 const isDragged = !!draggedClientIds?.includes(clientId); 63099 63100 // Determine the displacement of the block while dragging. This 63101 // works out whether the current block should be displaced up or 63102 // down, relative to the dragged blocks and the drop target. 63103 const { 63104 displacement, 63105 isAfterDraggedBlocks, 63106 isNesting 63107 } = getDragDisplacementValues({ 63108 blockIndexes, 63109 blockDropTargetIndex, 63110 blockDropPosition, 63111 clientId, 63112 firstDraggedBlockIndex, 63113 isDragged 63114 }); 63115 const { 63116 itemInView 63117 } = fixedListWindow; 63118 const blockInView = itemInView(nextPositionRef.current); 63119 const position = index + 1; 63120 const updatedPath = path.length > 0 ? `$path}_$position}` : `$position}`; 63121 const hasNestedBlocks = !!innerBlocks?.length; 63122 const shouldExpand = hasNestedBlocks && shouldShowInnerBlocks ? (_expandedState$client = expandedState[clientId]) !== null && _expandedState$client !== void 0 ? _expandedState$client : isExpanded : undefined; 63123 63124 // Make updates to the selected or dragged blocks synchronous, 63125 // but asynchronous for any other block. 63126 const isSelected = isClientIdSelected(clientId, selectedClientIds); 63127 const isSelectedBranch = isBranchSelected || isSelected && hasNestedBlocks; 63128 63129 // To avoid performance issues, we only render blocks that are in view, 63130 // or blocks that are selected or dragged. If a block is selected, 63131 // it is only counted if it is the first of the block selection. 63132 // This prevents the entire tree from being rendered when a branch is 63133 // selected, or a user selects all blocks, while still enabling scroll 63134 // into view behavior when selecting a block or opening the list view. 63135 // The first and last blocks of the list are always rendered, to ensure 63136 // that Home and End keys work as expected. 63137 const showBlock = isDragged || blockInView || isSelected && clientId === selectedClientIds[0] || index === 0 || index === blockCount - 1; 63138 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_data_namespaceObject.AsyncModeProvider, { 63139 value: !isSelected, 63140 children: [showBlock && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(list_view_block, { 63141 block: block, 63142 selectBlock: selectBlock, 63143 isSelected: isSelected, 63144 isBranchSelected: isSelectedBranch, 63145 isDragged: isDragged, 63146 level: level, 63147 position: position, 63148 rowCount: rowCount, 63149 siblingBlockCount: blockCount, 63150 showBlockMovers: showBlockMovers, 63151 path: updatedPath, 63152 isExpanded: isDragged ? false : shouldExpand, 63153 listPosition: nextPositionRef.current, 63154 selectedClientIds: selectedClientIds, 63155 isSyncedBranch: syncedBranch, 63156 displacement: displacement, 63157 isAfterDraggedBlocks: isAfterDraggedBlocks, 63158 isNesting: isNesting 63159 }), !showBlock && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("tr", { 63160 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("td", { 63161 className: "block-editor-list-view-placeholder" 63162 }) 63163 }), hasNestedBlocks && shouldExpand && !isDragged && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListViewBranch, { 63164 parentId: clientId, 63165 blocks: innerBlocks, 63166 selectBlock: selectBlock, 63167 showBlockMovers: showBlockMovers, 63168 level: level + 1, 63169 path: updatedPath, 63170 listPosition: nextPositionRef.current + 1, 63171 fixedListWindow: fixedListWindow, 63172 isBranchSelected: isSelectedBranch, 63173 selectedClientIds: selectedClientIds, 63174 isExpanded: isExpanded, 63175 isSyncedBranch: syncedBranch 63176 })] 63177 }, clientId); 63178 }), showAppender && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGridRow, { 63179 level: level, 63180 setSize: rowCount, 63181 positionInSet: rowCount, 63182 isExpanded: true, 63183 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGridCell, { 63184 children: treeGridCellProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Appender, { 63185 clientId: parentId, 63186 nestingLevel: level, 63187 blockCount: blockCount, 63188 ...treeGridCellProps 63189 }) 63190 }) 63191 })] 63192 }); 63193 } 63194 /* harmony default export */ const branch = ((0,external_wp_element_namespaceObject.memo)(ListViewBranch)); 63195 63196 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/drop-indicator.js 63197 /** 63198 * External dependencies 63199 */ 63200 63201 63202 /** 63203 * WordPress dependencies 63204 */ 63205 63206 63207 63208 63209 63210 /** 63211 * Internal dependencies 63212 */ 63213 63214 63215 63216 63217 63218 function ListViewDropIndicatorPreview({ 63219 draggedBlockClientId, 63220 listViewRef, 63221 blockDropTarget 63222 }) { 63223 const blockInformation = useBlockDisplayInformation(draggedBlockClientId); 63224 const blockTitle = useBlockDisplayTitle({ 63225 clientId: draggedBlockClientId, 63226 context: 'list-view' 63227 }); 63228 const { 63229 rootClientId, 63230 clientId, 63231 dropPosition 63232 } = blockDropTarget || {}; 63233 const [rootBlockElement, blockElement] = (0,external_wp_element_namespaceObject.useMemo)(() => { 63234 if (!listViewRef.current) { 63235 return []; 63236 } 63237 63238 // The rootClientId will be defined whenever dropping into inner 63239 // block lists, but is undefined when dropping at the root level. 63240 const _rootBlockElement = rootClientId ? listViewRef.current.querySelector(`[data-block="$rootClientId}"]`) : undefined; 63241 63242 // The clientId represents the sibling block, the dragged block will 63243 // usually be inserted adjacent to it. It will be undefined when 63244 // dropping a block into an empty block list. 63245 const _blockElement = clientId ? listViewRef.current.querySelector(`[data-block="$clientId}"]`) : undefined; 63246 return [_rootBlockElement, _blockElement]; 63247 }, [listViewRef, rootClientId, clientId]); 63248 63249 // The targetElement is the element that the drop indicator will appear 63250 // before or after. When dropping into an empty block list, blockElement 63251 // is undefined, so the indicator will appear after the rootBlockElement. 63252 const targetElement = blockElement || rootBlockElement; 63253 const rtl = (0,external_wp_i18n_namespaceObject.isRTL)(); 63254 const getDropIndicatorWidth = (0,external_wp_element_namespaceObject.useCallback)((targetElementRect, indent) => { 63255 if (!targetElement) { 63256 return 0; 63257 } 63258 63259 // Default to assuming that the width of the drop indicator 63260 // should be the same as the target element. 63261 let width = targetElement.offsetWidth; 63262 63263 // In deeply nested lists, where a scrollbar is present, 63264 // the width of the drop indicator should be the width of 63265 // the scroll container, minus the distance from the left 63266 // edge of the scroll container to the left edge of the 63267 // target element. 63268 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(targetElement, 'horizontal'); 63269 const ownerDocument = targetElement.ownerDocument; 63270 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 63271 if (scrollContainer && !windowScroll) { 63272 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 63273 const distanceBetweenContainerAndTarget = (0,external_wp_i18n_namespaceObject.isRTL)() ? scrollContainerRect.right - targetElementRect.right : targetElementRect.left - scrollContainerRect.left; 63274 const scrollContainerWidth = scrollContainer.clientWidth; 63275 if (scrollContainerWidth < width + distanceBetweenContainerAndTarget) { 63276 width = scrollContainerWidth - distanceBetweenContainerAndTarget; 63277 } 63278 63279 // LTR logic for ensuring the drop indicator does not extend 63280 // beyond the right edge of the scroll container. 63281 if (!rtl && targetElementRect.left + indent < scrollContainerRect.left) { 63282 width -= scrollContainerRect.left - targetElementRect.left; 63283 return width; 63284 } 63285 63286 // RTL logic for ensuring the drop indicator does not extend 63287 // beyond the right edge of the scroll container. 63288 if (rtl && targetElementRect.right - indent > scrollContainerRect.right) { 63289 width -= targetElementRect.right - scrollContainerRect.right; 63290 return width; 63291 } 63292 } 63293 63294 // Subtract the indent from the final width of the indicator. 63295 return width - indent; 63296 }, [rtl, targetElement]); 63297 const style = (0,external_wp_element_namespaceObject.useMemo)(() => { 63298 if (!targetElement) { 63299 return {}; 63300 } 63301 const targetElementRect = targetElement.getBoundingClientRect(); 63302 return { 63303 width: getDropIndicatorWidth(targetElementRect, 0) 63304 }; 63305 }, [getDropIndicatorWidth, targetElement]); 63306 const horizontalScrollOffsetStyle = (0,external_wp_element_namespaceObject.useMemo)(() => { 63307 if (!targetElement) { 63308 return {}; 63309 } 63310 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(targetElement); 63311 const ownerDocument = targetElement.ownerDocument; 63312 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 63313 if (scrollContainer && !windowScroll) { 63314 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 63315 const targetElementRect = targetElement.getBoundingClientRect(); 63316 const distanceBetweenContainerAndTarget = rtl ? scrollContainerRect.right - targetElementRect.right : targetElementRect.left - scrollContainerRect.left; 63317 if (!rtl && scrollContainerRect.left > targetElementRect.left) { 63318 return { 63319 transform: `translateX( $distanceBetweenContainerAndTarget}px )` 63320 }; 63321 } 63322 if (rtl && scrollContainerRect.right < targetElementRect.right) { 63323 return { 63324 transform: `translateX( $distanceBetweenContainerAndTarget * -1}px )` 63325 }; 63326 } 63327 } 63328 return {}; 63329 }, [rtl, targetElement]); 63330 const ariaLevel = (0,external_wp_element_namespaceObject.useMemo)(() => { 63331 if (!rootBlockElement) { 63332 return 1; 63333 } 63334 const _ariaLevel = parseInt(rootBlockElement.getAttribute('aria-level'), 10); 63335 return _ariaLevel ? _ariaLevel + 1 : 1; 63336 }, [rootBlockElement]); 63337 const hasAdjacentSelectedBranch = (0,external_wp_element_namespaceObject.useMemo)(() => { 63338 if (!targetElement) { 63339 return false; 63340 } 63341 return targetElement.classList.contains('is-branch-selected'); 63342 }, [targetElement]); 63343 const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => { 63344 const isValidDropPosition = dropPosition === 'top' || dropPosition === 'bottom' || dropPosition === 'inside'; 63345 if (!targetElement || !isValidDropPosition) { 63346 return undefined; 63347 } 63348 return { 63349 contextElement: targetElement, 63350 getBoundingClientRect() { 63351 const rect = targetElement.getBoundingClientRect(); 63352 // In RTL languages, the drop indicator should be positioned 63353 // to the left of the target element, with the width of the 63354 // indicator determining the indent at the right edge of the 63355 // target element. In LTR languages, the drop indicator should 63356 // end at the right edge of the target element, with the indent 63357 // added to the position of the left edge of the target element. 63358 // let left = rtl ? rect.left : rect.left + indent; 63359 let left = rect.left; 63360 let top = 0; 63361 63362 // In deeply nested lists, where a scrollbar is present, 63363 // the width of the drop indicator should be the width of 63364 // the visible area of the scroll container. Additionally, 63365 // the left edge of the drop indicator line needs to be 63366 // offset by the distance the left edge of the target element 63367 // and the left edge of the scroll container. The ensures 63368 // that the drop indicator position never breaks out of the 63369 // visible area of the scroll container. 63370 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(targetElement, 'horizontal'); 63371 const doc = targetElement.ownerDocument; 63372 const windowScroll = scrollContainer === doc.body || scrollContainer === doc.documentElement; 63373 63374 // If the scroll container is not the window, offset the left position, if need be. 63375 if (scrollContainer && !windowScroll) { 63376 const scrollContainerRect = scrollContainer.getBoundingClientRect(); 63377 63378 // In RTL languages, a vertical scrollbar is present on the 63379 // left edge of the scroll container. The width of the 63380 // scrollbar needs to be accounted for when positioning the 63381 // drop indicator. 63382 const scrollbarWidth = rtl ? scrollContainer.offsetWidth - scrollContainer.clientWidth : 0; 63383 if (left < scrollContainerRect.left + scrollbarWidth) { 63384 left = scrollContainerRect.left + scrollbarWidth; 63385 } 63386 } 63387 if (dropPosition === 'top') { 63388 top = rect.top - rect.height * 2; 63389 } else { 63390 // `dropPosition` is either `bottom` or `inside` 63391 top = rect.top; 63392 } 63393 const width = getDropIndicatorWidth(rect, 0); 63394 const height = rect.height; 63395 return new window.DOMRect(left, top, width, height); 63396 } 63397 }; 63398 }, [targetElement, dropPosition, getDropIndicatorWidth, rtl]); 63399 if (!targetElement) { 63400 return null; 63401 } 63402 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 63403 animate: false, 63404 anchor: popoverAnchor, 63405 focusOnMount: false, 63406 className: "block-editor-list-view-drop-indicator--preview", 63407 variant: "unstyled", 63408 flip: false, 63409 resize: true, 63410 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 63411 style: style, 63412 className: dist_clsx('block-editor-list-view-drop-indicator__line', { 63413 'block-editor-list-view-drop-indicator__line--darker': hasAdjacentSelectedBranch 63414 }), 63415 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 63416 className: "block-editor-list-view-leaf", 63417 "aria-level": ariaLevel, 63418 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 63419 className: dist_clsx('block-editor-list-view-block-select-button', 'block-editor-list-view-block-contents'), 63420 style: horizontalScrollOffsetStyle, 63421 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListViewExpander, { 63422 onClick: () => {} 63423 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 63424 icon: blockInformation?.icon, 63425 showColors: true, 63426 context: "list-view" 63427 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalHStack, { 63428 alignment: "center", 63429 className: "block-editor-list-view-block-select-button__label-wrapper", 63430 justify: "flex-start", 63431 spacing: 1, 63432 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 63433 className: "block-editor-list-view-block-select-button__title", 63434 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 63435 ellipsizeMode: "auto", 63436 children: blockTitle 63437 }) 63438 }) 63439 })] 63440 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 63441 className: "block-editor-list-view-block__menu-cell" 63442 })] 63443 }) 63444 }) 63445 }); 63446 } 63447 63448 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-block-selection.js 63449 /** 63450 * WordPress dependencies 63451 */ 63452 63453 63454 63455 63456 63457 63458 63459 /** 63460 * Internal dependencies 63461 */ 63462 63463 63464 function useBlockSelection() { 63465 const { 63466 clearSelectedBlock, 63467 multiSelect, 63468 selectBlock 63469 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 63470 const { 63471 getBlockName, 63472 getBlockParents, 63473 getBlockSelectionStart, 63474 getSelectedBlockClientIds, 63475 hasMultiSelection, 63476 hasSelectedBlock 63477 } = (0,external_wp_data_namespaceObject.useSelect)(store); 63478 const { 63479 getBlockType 63480 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blocks_namespaceObject.store); 63481 const updateBlockSelection = (0,external_wp_element_namespaceObject.useCallback)(async (event, clientId, destinationClientId, focusPosition) => { 63482 if (!event?.shiftKey && event?.keyCode !== external_wp_keycodes_namespaceObject.ESCAPE) { 63483 selectBlock(clientId, focusPosition); 63484 return; 63485 } 63486 63487 // To handle multiple block selection via the `SHIFT` key, prevent 63488 // the browser default behavior of opening the link in a new window. 63489 event.preventDefault(); 63490 const isOnlyDeselection = event.type === 'keydown' && event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE; 63491 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); 63492 63493 // Handle clicking on a block when no blocks are selected, and return early. 63494 if (!isKeyPress && !hasSelectedBlock() && !hasMultiSelection()) { 63495 selectBlock(clientId, null); 63496 return; 63497 } 63498 const selectedBlocks = getSelectedBlockClientIds(); 63499 const clientIdWithParents = [...getBlockParents(clientId), clientId]; 63500 if (isOnlyDeselection || isKeyPress && !selectedBlocks.some(blockId => clientIdWithParents.includes(blockId))) { 63501 // Ensure that shift-selecting blocks via the keyboard only 63502 // expands the current selection if focusing over already 63503 // selected blocks. Otherwise, clear the selection so that 63504 // a user can create a new selection entirely by keyboard. 63505 await clearSelectedBlock(); 63506 } 63507 63508 // Update selection, if not only clearing the selection. 63509 if (!isOnlyDeselection) { 63510 let startTarget = getBlockSelectionStart(); 63511 let endTarget = clientId; 63512 63513 // Handle keyboard behavior for selecting multiple blocks. 63514 if (isKeyPress) { 63515 if (!hasSelectedBlock() && !hasMultiSelection()) { 63516 // Set the starting point of the selection to the currently 63517 // focused block, if there are no blocks currently selected. 63518 // This ensures that as the selection is expanded or contracted, 63519 // the starting point of the selection is anchored to that block. 63520 startTarget = clientId; 63521 } 63522 if (destinationClientId) { 63523 // If the user presses UP or DOWN, we want to ensure that the block they're 63524 // moving to is the target for selection, and not the currently focused one. 63525 endTarget = destinationClientId; 63526 } 63527 } 63528 const startParents = getBlockParents(startTarget); 63529 const endParents = getBlockParents(endTarget); 63530 const { 63531 start, 63532 end 63533 } = getCommonDepthClientIds(startTarget, endTarget, startParents, endParents); 63534 await multiSelect(start, end, null); 63535 } 63536 63537 // Announce deselected block, or number of deselected blocks if 63538 // the total number of blocks deselected is greater than one. 63539 const updatedSelectedBlocks = getSelectedBlockClientIds(); 63540 63541 // If the selection is greater than 1 and the Home or End keys 63542 // were used to generate the selection, then skip announcing the 63543 // deselected blocks. 63544 if ((event.keyCode === external_wp_keycodes_namespaceObject.HOME || event.keyCode === external_wp_keycodes_namespaceObject.END) && updatedSelectedBlocks.length > 1) { 63545 return; 63546 } 63547 const selectionDiff = selectedBlocks.filter(blockId => !updatedSelectedBlocks.includes(blockId)); 63548 let label; 63549 if (selectionDiff.length === 1) { 63550 const title = getBlockType(getBlockName(selectionDiff[0]))?.title; 63551 if (title) { 63552 label = (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: block name */ 63553 (0,external_wp_i18n_namespaceObject.__)('%s deselected.'), title); 63554 } 63555 } else if (selectionDiff.length > 1) { 63556 label = (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: number of deselected blocks */ 63557 (0,external_wp_i18n_namespaceObject.__)('%s blocks deselected.'), selectionDiff.length); 63558 } 63559 if (label) { 63560 (0,external_wp_a11y_namespaceObject.speak)(label, 'assertive'); 63561 } 63562 }, [clearSelectedBlock, getBlockName, getBlockType, getBlockParents, getBlockSelectionStart, getSelectedBlockClientIds, hasMultiSelection, hasSelectedBlock, multiSelect, selectBlock]); 63563 return { 63564 updateBlockSelection 63565 }; 63566 } 63567 63568 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-block-indexes.js 63569 /** 63570 * WordPress dependencies 63571 */ 63572 63573 function useListViewBlockIndexes(blocks) { 63574 const blockIndexes = (0,external_wp_element_namespaceObject.useMemo)(() => { 63575 const indexes = {}; 63576 let currentGlobalIndex = 0; 63577 const traverseBlocks = blockList => { 63578 blockList.forEach(block => { 63579 indexes[block.clientId] = currentGlobalIndex; 63580 currentGlobalIndex++; 63581 if (block.innerBlocks.length > 0) { 63582 traverseBlocks(block.innerBlocks); 63583 } 63584 }); 63585 }; 63586 traverseBlocks(blocks); 63587 return indexes; 63588 }, [blocks]); 63589 return blockIndexes; 63590 } 63591 63592 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-client-ids.js 63593 /** 63594 * WordPress dependencies 63595 */ 63596 63597 63598 63599 /** 63600 * Internal dependencies 63601 */ 63602 63603 63604 function useListViewClientIds({ 63605 blocks, 63606 rootClientId 63607 }) { 63608 return (0,external_wp_data_namespaceObject.useSelect)(select => { 63609 const { 63610 getDraggedBlockClientIds, 63611 getSelectedBlockClientIds, 63612 getEnabledClientIdsTree 63613 } = unlock(select(store)); 63614 return { 63615 selectedClientIds: getSelectedBlockClientIds(), 63616 draggedClientIds: getDraggedBlockClientIds(), 63617 clientIdsTree: blocks !== null && blocks !== void 0 ? blocks : getEnabledClientIdsTree(rootClientId) 63618 }; 63619 }, [blocks, rootClientId]); 63620 } 63621 63622 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-collapse-items.js 63623 /** 63624 * WordPress dependencies 63625 */ 63626 63627 63628 63629 /** 63630 * Internal dependencies 63631 */ 63632 63633 63634 function useListViewCollapseItems({ 63635 collapseAll, 63636 expand 63637 }) { 63638 const { 63639 expandedBlock, 63640 getBlockParents 63641 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 63642 const { 63643 getBlockParents: _getBlockParents, 63644 getExpandedBlock 63645 } = unlock(select(store)); 63646 return { 63647 expandedBlock: getExpandedBlock(), 63648 getBlockParents: _getBlockParents 63649 }; 63650 }, []); 63651 63652 // Collapse all but the specified block when the expanded block client Id changes. 63653 (0,external_wp_element_namespaceObject.useEffect)(() => { 63654 if (expandedBlock) { 63655 const blockParents = getBlockParents(expandedBlock, false); 63656 // Collapse all blocks and expand the block's parents. 63657 collapseAll(); 63658 expand(blockParents); 63659 } 63660 }, [collapseAll, expand, expandedBlock, getBlockParents]); 63661 } 63662 63663 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-drop-zone.js 63664 /** 63665 * WordPress dependencies 63666 */ 63667 63668 63669 63670 63671 63672 /** 63673 * Internal dependencies 63674 */ 63675 63676 63677 63678 63679 /** @typedef {import('../../utils/math').WPPoint} WPPoint */ 63680 63681 /** 63682 * The type of a drag event. 63683 * 63684 * @typedef {'default'|'file'|'html'} WPDragEventType 63685 */ 63686 63687 /** 63688 * An object representing data for blocks in the DOM used by drag and drop. 63689 * 63690 * @typedef {Object} WPListViewDropZoneBlock 63691 * @property {string} clientId The client id for the block. 63692 * @property {string} rootClientId The root client id for the block. 63693 * @property {number} blockIndex The block's index. 63694 * @property {Element} element The DOM element representing the block. 63695 * @property {number} innerBlockCount The number of inner blocks the block has. 63696 * @property {boolean} isDraggedBlock Whether the block is currently being dragged. 63697 * @property {boolean} isExpanded Whether the block is expanded in the UI. 63698 * @property {boolean} canInsertDraggedBlocksAsSibling Whether the dragged block can be a sibling of this block. 63699 * @property {boolean} canInsertDraggedBlocksAsChild Whether the dragged block can be a child of this block. 63700 */ 63701 63702 /** 63703 * An array representing data for blocks in the DOM used by drag and drop. 63704 * 63705 * @typedef {WPListViewDropZoneBlock[]} WPListViewDropZoneBlocks 63706 */ 63707 63708 /** 63709 * An object containing details of a drop target. 63710 * 63711 * @typedef {Object} WPListViewDropZoneTarget 63712 * @property {string} blockIndex The insertion index. 63713 * @property {string} rootClientId The root client id for the block. 63714 * @property {string|undefined} clientId The client id for the block. 63715 * @property {'top'|'bottom'|'inside'} dropPosition The position relative to the block that the user is dropping to. 63716 * 'inside' refers to nesting as an inner block. 63717 */ 63718 63719 // When the indentation level, the corresponding left margin in `style.scss` 63720 // must be updated as well to ensure the drop zone is aligned with the indentation. 63721 const NESTING_LEVEL_INDENTATION = 24; 63722 63723 /** 63724 * Determines whether the user is positioning the dragged block to be 63725 * moved up to a parent level. 63726 * 63727 * Determined based on nesting level indentation of the current block. 63728 * 63729 * @param {WPPoint} point The point representing the cursor position when dragging. 63730 * @param {DOMRect} rect The rectangle. 63731 * @param {number} nestingLevel The nesting level of the block. 63732 * @param {boolean} rtl Whether the editor is in RTL mode. 63733 * @return {boolean} Whether the gesture is an upward gesture. 63734 */ 63735 function isUpGesture(point, rect, nestingLevel = 1, rtl = false) { 63736 // If the block is nested, and the user is dragging to the bottom 63737 // left of the block (or bottom right in RTL languages), then it is an upward gesture. 63738 const blockIndentPosition = rtl ? rect.right - nestingLevel * NESTING_LEVEL_INDENTATION : rect.left + nestingLevel * NESTING_LEVEL_INDENTATION; 63739 return rtl ? point.x > blockIndentPosition : point.x < blockIndentPosition; 63740 } 63741 63742 /** 63743 * Returns how many nesting levels up the user is attempting to drag to. 63744 * 63745 * The relative parent level is calculated based on how far 63746 * the cursor is from the provided nesting level (e.g. of a candidate block 63747 * that the user is hovering over). The nesting level is considered "desired" 63748 * because it is not guaranteed that the user will be able to drag to the desired level. 63749 * 63750 * The returned integer can be used to access an ascending array 63751 * of parent blocks, where the first item is the block the user 63752 * is hovering over, and the last item is the root block. 63753 * 63754 * @param {WPPoint} point The point representing the cursor position when dragging. 63755 * @param {DOMRect} rect The rectangle. 63756 * @param {number} nestingLevel The nesting level of the block. 63757 * @param {boolean} rtl Whether the editor is in RTL mode. 63758 * @return {number} The desired relative parent level. 63759 */ 63760 function getDesiredRelativeParentLevel(point, rect, nestingLevel = 1, rtl = false) { 63761 // In RTL languages, the block indent position is from the right edge of the block. 63762 // In LTR languages, the block indent position is from the left edge of the block. 63763 const blockIndentPosition = rtl ? rect.right - nestingLevel * NESTING_LEVEL_INDENTATION : rect.left + nestingLevel * NESTING_LEVEL_INDENTATION; 63764 const distanceBetweenPointAndBlockIndentPosition = rtl ? blockIndentPosition - point.x : point.x - blockIndentPosition; 63765 const desiredParentLevel = Math.round(distanceBetweenPointAndBlockIndentPosition / NESTING_LEVEL_INDENTATION); 63766 return Math.abs(desiredParentLevel); 63767 } 63768 63769 /** 63770 * Returns an array of the parent blocks of the block the user is dropping to. 63771 * 63772 * @param {WPListViewDropZoneBlock} candidateBlockData The block the user is dropping to. 63773 * @param {WPListViewDropZoneBlocks} blocksData Data about the blocks in list view. 63774 * @return {WPListViewDropZoneBlocks} An array of block parents, including the block the user is dropping to. 63775 */ 63776 function getCandidateBlockParents(candidateBlockData, blocksData) { 63777 const candidateBlockParents = []; 63778 let currentBlockData = candidateBlockData; 63779 while (currentBlockData) { 63780 candidateBlockParents.push({ 63781 ...currentBlockData 63782 }); 63783 currentBlockData = blocksData.find(blockData => blockData.clientId === currentBlockData.rootClientId); 63784 } 63785 return candidateBlockParents; 63786 } 63787 63788 /** 63789 * Given a list of blocks data and a block index, return the next non-dragged 63790 * block. This is used to determine the block that the user is dropping to, 63791 * while ignoring the dragged block. 63792 * 63793 * @param {WPListViewDropZoneBlocks} blocksData Data about the blocks in list view. 63794 * @param {number} index The index to begin searching from. 63795 * @return {WPListViewDropZoneBlock | undefined} The next non-dragged block. 63796 */ 63797 function getNextNonDraggedBlock(blocksData, index) { 63798 const nextBlockData = blocksData[index + 1]; 63799 if (nextBlockData && nextBlockData.isDraggedBlock) { 63800 return getNextNonDraggedBlock(blocksData, index + 1); 63801 } 63802 return nextBlockData; 63803 } 63804 63805 /** 63806 * Determines whether the user positioning the dragged block to nest as an 63807 * inner block. 63808 * 63809 * Determined based on nesting level indentation of the current block, plus 63810 * the indentation of the next level of nesting. The vertical position of the 63811 * cursor must also be within the block. 63812 * 63813 * @param {WPPoint} point The point representing the cursor position when dragging. 63814 * @param {DOMRect} rect The rectangle. 63815 * @param {number} nestingLevel The nesting level of the block. 63816 * @param {boolean} rtl Whether the editor is in RTL mode. 63817 */ 63818 function isNestingGesture(point, rect, nestingLevel = 1, rtl = false) { 63819 const blockIndentPosition = rtl ? rect.right - nestingLevel * NESTING_LEVEL_INDENTATION : rect.left + nestingLevel * NESTING_LEVEL_INDENTATION; 63820 const isNestingHorizontalGesture = rtl ? point.x < blockIndentPosition - NESTING_LEVEL_INDENTATION : point.x > blockIndentPosition + NESTING_LEVEL_INDENTATION; 63821 return isNestingHorizontalGesture && point.y < rect.bottom; 63822 } 63823 63824 // Block navigation is always a vertical list, so only allow dropping 63825 // to the above or below a block. 63826 const ALLOWED_DROP_EDGES = ['top', 'bottom']; 63827 63828 /** 63829 * Given blocks data and the cursor position, compute the drop target. 63830 * 63831 * @param {WPListViewDropZoneBlocks} blocksData Data about the blocks in list view. 63832 * @param {WPPoint} position The point representing the cursor position when dragging. 63833 * @param {boolean} rtl Whether the editor is in RTL mode. 63834 * 63835 * @return {WPListViewDropZoneTarget | undefined} An object containing data about the drop target. 63836 */ 63837 function getListViewDropTarget(blocksData, position, rtl = false) { 63838 let candidateEdge; 63839 let candidateBlockData; 63840 let candidateDistance; 63841 let candidateRect; 63842 let candidateBlockIndex; 63843 for (let i = 0; i < blocksData.length; i++) { 63844 const blockData = blocksData[i]; 63845 if (blockData.isDraggedBlock) { 63846 continue; 63847 } 63848 const rect = blockData.element.getBoundingClientRect(); 63849 const [distance, edge] = getDistanceToNearestEdge(position, rect, ALLOWED_DROP_EDGES); 63850 const isCursorWithinBlock = isPointContainedByRect(position, rect); 63851 if (candidateDistance === undefined || distance < candidateDistance || isCursorWithinBlock) { 63852 candidateDistance = distance; 63853 const index = blocksData.indexOf(blockData); 63854 const previousBlockData = blocksData[index - 1]; 63855 63856 // If dragging near the top of a block and the preceding block 63857 // is at the same level, use the preceding block as the candidate 63858 // instead, as later it makes determining a nesting drop easier. 63859 if (edge === 'top' && previousBlockData && previousBlockData.rootClientId === blockData.rootClientId && !previousBlockData.isDraggedBlock) { 63860 candidateBlockData = previousBlockData; 63861 candidateEdge = 'bottom'; 63862 candidateRect = previousBlockData.element.getBoundingClientRect(); 63863 candidateBlockIndex = index - 1; 63864 } else { 63865 candidateBlockData = blockData; 63866 candidateEdge = edge; 63867 candidateRect = rect; 63868 candidateBlockIndex = index; 63869 } 63870 63871 // If the mouse position is within the block, break early 63872 // as the user would intend to drop either before or after 63873 // this block. 63874 // 63875 // This solves an issue where some rows in the list view 63876 // tree overlap slightly due to sub-pixel rendering. 63877 if (isCursorWithinBlock) { 63878 break; 63879 } 63880 } 63881 } 63882 if (!candidateBlockData) { 63883 return; 63884 } 63885 const candidateBlockParents = getCandidateBlockParents(candidateBlockData, blocksData); 63886 const isDraggingBelow = candidateEdge === 'bottom'; 63887 63888 // If the user is dragging towards the bottom of the block check whether 63889 // they might be trying to nest the block as a child. 63890 // If the block already has inner blocks, and is expanded, this should be treated 63891 // as nesting since the next block in the tree will be the first child. 63892 // However, if the block is collapsed, dragging beneath the block should 63893 // still be allowed, as the next visible block in the tree will be a sibling. 63894 if (isDraggingBelow && candidateBlockData.canInsertDraggedBlocksAsChild && (candidateBlockData.innerBlockCount > 0 && candidateBlockData.isExpanded || isNestingGesture(position, candidateRect, candidateBlockParents.length, rtl))) { 63895 // If the block is expanded, insert the block as the first child. 63896 // Otherwise, for collapsed blocks, insert the block as the last child. 63897 const newBlockIndex = candidateBlockData.isExpanded ? 0 : candidateBlockData.innerBlockCount || 0; 63898 return { 63899 rootClientId: candidateBlockData.clientId, 63900 clientId: candidateBlockData.clientId, 63901 blockIndex: newBlockIndex, 63902 dropPosition: 'inside' 63903 }; 63904 } 63905 63906 // If the user is dragging towards the bottom of the block check whether 63907 // they might be trying to move the block to be at a parent level. 63908 if (isDraggingBelow && candidateBlockData.rootClientId && isUpGesture(position, candidateRect, candidateBlockParents.length, rtl)) { 63909 const nextBlock = getNextNonDraggedBlock(blocksData, candidateBlockIndex); 63910 const currentLevel = candidateBlockData.nestingLevel; 63911 const nextLevel = nextBlock ? nextBlock.nestingLevel : 1; 63912 if (currentLevel && nextLevel) { 63913 // Determine the desired relative level of the block to be dropped. 63914 const desiredRelativeLevel = getDesiredRelativeParentLevel(position, candidateRect, candidateBlockParents.length, rtl); 63915 const targetParentIndex = Math.max(Math.min(desiredRelativeLevel, currentLevel - nextLevel), 0); 63916 if (candidateBlockParents[targetParentIndex]) { 63917 // Default to the block index of the candidate block. 63918 let newBlockIndex = candidateBlockData.blockIndex; 63919 63920 // If the next block is at the same level, use that as the default 63921 // block index. This ensures that the block is dropped in the correct 63922 // position when dragging to the bottom of a block. 63923 if (candidateBlockParents[targetParentIndex].nestingLevel === nextBlock?.nestingLevel) { 63924 newBlockIndex = nextBlock?.blockIndex; 63925 } else { 63926 // Otherwise, search from the current block index back 63927 // to find the last block index within the same target parent. 63928 for (let i = candidateBlockIndex; i >= 0; i--) { 63929 const blockData = blocksData[i]; 63930 if (blockData.rootClientId === candidateBlockParents[targetParentIndex].rootClientId) { 63931 newBlockIndex = blockData.blockIndex + 1; 63932 break; 63933 } 63934 } 63935 } 63936 return { 63937 rootClientId: candidateBlockParents[targetParentIndex].rootClientId, 63938 clientId: candidateBlockData.clientId, 63939 blockIndex: newBlockIndex, 63940 dropPosition: candidateEdge 63941 }; 63942 } 63943 } 63944 } 63945 63946 // If dropping as a sibling, but block cannot be inserted in 63947 // this context, return early. 63948 if (!candidateBlockData.canInsertDraggedBlocksAsSibling) { 63949 return; 63950 } 63951 const offset = isDraggingBelow ? 1 : 0; 63952 return { 63953 rootClientId: candidateBlockData.rootClientId, 63954 clientId: candidateBlockData.clientId, 63955 blockIndex: candidateBlockData.blockIndex + offset, 63956 dropPosition: candidateEdge 63957 }; 63958 } 63959 63960 // Throttle options need to be defined outside of the hook to avoid 63961 // re-creating the object on every render. This is due to a limitation 63962 // of the `useThrottle` hook, where the options object is included 63963 // in the dependency array for memoization. 63964 const EXPAND_THROTTLE_OPTIONS = { 63965 leading: false, 63966 // Don't call the function immediately on the first call. 63967 trailing: true // Do call the function on the last call. 63968 }; 63969 63970 /** 63971 * A react hook for implementing a drop zone in list view. 63972 * 63973 * @param {Object} props Named parameters. 63974 * @param {?HTMLElement} [props.dropZoneElement] Optional element to be used as the drop zone. 63975 * @param {Object} [props.expandedState] The expanded state of the blocks in the list view. 63976 * @param {Function} [props.setExpandedState] Function to set the expanded state of a list of block clientIds. 63977 * 63978 * @return {WPListViewDropZoneTarget} The drop target. 63979 */ 63980 function useListViewDropZone({ 63981 dropZoneElement, 63982 expandedState, 63983 setExpandedState 63984 }) { 63985 const { 63986 getBlockRootClientId, 63987 getBlockIndex, 63988 getBlockCount, 63989 getDraggedBlockClientIds, 63990 canInsertBlocks 63991 } = (0,external_wp_data_namespaceObject.useSelect)(store); 63992 const [target, setTarget] = (0,external_wp_element_namespaceObject.useState)(); 63993 const { 63994 rootClientId: targetRootClientId, 63995 blockIndex: targetBlockIndex 63996 } = target || {}; 63997 const onBlockDrop = useOnBlockDrop(targetRootClientId, targetBlockIndex); 63998 const rtl = (0,external_wp_i18n_namespaceObject.isRTL)(); 63999 const previousRootClientId = (0,external_wp_compose_namespaceObject.usePrevious)(targetRootClientId); 64000 const maybeExpandBlock = (0,external_wp_element_namespaceObject.useCallback)((_expandedState, _target) => { 64001 // If the user is attempting to drop a block inside a collapsed block, 64002 // that is, using a nesting gesture flagged by 'inside' dropPosition, 64003 // expand the block within the list view, if it isn't already. 64004 const { 64005 rootClientId 64006 } = _target || {}; 64007 if (!rootClientId) { 64008 return; 64009 } 64010 if (_target?.dropPosition === 'inside' && !_expandedState[rootClientId]) { 64011 setExpandedState({ 64012 type: 'expand', 64013 clientIds: [rootClientId] 64014 }); 64015 } 64016 }, [setExpandedState]); 64017 64018 // Throttle the maybeExpandBlock function to avoid expanding the block 64019 // too quickly when the user is dragging over the block. This is to 64020 // avoid expanding the block when the user is just passing over it. 64021 const throttledMaybeExpandBlock = (0,external_wp_compose_namespaceObject.useThrottle)(maybeExpandBlock, 500, EXPAND_THROTTLE_OPTIONS); 64022 (0,external_wp_element_namespaceObject.useEffect)(() => { 64023 if (target?.dropPosition !== 'inside' || previousRootClientId !== target?.rootClientId) { 64024 throttledMaybeExpandBlock.cancel(); 64025 return; 64026 } 64027 throttledMaybeExpandBlock(expandedState, target); 64028 }, [expandedState, previousRootClientId, target, throttledMaybeExpandBlock]); 64029 const draggedBlockClientIds = getDraggedBlockClientIds(); 64030 const throttled = (0,external_wp_compose_namespaceObject.useThrottle)((0,external_wp_element_namespaceObject.useCallback)((event, currentTarget) => { 64031 const position = { 64032 x: event.clientX, 64033 y: event.clientY 64034 }; 64035 const isBlockDrag = !!draggedBlockClientIds?.length; 64036 const blockElements = Array.from(currentTarget.querySelectorAll('[data-block]')); 64037 const blocksData = blockElements.map(blockElement => { 64038 const clientId = blockElement.dataset.block; 64039 const isExpanded = blockElement.dataset.expanded === 'true'; 64040 const isDraggedBlock = blockElement.classList.contains('is-dragging'); 64041 64042 // Get nesting level from `aria-level` attribute because Firefox does not support `element.ariaLevel`. 64043 const nestingLevel = parseInt(blockElement.getAttribute('aria-level'), 10); 64044 const rootClientId = getBlockRootClientId(clientId); 64045 return { 64046 clientId, 64047 isExpanded, 64048 rootClientId, 64049 blockIndex: getBlockIndex(clientId), 64050 element: blockElement, 64051 nestingLevel: nestingLevel || undefined, 64052 isDraggedBlock: isBlockDrag ? isDraggedBlock : false, 64053 innerBlockCount: getBlockCount(clientId), 64054 canInsertDraggedBlocksAsSibling: isBlockDrag ? canInsertBlocks(draggedBlockClientIds, rootClientId) : true, 64055 canInsertDraggedBlocksAsChild: isBlockDrag ? canInsertBlocks(draggedBlockClientIds, clientId) : true 64056 }; 64057 }); 64058 const newTarget = getListViewDropTarget(blocksData, position, rtl); 64059 if (newTarget) { 64060 setTarget(newTarget); 64061 } 64062 }, [canInsertBlocks, draggedBlockClientIds, getBlockCount, getBlockIndex, getBlockRootClientId, rtl]), 50); 64063 const ref = (0,external_wp_compose_namespaceObject.__experimentalUseDropZone)({ 64064 dropZoneElement, 64065 onDrop(event) { 64066 throttled.cancel(); 64067 if (target) { 64068 onBlockDrop(event); 64069 } 64070 // Use `undefined` value to indicate that the drag has concluded. 64071 // This allows styling rules that are active only when a user is 64072 // dragging to be removed. 64073 setTarget(undefined); 64074 }, 64075 onDragLeave() { 64076 throttled.cancel(); 64077 // Use `null` value to indicate that the drop target is not valid, 64078 // but that the drag is still active. This allows for styling rules 64079 // that are active only when a user drags outside of the list view. 64080 setTarget(null); 64081 }, 64082 onDragOver(event) { 64083 // `currentTarget` is only available while the event is being 64084 // handled, so get it now and pass it to the thottled function. 64085 // https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget 64086 throttled(event, event.currentTarget); 64087 }, 64088 onDragEnd() { 64089 throttled.cancel(); 64090 // Use `undefined` value to indicate that the drag has concluded. 64091 // This allows styling rules that are active only when a user is 64092 // dragging to be removed. 64093 setTarget(undefined); 64094 } 64095 }); 64096 return { 64097 ref, 64098 target 64099 }; 64100 } 64101 64102 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-list-view-expand-selected-item.js 64103 /** 64104 * WordPress dependencies 64105 */ 64106 64107 64108 64109 /** 64110 * Internal dependencies 64111 */ 64112 64113 function useListViewExpandSelectedItem({ 64114 firstSelectedBlockClientId, 64115 setExpandedState 64116 }) { 64117 const [selectedTreeId, setSelectedTreeId] = (0,external_wp_element_namespaceObject.useState)(null); 64118 const { 64119 selectedBlockParentClientIds 64120 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 64121 const { 64122 getBlockParents 64123 } = select(store); 64124 return { 64125 selectedBlockParentClientIds: getBlockParents(firstSelectedBlockClientId, false) 64126 }; 64127 }, [firstSelectedBlockClientId]); 64128 64129 // Expand tree when a block is selected. 64130 (0,external_wp_element_namespaceObject.useEffect)(() => { 64131 // If the selectedTreeId is the same as the selected block, 64132 // it means that the block was selected using the block list tree. 64133 if (selectedTreeId === firstSelectedBlockClientId) { 64134 return; 64135 } 64136 64137 // If the selected block has parents, get the top-level parent. 64138 if (selectedBlockParentClientIds?.length) { 64139 // If the selected block has parents, 64140 // expand the tree branch. 64141 setExpandedState({ 64142 type: 'expand', 64143 clientIds: selectedBlockParentClientIds 64144 }); 64145 } 64146 }, [firstSelectedBlockClientId, selectedBlockParentClientIds, selectedTreeId, setExpandedState]); 64147 return { 64148 setSelectedTreeId 64149 }; 64150 } 64151 64152 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/use-clipboard-handler.js 64153 /** 64154 * WordPress dependencies 64155 */ 64156 64157 64158 64159 /** 64160 * Internal dependencies 64161 */ 64162 64163 64164 64165 64166 64167 // This hook borrows from useClipboardHandler in ../writing-flow/use-clipboard-handler.js 64168 // and adds behaviour for the list view, while skipping partial selection. 64169 function use_clipboard_handler_useClipboardHandler({ 64170 selectBlock 64171 }) { 64172 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 64173 const { 64174 getBlockOrder, 64175 getBlockRootClientId, 64176 getBlocksByClientId, 64177 getPreviousBlockClientId, 64178 getSelectedBlockClientIds, 64179 getSettings, 64180 canInsertBlockType, 64181 canRemoveBlocks 64182 } = (0,external_wp_data_namespaceObject.useSelect)(store); 64183 const { 64184 flashBlock, 64185 removeBlocks, 64186 replaceBlocks, 64187 insertBlocks 64188 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 64189 const notifyCopy = useNotifyCopy(); 64190 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 64191 function updateFocusAndSelection(focusClientId, shouldSelectBlock) { 64192 if (shouldSelectBlock) { 64193 selectBlock(undefined, focusClientId, null, null); 64194 } 64195 focusListItem(focusClientId, node); 64196 } 64197 64198 // Determine which blocks to update: 64199 // If the current (focused) block is part of the block selection, use the whole selection. 64200 // If the focused block is not part of the block selection, only update the focused block. 64201 function getBlocksToUpdate(clientId) { 64202 const selectedBlockClientIds = getSelectedBlockClientIds(); 64203 const isUpdatingSelectedBlocks = selectedBlockClientIds.includes(clientId); 64204 const firstBlockClientId = isUpdatingSelectedBlocks ? selectedBlockClientIds[0] : clientId; 64205 const firstBlockRootClientId = getBlockRootClientId(firstBlockClientId); 64206 const blocksToUpdate = isUpdatingSelectedBlocks ? selectedBlockClientIds : [clientId]; 64207 return { 64208 blocksToUpdate, 64209 firstBlockClientId, 64210 firstBlockRootClientId, 64211 originallySelectedBlockClientIds: selectedBlockClientIds 64212 }; 64213 } 64214 function handler(event) { 64215 if (event.defaultPrevented) { 64216 // This was possibly already handled in rich-text/use-paste-handler.js. 64217 return; 64218 } 64219 64220 // Only handle events that occur within the list view. 64221 if (!node.contains(event.target.ownerDocument.activeElement)) { 64222 return; 64223 } 64224 64225 // Retrieve the block clientId associated with the focused list view row. 64226 // This enables applying copy / cut / paste behavior to the focused block, 64227 // rather than just the blocks that are currently selected. 64228 const listViewRow = event.target.ownerDocument.activeElement?.closest('[role=row]'); 64229 const clientId = listViewRow?.dataset?.block; 64230 if (!clientId) { 64231 return; 64232 } 64233 const { 64234 blocksToUpdate: selectedBlockClientIds, 64235 firstBlockClientId, 64236 firstBlockRootClientId, 64237 originallySelectedBlockClientIds 64238 } = getBlocksToUpdate(clientId); 64239 if (selectedBlockClientIds.length === 0) { 64240 return; 64241 } 64242 event.preventDefault(); 64243 if (event.type === 'copy' || event.type === 'cut') { 64244 if (selectedBlockClientIds.length === 1) { 64245 flashBlock(selectedBlockClientIds[0]); 64246 } 64247 notifyCopy(event.type, selectedBlockClientIds); 64248 const blocks = getBlocksByClientId(selectedBlockClientIds); 64249 setClipboardBlocks(event, blocks, registry); 64250 } 64251 if (event.type === 'cut') { 64252 var _getPreviousBlockClie; 64253 // Don't update the selection if the blocks cannot be deleted. 64254 if (!canRemoveBlocks(selectedBlockClientIds)) { 64255 return; 64256 } 64257 let blockToFocus = (_getPreviousBlockClie = getPreviousBlockClientId(firstBlockClientId)) !== null && _getPreviousBlockClie !== void 0 ? _getPreviousBlockClie : 64258 // If the previous block is not found (when the first block is deleted), 64259 // fallback to focus the parent block. 64260 firstBlockRootClientId; 64261 64262 // Remove blocks, but don't update selection, and it will be handled below. 64263 removeBlocks(selectedBlockClientIds, false); 64264 64265 // Update the selection if the original selection has been removed. 64266 const shouldUpdateSelection = originallySelectedBlockClientIds.length > 0 && getSelectedBlockClientIds().length === 0; 64267 64268 // If there's no previous block nor parent block, focus the first block. 64269 if (!blockToFocus) { 64270 blockToFocus = getBlockOrder()[0]; 64271 } 64272 updateFocusAndSelection(blockToFocus, shouldUpdateSelection); 64273 } else if (event.type === 'paste') { 64274 const { 64275 __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML 64276 } = getSettings(); 64277 const blocks = getPasteBlocks(event, canUserUseUnfilteredHTML); 64278 if (selectedBlockClientIds.length === 1) { 64279 const [selectedBlockClientId] = selectedBlockClientIds; 64280 64281 // If a single block is focused, and the blocks to be posted can 64282 // be inserted within the block, then append the pasted blocks 64283 // within the focused block. For example, if you have copied a paragraph 64284 // block and paste it within a single Group block, this will append 64285 // the paragraph block within the Group block. 64286 if (blocks.every(block => canInsertBlockType(block.name, selectedBlockClientId))) { 64287 insertBlocks(blocks, undefined, selectedBlockClientId); 64288 updateFocusAndSelection(blocks[0]?.clientId, false); 64289 return; 64290 } 64291 } 64292 replaceBlocks(selectedBlockClientIds, blocks, blocks.length - 1, -1); 64293 updateFocusAndSelection(blocks[0]?.clientId, false); 64294 } 64295 } 64296 node.ownerDocument.addEventListener('copy', handler); 64297 node.ownerDocument.addEventListener('cut', handler); 64298 node.ownerDocument.addEventListener('paste', handler); 64299 return () => { 64300 node.ownerDocument.removeEventListener('copy', handler); 64301 node.ownerDocument.removeEventListener('cut', handler); 64302 node.ownerDocument.removeEventListener('paste', handler); 64303 }; 64304 }, []); 64305 } 64306 64307 ;// ./node_modules/@wordpress/block-editor/build-module/components/list-view/index.js 64308 /** 64309 * External dependencies 64310 */ 64311 64312 64313 /** 64314 * WordPress dependencies 64315 */ 64316 64317 64318 64319 64320 64321 64322 64323 /** 64324 * Internal dependencies 64325 */ 64326 64327 64328 64329 64330 64331 64332 64333 64334 64335 64336 64337 64338 64339 64340 const expanded = (state, action) => { 64341 if (action.type === 'clear') { 64342 return {}; 64343 } 64344 if (Array.isArray(action.clientIds)) { 64345 return { 64346 ...state, 64347 ...action.clientIds.reduce((newState, id) => ({ 64348 ...newState, 64349 [id]: action.type === 'expand' 64350 }), {}) 64351 }; 64352 } 64353 return state; 64354 }; 64355 const BLOCK_LIST_ITEM_HEIGHT = 32; 64356 64357 /** @typedef {import('react').ComponentType} ComponentType */ 64358 /** @typedef {import('react').Ref<HTMLElement>} Ref */ 64359 64360 /** 64361 * Show a hierarchical list of blocks. 64362 * 64363 * @param {Object} props Components props. 64364 * @param {string} props.id An HTML element id for the root element of ListView. 64365 * @param {Array} props.blocks _deprecated_ Custom subset of block client IDs to be used instead of the default hierarchy. 64366 * @param {?HTMLElement} props.dropZoneElement Optional element to be used as the drop zone. 64367 * @param {?boolean} props.showBlockMovers Flag to enable block movers. Defaults to `false`. 64368 * @param {?boolean} props.isExpanded Flag to determine whether nested levels are expanded by default. Defaults to `false`. 64369 * @param {?boolean} props.showAppender Flag to show or hide the block appender. Defaults to `false`. 64370 * @param {?ComponentType} props.blockSettingsMenu Optional more menu substitution. Defaults to the standard `BlockSettingsDropdown` component. 64371 * @param {string} props.rootClientId The client id of the root block from which we determine the blocks to show in the list. 64372 * @param {string} props.description Optional accessible description for the tree grid component. 64373 * @param {?Function} props.onSelect Optional callback to be invoked when a block is selected. Receives the block object that was selected. 64374 * @param {?ComponentType} props.additionalBlockContent Component that renders additional block content UI. 64375 * @param {Ref} ref Forwarded ref 64376 */ 64377 function ListViewComponent({ 64378 id, 64379 blocks, 64380 dropZoneElement, 64381 showBlockMovers = false, 64382 isExpanded = false, 64383 showAppender = false, 64384 blockSettingsMenu: BlockSettingsMenu = BlockSettingsDropdown, 64385 rootClientId, 64386 description, 64387 onSelect, 64388 additionalBlockContent: AdditionalBlockContent 64389 }, ref) { 64390 // This can be removed once we no longer need to support the blocks prop. 64391 if (blocks) { 64392 external_wp_deprecated_default()('`blocks` property in `wp.blockEditor.__experimentalListView`', { 64393 since: '6.3', 64394 alternative: '`rootClientId` property' 64395 }); 64396 } 64397 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(ListViewComponent); 64398 const { 64399 clientIdsTree, 64400 draggedClientIds, 64401 selectedClientIds 64402 } = useListViewClientIds({ 64403 blocks, 64404 rootClientId 64405 }); 64406 const blockIndexes = useListViewBlockIndexes(clientIdsTree); 64407 const { 64408 getBlock 64409 } = (0,external_wp_data_namespaceObject.useSelect)(store); 64410 const { 64411 visibleBlockCount 64412 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 64413 const { 64414 getGlobalBlockCount, 64415 getClientIdsOfDescendants 64416 } = select(store); 64417 const draggedBlockCount = draggedClientIds?.length > 0 ? getClientIdsOfDescendants(draggedClientIds).length + 1 : 0; 64418 return { 64419 visibleBlockCount: getGlobalBlockCount() - draggedBlockCount 64420 }; 64421 }, [draggedClientIds]); 64422 const { 64423 updateBlockSelection 64424 } = useBlockSelection(); 64425 const [expandedState, setExpandedState] = (0,external_wp_element_namespaceObject.useReducer)(expanded, {}); 64426 const [insertedBlock, setInsertedBlock] = (0,external_wp_element_namespaceObject.useState)(null); 64427 const { 64428 setSelectedTreeId 64429 } = useListViewExpandSelectedItem({ 64430 firstSelectedBlockClientId: selectedClientIds[0], 64431 setExpandedState 64432 }); 64433 const selectEditorBlock = (0,external_wp_element_namespaceObject.useCallback)( 64434 /** 64435 * @param {MouseEvent | KeyboardEvent | undefined} event 64436 * @param {string} blockClientId 64437 * @param {null | undefined | -1 | 1} focusPosition 64438 */ 64439 (event, blockClientId, focusPosition) => { 64440 updateBlockSelection(event, blockClientId, null, focusPosition); 64441 setSelectedTreeId(blockClientId); 64442 if (onSelect) { 64443 onSelect(getBlock(blockClientId)); 64444 } 64445 }, [setSelectedTreeId, updateBlockSelection, onSelect, getBlock]); 64446 const { 64447 ref: dropZoneRef, 64448 target: blockDropTarget 64449 } = useListViewDropZone({ 64450 dropZoneElement, 64451 expandedState, 64452 setExpandedState 64453 }); 64454 const elementRef = (0,external_wp_element_namespaceObject.useRef)(); 64455 64456 // Allow handling of copy, cut, and paste events. 64457 const clipBoardRef = use_clipboard_handler_useClipboardHandler({ 64458 selectBlock: selectEditorBlock 64459 }); 64460 const treeGridRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([clipBoardRef, elementRef, dropZoneRef, ref]); 64461 (0,external_wp_element_namespaceObject.useEffect)(() => { 64462 // If a blocks are already selected when the list view is initially 64463 // mounted, shift focus to the first selected block. 64464 if (selectedClientIds?.length) { 64465 focusListItem(selectedClientIds[0], elementRef?.current); 64466 } 64467 // Only focus on the selected item when the list view is mounted. 64468 }, []); 64469 const expand = (0,external_wp_element_namespaceObject.useCallback)(clientId => { 64470 if (!clientId) { 64471 return; 64472 } 64473 const clientIds = Array.isArray(clientId) ? clientId : [clientId]; 64474 setExpandedState({ 64475 type: 'expand', 64476 clientIds 64477 }); 64478 }, [setExpandedState]); 64479 const collapse = (0,external_wp_element_namespaceObject.useCallback)(clientId => { 64480 if (!clientId) { 64481 return; 64482 } 64483 setExpandedState({ 64484 type: 'collapse', 64485 clientIds: [clientId] 64486 }); 64487 }, [setExpandedState]); 64488 const collapseAll = (0,external_wp_element_namespaceObject.useCallback)(() => { 64489 setExpandedState({ 64490 type: 'clear' 64491 }); 64492 }, [setExpandedState]); 64493 const expandRow = (0,external_wp_element_namespaceObject.useCallback)(row => { 64494 expand(row?.dataset?.block); 64495 }, [expand]); 64496 const collapseRow = (0,external_wp_element_namespaceObject.useCallback)(row => { 64497 collapse(row?.dataset?.block); 64498 }, [collapse]); 64499 const focusRow = (0,external_wp_element_namespaceObject.useCallback)((event, startRow, endRow) => { 64500 if (event.shiftKey) { 64501 updateBlockSelection(event, startRow?.dataset?.block, endRow?.dataset?.block); 64502 } 64503 }, [updateBlockSelection]); 64504 useListViewCollapseItems({ 64505 collapseAll, 64506 expand 64507 }); 64508 const firstDraggedBlockClientId = draggedClientIds?.[0]; 64509 64510 // Convert a blockDropTarget into indexes relative to the blocks in the list view. 64511 // These values are used to determine which blocks should be displaced to make room 64512 // for the drop indicator. See `ListViewBranch` and `getDragDisplacementValues`. 64513 const { 64514 blockDropTargetIndex, 64515 blockDropPosition, 64516 firstDraggedBlockIndex 64517 } = (0,external_wp_element_namespaceObject.useMemo)(() => { 64518 let _blockDropTargetIndex, _firstDraggedBlockIndex; 64519 if (blockDropTarget?.clientId) { 64520 const foundBlockIndex = blockIndexes[blockDropTarget.clientId]; 64521 // If dragging below or inside the block, treat the drop target as the next block. 64522 _blockDropTargetIndex = foundBlockIndex === undefined || blockDropTarget?.dropPosition === 'top' ? foundBlockIndex : foundBlockIndex + 1; 64523 } else if (blockDropTarget === null) { 64524 // A `null` value is used to indicate that the user is dragging outside of the list view. 64525 _blockDropTargetIndex = null; 64526 } 64527 if (firstDraggedBlockClientId) { 64528 const foundBlockIndex = blockIndexes[firstDraggedBlockClientId]; 64529 _firstDraggedBlockIndex = foundBlockIndex === undefined || blockDropTarget?.dropPosition === 'top' ? foundBlockIndex : foundBlockIndex + 1; 64530 } 64531 return { 64532 blockDropTargetIndex: _blockDropTargetIndex, 64533 blockDropPosition: blockDropTarget?.dropPosition, 64534 firstDraggedBlockIndex: _firstDraggedBlockIndex 64535 }; 64536 }, [blockDropTarget, blockIndexes, firstDraggedBlockClientId]); 64537 const contextValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 64538 blockDropPosition, 64539 blockDropTargetIndex, 64540 blockIndexes, 64541 draggedClientIds, 64542 expandedState, 64543 expand, 64544 firstDraggedBlockIndex, 64545 collapse, 64546 collapseAll, 64547 BlockSettingsMenu, 64548 listViewInstanceId: instanceId, 64549 AdditionalBlockContent, 64550 insertedBlock, 64551 setInsertedBlock, 64552 treeGridElementRef: elementRef, 64553 rootClientId 64554 }), [blockDropPosition, blockDropTargetIndex, blockIndexes, draggedClientIds, expandedState, expand, firstDraggedBlockIndex, collapse, collapseAll, BlockSettingsMenu, instanceId, AdditionalBlockContent, insertedBlock, setInsertedBlock, rootClientId]); 64555 64556 // List View renders a fixed number of items and relies on each having a fixed item height of 36px. 64557 // If this value changes, we should also change the itemHeight value set in useFixedWindowList. 64558 // See: https://github.com/WordPress/gutenberg/pull/35230 for additional context. 64559 const [fixedListWindow] = (0,external_wp_compose_namespaceObject.__experimentalUseFixedWindowList)(elementRef, BLOCK_LIST_ITEM_HEIGHT, visibleBlockCount, { 64560 // Ensure that the windowing logic is recalculated when the expanded state changes. 64561 // This is necessary because expanding a collapsed block in a short list view can 64562 // switch the list view to a tall list view with a scrollbar, and vice versa. 64563 // When this happens, the windowing logic needs to be recalculated to ensure that 64564 // the correct number of blocks are rendered, by rechecking for a scroll container. 64565 expandedState, 64566 useWindowing: true, 64567 windowOverscan: 40 64568 }); 64569 64570 // If there are no blocks to show and we're not showing the appender, do not render the list view. 64571 if (!clientIdsTree.length && !showAppender) { 64572 return null; 64573 } 64574 const describedById = description && `block-editor-list-view-description-$instanceId}`; 64575 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_data_namespaceObject.AsyncModeProvider, { 64576 value: true, 64577 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListViewDropIndicatorPreview, { 64578 draggedBlockClientId: firstDraggedBlockClientId, 64579 listViewRef: elementRef, 64580 blockDropTarget: blockDropTarget 64581 }), description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 64582 id: describedById, 64583 children: description 64584 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTreeGrid, { 64585 id: id, 64586 className: dist_clsx('block-editor-list-view-tree', { 64587 'is-dragging': draggedClientIds?.length > 0 && blockDropTargetIndex !== undefined 64588 }), 64589 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block navigation structure'), 64590 ref: treeGridRef, 64591 onCollapseRow: collapseRow, 64592 onExpandRow: expandRow, 64593 onFocusRow: focusRow, 64594 applicationAriaLabel: (0,external_wp_i18n_namespaceObject.__)('Block navigation structure'), 64595 "aria-describedby": describedById, 64596 style: { 64597 '--wp-admin--list-view-dragged-items-height': draggedClientIds?.length ? `$BLOCK_LIST_ITEM_HEIGHT * (draggedClientIds.length - 1)}px` : null 64598 }, 64599 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ListViewContext.Provider, { 64600 value: contextValue, 64601 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(branch, { 64602 blocks: clientIdsTree, 64603 parentId: rootClientId, 64604 selectBlock: selectEditorBlock, 64605 showBlockMovers: showBlockMovers, 64606 fixedListWindow: fixedListWindow, 64607 selectedClientIds: selectedClientIds, 64608 isExpanded: isExpanded, 64609 showAppender: showAppender 64610 }) 64611 }) 64612 })] 64613 }); 64614 } 64615 64616 // This is the private API for the ListView component. 64617 // It allows access to all props, not just the public ones. 64618 const PrivateListView = (0,external_wp_element_namespaceObject.forwardRef)(ListViewComponent); 64619 64620 // This is the public API for the ListView component. 64621 // We wrap the PrivateListView component to hide some props from the public API. 64622 /* harmony default export */ const components_list_view = ((0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 64623 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateListView, { 64624 ref: ref, 64625 ...props, 64626 showAppender: false, 64627 rootClientId: null, 64628 onSelect: null, 64629 additionalBlockContent: null, 64630 blockSettingsMenu: undefined 64631 }); 64632 })); 64633 64634 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-navigation/dropdown.js 64635 /** 64636 * WordPress dependencies 64637 */ 64638 64639 64640 /** 64641 * WordPress dependencies 64642 */ 64643 64644 64645 64646 64647 64648 64649 /** 64650 * Internal dependencies 64651 */ 64652 64653 64654 64655 function BlockNavigationDropdownToggle({ 64656 isEnabled, 64657 onToggle, 64658 isOpen, 64659 innerRef, 64660 ...props 64661 }) { 64662 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 64663 __next40pxDefaultSize: true, 64664 ...props, 64665 ref: innerRef, 64666 icon: list_view, 64667 "aria-expanded": isOpen, 64668 "aria-haspopup": "true", 64669 onClick: isEnabled ? onToggle : undefined 64670 /* translators: button label text should, if possible, be under 16 characters. */, 64671 label: (0,external_wp_i18n_namespaceObject.__)('List view'), 64672 className: "block-editor-block-navigation", 64673 "aria-disabled": !isEnabled 64674 }); 64675 } 64676 function BlockNavigationDropdown({ 64677 isDisabled, 64678 ...props 64679 }, ref) { 64680 external_wp_deprecated_default()('wp.blockEditor.BlockNavigationDropdown', { 64681 since: '6.1', 64682 alternative: 'wp.components.Dropdown and wp.blockEditor.ListView' 64683 }); 64684 const hasBlocks = (0,external_wp_data_namespaceObject.useSelect)(select => !!select(store).getBlockCount(), []); 64685 const isEnabled = hasBlocks && !isDisabled; 64686 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 64687 contentClassName: "block-editor-block-navigation__popover", 64688 popoverProps: { 64689 placement: 'bottom-start' 64690 }, 64691 renderToggle: ({ 64692 isOpen, 64693 onToggle 64694 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockNavigationDropdownToggle, { 64695 ...props, 64696 innerRef: ref, 64697 isOpen: isOpen, 64698 onToggle: onToggle, 64699 isEnabled: isEnabled 64700 }), 64701 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 64702 className: "block-editor-block-navigation__container", 64703 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 64704 className: "block-editor-block-navigation__label", 64705 children: (0,external_wp_i18n_namespaceObject.__)('List view') 64706 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(components_list_view, {})] 64707 }) 64708 }); 64709 } 64710 /* harmony default export */ const dropdown = ((0,external_wp_element_namespaceObject.forwardRef)(BlockNavigationDropdown)); 64711 64712 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-styles/preview-panel.js 64713 /** 64714 * WordPress dependencies 64715 */ 64716 64717 64718 64719 /** 64720 * Internal dependencies 64721 */ 64722 64723 64724 64725 function BlockStylesPreviewPanel({ 64726 genericPreviewBlock, 64727 style, 64728 className, 64729 activeStyle 64730 }) { 64731 const example = (0,external_wp_blocks_namespaceObject.getBlockType)(genericPreviewBlock.name)?.example; 64732 const styleClassName = replaceActiveStyle(className, activeStyle, style); 64733 const previewBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => { 64734 return { 64735 ...genericPreviewBlock, 64736 title: style.label || style.name, 64737 description: style.description, 64738 initialAttributes: { 64739 ...genericPreviewBlock.attributes, 64740 className: styleClassName + ' block-editor-block-styles__block-preview-container' 64741 }, 64742 example 64743 }; 64744 }, [genericPreviewBlock, styleClassName]); 64745 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(preview_panel, { 64746 item: previewBlocks 64747 }); 64748 } 64749 64750 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-styles/index.js 64751 /** 64752 * External dependencies 64753 */ 64754 64755 64756 /** 64757 * WordPress dependencies 64758 */ 64759 64760 64761 64762 64763 /** 64764 * Internal dependencies 64765 */ 64766 64767 64768 64769 const block_styles_noop = () => {}; 64770 64771 // Block Styles component for the Settings Sidebar. 64772 function BlockStyles({ 64773 clientId, 64774 onSwitch = block_styles_noop, 64775 onHoverClassName = block_styles_noop 64776 }) { 64777 const { 64778 onSelect, 64779 stylesToRender, 64780 activeStyle, 64781 genericPreviewBlock, 64782 className: previewClassName 64783 } = useStylesForBlocks({ 64784 clientId, 64785 onSwitch 64786 }); 64787 const [hoveredStyle, setHoveredStyle] = (0,external_wp_element_namespaceObject.useState)(null); 64788 const isMobileViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<'); 64789 if (!stylesToRender || stylesToRender.length === 0) { 64790 return null; 64791 } 64792 const debouncedSetHoveredStyle = (0,external_wp_compose_namespaceObject.debounce)(setHoveredStyle, 250); 64793 const onSelectStylePreview = style => { 64794 onSelect(style); 64795 onHoverClassName(null); 64796 setHoveredStyle(null); 64797 debouncedSetHoveredStyle.cancel(); 64798 }; 64799 const styleItemHandler = item => { 64800 var _item$name; 64801 if (hoveredStyle === item) { 64802 debouncedSetHoveredStyle.cancel(); 64803 return; 64804 } 64805 debouncedSetHoveredStyle(item); 64806 onHoverClassName((_item$name = item?.name) !== null && _item$name !== void 0 ? _item$name : null); 64807 }; 64808 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 64809 className: "block-editor-block-styles", 64810 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 64811 className: "block-editor-block-styles__variants", 64812 children: stylesToRender.map(style => { 64813 const buttonText = style.label || style.name; 64814 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 64815 __next40pxDefaultSize: true, 64816 className: dist_clsx('block-editor-block-styles__item', { 64817 'is-active': activeStyle.name === style.name 64818 }), 64819 variant: "secondary", 64820 label: buttonText, 64821 onMouseEnter: () => styleItemHandler(style), 64822 onFocus: () => styleItemHandler(style), 64823 onMouseLeave: () => styleItemHandler(null), 64824 onBlur: () => styleItemHandler(null), 64825 onClick: () => onSelectStylePreview(style), 64826 "aria-current": activeStyle.name === style.name, 64827 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 64828 numberOfLines: 1, 64829 className: "block-editor-block-styles__item-text", 64830 children: buttonText 64831 }) 64832 }, style.name); 64833 }) 64834 }), hoveredStyle && !isMobileViewport && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 64835 placement: "left-start", 64836 offset: 34, 64837 focusOnMount: false, 64838 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 64839 className: "block-editor-block-styles__preview-panel", 64840 onMouseLeave: () => styleItemHandler(null), 64841 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockStylesPreviewPanel, { 64842 activeStyle: activeStyle, 64843 className: previewClassName, 64844 genericPreviewBlock: genericPreviewBlock, 64845 style: hoveredStyle 64846 }) 64847 }) 64848 })] 64849 }); 64850 } 64851 /* harmony default export */ const block_styles = (BlockStyles); 64852 64853 ;// ./node_modules/@wordpress/icons/build-module/library/paragraph.js 64854 /** 64855 * WordPress dependencies 64856 */ 64857 64858 64859 const paragraph = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64860 xmlns: "http://www.w3.org/2000/svg", 64861 viewBox: "0 0 24 24", 64862 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64863 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" 64864 }) 64865 }); 64866 /* harmony default export */ const library_paragraph = (paragraph); 64867 64868 ;// ./node_modules/@wordpress/icons/build-module/library/heading-level-1.js 64869 /** 64870 * WordPress dependencies 64871 */ 64872 64873 64874 const headingLevel1 = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64875 xmlns: "http://www.w3.org/2000/svg", 64876 viewBox: "0 0 24 24", 64877 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64878 d: "M17.6 7c-.6.9-1.5 1.7-2.6 2v1h2v7h2V7h-1.4zM11 11H7V7H5v10h2v-4h4v4h2V7h-2v4z" 64879 }) 64880 }); 64881 /* harmony default export */ const heading_level_1 = (headingLevel1); 64882 64883 ;// ./node_modules/@wordpress/icons/build-module/library/heading-level-2.js 64884 /** 64885 * WordPress dependencies 64886 */ 64887 64888 64889 const headingLevel2 = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64890 xmlns: "http://www.w3.org/2000/svg", 64891 viewBox: "0 0 24 24", 64892 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64893 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" 64894 }) 64895 }); 64896 /* harmony default export */ const heading_level_2 = (headingLevel2); 64897 64898 ;// ./node_modules/@wordpress/icons/build-module/library/heading-level-3.js 64899 /** 64900 * WordPress dependencies 64901 */ 64902 64903 64904 const headingLevel3 = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64905 xmlns: "http://www.w3.org/2000/svg", 64906 viewBox: "0 0 24 24", 64907 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64908 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" 64909 }) 64910 }); 64911 /* harmony default export */ const heading_level_3 = (headingLevel3); 64912 64913 ;// ./node_modules/@wordpress/icons/build-module/library/heading-level-4.js 64914 /** 64915 * WordPress dependencies 64916 */ 64917 64918 64919 const headingLevel4 = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64920 xmlns: "http://www.w3.org/2000/svg", 64921 viewBox: "0 0 24 24", 64922 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64923 d: "M20 13V7h-3l-4 6v2h5v2h2v-2h1v-2h-1zm-2 0h-2.8L18 9v4zm-9-2H5V7H3v10h2v-4h4v4h2V7H9v4z" 64924 }) 64925 }); 64926 /* harmony default export */ const heading_level_4 = (headingLevel4); 64927 64928 ;// ./node_modules/@wordpress/icons/build-module/library/heading-level-5.js 64929 /** 64930 * WordPress dependencies 64931 */ 64932 64933 64934 const headingLevel5 = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64935 xmlns: "http://www.w3.org/2000/svg", 64936 viewBox: "0 0 24 24", 64937 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64938 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" 64939 }) 64940 }); 64941 /* harmony default export */ const heading_level_5 = (headingLevel5); 64942 64943 ;// ./node_modules/@wordpress/icons/build-module/library/heading-level-6.js 64944 /** 64945 * WordPress dependencies 64946 */ 64947 64948 64949 const headingLevel6 = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 64950 xmlns: "http://www.w3.org/2000/svg", 64951 viewBox: "0 0 24 24", 64952 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 64953 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" 64954 }) 64955 }); 64956 /* harmony default export */ const heading_level_6 = (headingLevel6); 64957 64958 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-heading-level-dropdown/heading-level-icon.js 64959 /** 64960 * WordPress dependencies 64961 */ 64962 64963 64964 64965 /** @typedef {import('react').ComponentType} ComponentType */ 64966 64967 /** 64968 * HeadingLevelIcon props. 64969 * 64970 * @typedef WPHeadingLevelIconProps 64971 * 64972 * @property {number} level The heading level to show an icon for. 64973 */ 64974 64975 const LEVEL_TO_PATH = { 64976 0: library_paragraph, 64977 1: heading_level_1, 64978 2: heading_level_2, 64979 3: heading_level_3, 64980 4: heading_level_4, 64981 5: heading_level_5, 64982 6: heading_level_6 64983 }; 64984 64985 /** 64986 * Heading level icon. 64987 * 64988 * @param {WPHeadingLevelIconProps} props Component props. 64989 * 64990 * @return {?ComponentType} The icon. 64991 */ 64992 function HeadingLevelIcon({ 64993 level 64994 }) { 64995 if (LEVEL_TO_PATH[level]) { 64996 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 64997 icon: LEVEL_TO_PATH[level] 64998 }); 64999 } 65000 return null; 65001 } 65002 65003 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-heading-level-dropdown/index.js 65004 /** 65005 * WordPress dependencies 65006 */ 65007 65008 65009 65010 /** 65011 * Internal dependencies 65012 */ 65013 65014 65015 const HEADING_LEVELS = [1, 2, 3, 4, 5, 6]; 65016 const block_heading_level_dropdown_POPOVER_PROPS = { 65017 className: 'block-library-heading-level-dropdown' 65018 }; 65019 65020 /** @typedef {import('react').ComponentType} ComponentType */ 65021 65022 /** 65023 * HeadingLevelDropdown props. 65024 * 65025 * @typedef WPHeadingLevelDropdownProps 65026 * 65027 * @property {number} value The chosen heading level. 65028 * @property {number[]} options An array of supported heading levels. 65029 * @property {()=>number} onChange Function called with 65030 * the selected value changes. 65031 */ 65032 65033 /** 65034 * Dropdown for selecting a heading level (1 through 6) or paragraph (0). 65035 * 65036 * @param {WPHeadingLevelDropdownProps} props Component props. 65037 * 65038 * @return {ComponentType} The toolbar. 65039 */ 65040 function HeadingLevelDropdown({ 65041 options = HEADING_LEVELS, 65042 value, 65043 onChange 65044 }) { 65045 const validOptions = options.filter(option => option === 0 || HEADING_LEVELS.includes(option)).sort((a, b) => a - b); // Sorts numerically in ascending order; 65046 65047 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarDropdownMenu, { 65048 popoverProps: block_heading_level_dropdown_POPOVER_PROPS, 65049 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(HeadingLevelIcon, { 65050 level: value 65051 }), 65052 label: (0,external_wp_i18n_namespaceObject.__)('Change level'), 65053 controls: validOptions.map(targetLevel => { 65054 const isActive = targetLevel === value; 65055 return { 65056 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(HeadingLevelIcon, { 65057 level: targetLevel 65058 }), 65059 title: targetLevel === 0 ? (0,external_wp_i18n_namespaceObject.__)('Paragraph') : (0,external_wp_i18n_namespaceObject.sprintf)( 65060 // translators: %d: heading level e.g: "1", "2", "3" 65061 (0,external_wp_i18n_namespaceObject.__)('Heading %d'), targetLevel), 65062 isActive, 65063 onClick() { 65064 onChange(targetLevel); 65065 }, 65066 role: 'menuitemradio' 65067 }; 65068 }) 65069 }); 65070 } 65071 65072 ;// ./node_modules/@wordpress/icons/build-module/library/layout.js 65073 /** 65074 * WordPress dependencies 65075 */ 65076 65077 65078 const layout_layout = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 65079 xmlns: "http://www.w3.org/2000/svg", 65080 viewBox: "0 0 24 24", 65081 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 65082 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" 65083 }) 65084 }); 65085 /* harmony default export */ const library_layout = (layout_layout); 65086 65087 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-variation-picker/index.js 65088 /** 65089 * External dependencies 65090 */ 65091 65092 65093 /** 65094 * WordPress dependencies 65095 */ 65096 65097 65098 65099 65100 function BlockVariationPicker({ 65101 icon = library_layout, 65102 label = (0,external_wp_i18n_namespaceObject.__)('Choose variation'), 65103 instructions = (0,external_wp_i18n_namespaceObject.__)('Select a variation to start with:'), 65104 variations, 65105 onSelect, 65106 allowSkip 65107 }) { 65108 const classes = dist_clsx('block-editor-block-variation-picker', { 65109 'has-many-variations': variations.length > 4 65110 }); 65111 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Placeholder, { 65112 icon: icon, 65113 label: label, 65114 instructions: instructions, 65115 className: classes, 65116 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("ul", { 65117 className: "block-editor-block-variation-picker__variations", 65118 role: "list", 65119 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Block variations'), 65120 children: variations.map(variation => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 65121 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65122 __next40pxDefaultSize: true, 65123 variant: "tertiary", 65124 icon: variation.icon && variation.icon.src ? variation.icon.src : variation.icon, 65125 iconSize: 48, 65126 onClick: () => onSelect(variation), 65127 className: "block-editor-block-variation-picker__variation", 65128 label: variation.description || variation.title 65129 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 65130 className: "block-editor-block-variation-picker__variation-label", 65131 children: variation.title 65132 })] 65133 }, variation.name)) 65134 }), allowSkip && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65135 className: "block-editor-block-variation-picker__skip", 65136 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65137 __next40pxDefaultSize: true, 65138 variant: "link", 65139 onClick: () => onSelect(), 65140 children: (0,external_wp_i18n_namespaceObject.__)('Skip') 65141 }) 65142 })] 65143 }); 65144 } 65145 /* harmony default export */ const block_variation_picker = (BlockVariationPicker); 65146 65147 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/constants.js 65148 const VIEWMODES = { 65149 carousel: 'carousel', 65150 grid: 'grid' 65151 }; 65152 65153 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/setup-toolbar.js 65154 /** 65155 * WordPress dependencies 65156 */ 65157 65158 65159 65160 65161 /** 65162 * Internal dependencies 65163 */ 65164 65165 65166 const Actions = ({ 65167 onBlockPatternSelect 65168 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65169 className: "block-editor-block-pattern-setup__actions", 65170 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65171 __next40pxDefaultSize: true, 65172 variant: "primary", 65173 onClick: onBlockPatternSelect, 65174 children: (0,external_wp_i18n_namespaceObject.__)('Choose') 65175 }) 65176 }); 65177 const CarouselNavigation = ({ 65178 handlePrevious, 65179 handleNext, 65180 activeSlide, 65181 totalSlides 65182 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 65183 className: "block-editor-block-pattern-setup__navigation", 65184 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65185 size: "compact", 65186 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left, 65187 label: (0,external_wp_i18n_namespaceObject.__)('Previous pattern'), 65188 onClick: handlePrevious, 65189 disabled: activeSlide === 0, 65190 accessibleWhenDisabled: true 65191 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65192 size: "compact", 65193 icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right, 65194 label: (0,external_wp_i18n_namespaceObject.__)('Next pattern'), 65195 onClick: handleNext, 65196 disabled: activeSlide === totalSlides - 1, 65197 accessibleWhenDisabled: true 65198 })] 65199 }); 65200 const SetupToolbar = ({ 65201 viewMode, 65202 setViewMode, 65203 handlePrevious, 65204 handleNext, 65205 activeSlide, 65206 totalSlides, 65207 onBlockPatternSelect 65208 }) => { 65209 const isCarouselView = viewMode === VIEWMODES.carousel; 65210 const displayControls = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 65211 className: "block-editor-block-pattern-setup__display-controls", 65212 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65213 size: "compact", 65214 icon: stretch_full_width, 65215 label: (0,external_wp_i18n_namespaceObject.__)('Carousel view'), 65216 onClick: () => setViewMode(VIEWMODES.carousel), 65217 isPressed: isCarouselView 65218 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65219 size: "compact", 65220 icon: library_grid, 65221 label: (0,external_wp_i18n_namespaceObject.__)('Grid view'), 65222 onClick: () => setViewMode(VIEWMODES.grid), 65223 isPressed: viewMode === VIEWMODES.grid 65224 })] 65225 }); 65226 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 65227 className: "block-editor-block-pattern-setup__toolbar", 65228 children: [isCarouselView && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(CarouselNavigation, { 65229 handlePrevious: handlePrevious, 65230 handleNext: handleNext, 65231 activeSlide: activeSlide, 65232 totalSlides: totalSlides 65233 }), displayControls, isCarouselView && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Actions, { 65234 onBlockPatternSelect: onBlockPatternSelect 65235 })] 65236 }); 65237 }; 65238 /* harmony default export */ const setup_toolbar = (SetupToolbar); 65239 65240 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/use-patterns-setup.js 65241 /** 65242 * WordPress dependencies 65243 */ 65244 65245 65246 /** 65247 * Internal dependencies 65248 */ 65249 65250 function usePatternsSetup(clientId, blockName, filterPatternsFn) { 65251 return (0,external_wp_data_namespaceObject.useSelect)(select => { 65252 const { 65253 getBlockRootClientId, 65254 getPatternsByBlockTypes, 65255 __experimentalGetAllowedPatterns 65256 } = select(store); 65257 const rootClientId = getBlockRootClientId(clientId); 65258 if (filterPatternsFn) { 65259 return __experimentalGetAllowedPatterns(rootClientId).filter(filterPatternsFn); 65260 } 65261 return getPatternsByBlockTypes(blockName, rootClientId); 65262 }, [clientId, blockName, filterPatternsFn]); 65263 } 65264 /* harmony default export */ const use_patterns_setup = (usePatternsSetup); 65265 65266 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-pattern-setup/index.js 65267 /** 65268 * WordPress dependencies 65269 */ 65270 65271 65272 65273 65274 65275 65276 65277 /** 65278 * Internal dependencies 65279 */ 65280 65281 65282 65283 65284 65285 65286 const SetupContent = ({ 65287 viewMode, 65288 activeSlide, 65289 patterns, 65290 onBlockPatternSelect, 65291 showTitles 65292 }) => { 65293 const containerClass = 'block-editor-block-pattern-setup__container'; 65294 if (viewMode === VIEWMODES.carousel) { 65295 const slideClass = new Map([[activeSlide, 'active-slide'], [activeSlide - 1, 'previous-slide'], [activeSlide + 1, 'next-slide']]); 65296 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65297 className: "block-editor-block-pattern-setup__carousel", 65298 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65299 className: containerClass, 65300 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65301 className: "carousel-container", 65302 children: patterns.map((pattern, index) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockPatternSlide, { 65303 active: index === activeSlide, 65304 className: slideClass.get(index) || '', 65305 pattern: pattern 65306 }, pattern.name)) 65307 }) 65308 }) 65309 }); 65310 } 65311 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65312 className: "block-editor-block-pattern-setup__grid", 65313 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Composite, { 65314 role: "listbox", 65315 className: containerClass, 65316 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Patterns list'), 65317 children: patterns.map(pattern => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_pattern_setup_BlockPattern, { 65318 pattern: pattern, 65319 onSelect: onBlockPatternSelect, 65320 showTitles: showTitles 65321 }, pattern.name)) 65322 }) 65323 }); 65324 }; 65325 function block_pattern_setup_BlockPattern({ 65326 pattern, 65327 onSelect, 65328 showTitles 65329 }) { 65330 const baseClassName = 'block-editor-block-pattern-setup-list'; 65331 const { 65332 blocks, 65333 description, 65334 viewportWidth = 700 65335 } = pattern; 65336 const descriptionId = (0,external_wp_compose_namespaceObject.useInstanceId)(block_pattern_setup_BlockPattern, `$baseClassName}__item-description`); 65337 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65338 className: `$baseClassName}__list-item`, 65339 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Composite.Item, { 65340 render: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65341 "aria-describedby": description ? descriptionId : undefined, 65342 "aria-label": pattern.title, 65343 className: `$baseClassName}__item` 65344 }), 65345 id: `$baseClassName}__pattern__$pattern.name}`, 65346 role: "option", 65347 onClick: () => onSelect(blocks), 65348 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview, { 65349 blocks: blocks, 65350 viewportWidth: viewportWidth 65351 }), showTitles && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65352 className: `$baseClassName}__item-title`, 65353 children: pattern.title 65354 }), !!description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 65355 id: descriptionId, 65356 children: description 65357 })] 65358 }) 65359 }); 65360 } 65361 function BlockPatternSlide({ 65362 active, 65363 className, 65364 pattern, 65365 minHeight 65366 }) { 65367 const { 65368 blocks, 65369 title, 65370 description 65371 } = pattern; 65372 const descriptionId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockPatternSlide, 'block-editor-block-pattern-setup-list__item-description'); 65373 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 65374 "aria-hidden": !active, 65375 role: "img", 65376 className: `pattern-slide $className}`, 65377 "aria-label": title, 65378 "aria-describedby": description ? descriptionId : undefined, 65379 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_preview, { 65380 blocks: blocks, 65381 minHeight: minHeight 65382 }), !!description && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 65383 id: descriptionId, 65384 children: description 65385 })] 65386 }); 65387 } 65388 const BlockPatternSetup = ({ 65389 clientId, 65390 blockName, 65391 filterPatternsFn, 65392 onBlockPatternSelect, 65393 initialViewMode = VIEWMODES.carousel, 65394 showTitles = false 65395 }) => { 65396 const [viewMode, setViewMode] = (0,external_wp_element_namespaceObject.useState)(initialViewMode); 65397 const [activeSlide, setActiveSlide] = (0,external_wp_element_namespaceObject.useState)(0); 65398 const { 65399 replaceBlock 65400 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 65401 const patterns = use_patterns_setup(clientId, blockName, filterPatternsFn); 65402 if (!patterns?.length) { 65403 return null; 65404 } 65405 const onBlockPatternSelectDefault = blocks => { 65406 const clonedBlocks = blocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)); 65407 replaceBlock(clientId, clonedBlocks); 65408 }; 65409 const onPatternSelectCallback = onBlockPatternSelect || onBlockPatternSelectDefault; 65410 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 65411 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 65412 className: `block-editor-block-pattern-setup view-mode-$viewMode}`, 65413 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SetupContent, { 65414 viewMode: viewMode, 65415 activeSlide: activeSlide, 65416 patterns: patterns, 65417 onBlockPatternSelect: onPatternSelectCallback, 65418 showTitles: showTitles 65419 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(setup_toolbar, { 65420 viewMode: viewMode, 65421 setViewMode: setViewMode, 65422 activeSlide: activeSlide, 65423 totalSlides: patterns.length, 65424 handleNext: () => { 65425 setActiveSlide(active => Math.min(active + 1, patterns.length - 1)); 65426 }, 65427 handlePrevious: () => { 65428 setActiveSlide(active => Math.max(active - 1, 0)); 65429 }, 65430 onBlockPatternSelect: () => { 65431 onPatternSelectCallback(patterns[activeSlide].blocks); 65432 } 65433 })] 65434 }) 65435 }); 65436 }; 65437 /* harmony default export */ const block_pattern_setup = (BlockPatternSetup); 65438 65439 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-variation-transforms/index.js 65440 /** 65441 * WordPress dependencies 65442 */ 65443 65444 65445 65446 65447 65448 65449 65450 /** 65451 * Internal dependencies 65452 */ 65453 65454 65455 65456 65457 function VariationsButtons({ 65458 className, 65459 onSelectVariation, 65460 selectedValue, 65461 variations 65462 }) { 65463 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 65464 className: className, 65465 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 65466 as: "legend", 65467 children: (0,external_wp_i18n_namespaceObject.__)('Transform to variation') 65468 }), variations.map(variation => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65469 __next40pxDefaultSize: true, 65470 size: "compact", 65471 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 65472 icon: variation.icon, 65473 showColors: true 65474 }), 65475 isPressed: selectedValue === variation.name, 65476 label: selectedValue === variation.name ? variation.title : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Block or block variation name. */ 65477 (0,external_wp_i18n_namespaceObject.__)('Transform to %s'), variation.title), 65478 onClick: () => onSelectVariation(variation.name), 65479 "aria-label": variation.title, 65480 showTooltip: true 65481 }, variation.name))] 65482 }); 65483 } 65484 function VariationsDropdown({ 65485 className, 65486 onSelectVariation, 65487 selectedValue, 65488 variations 65489 }) { 65490 const selectOptions = variations.map(({ 65491 name, 65492 title, 65493 description 65494 }) => ({ 65495 value: name, 65496 label: title, 65497 info: description 65498 })); 65499 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 65500 className: className, 65501 label: (0,external_wp_i18n_namespaceObject.__)('Transform to variation'), 65502 text: (0,external_wp_i18n_namespaceObject.__)('Transform to variation'), 65503 popoverProps: { 65504 position: 'bottom center', 65505 className: `$className}__popover` 65506 }, 65507 icon: chevron_down, 65508 toggleProps: { 65509 iconPosition: 'right' 65510 }, 65511 children: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65512 className: `$className}__container`, 65513 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 65514 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItemsChoice, { 65515 choices: selectOptions, 65516 value: selectedValue, 65517 onSelect: onSelectVariation 65518 }) 65519 }) 65520 }) 65521 }); 65522 } 65523 function VariationsToggleGroupControl({ 65524 className, 65525 onSelectVariation, 65526 selectedValue, 65527 variations 65528 }) { 65529 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 65530 className: className, 65531 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 65532 label: (0,external_wp_i18n_namespaceObject.__)('Transform to variation'), 65533 value: selectedValue, 65534 hideLabelFromVision: true, 65535 onChange: onSelectVariation, 65536 __next40pxDefaultSize: true, 65537 __nextHasNoMarginBottom: true, 65538 children: variations.map(variation => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, { 65539 icon: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 65540 icon: variation.icon, 65541 showColors: true 65542 }), 65543 value: variation.name, 65544 label: selectedValue === variation.name ? variation.title : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Block or block variation name. */ 65545 (0,external_wp_i18n_namespaceObject.__)('Transform to %s'), variation.title) 65546 }, variation.name)) 65547 }) 65548 }); 65549 } 65550 function __experimentalBlockVariationTransforms({ 65551 blockClientId 65552 }) { 65553 const { 65554 updateBlockAttributes 65555 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 65556 const { 65557 activeBlockVariation, 65558 variations, 65559 isContentOnly 65560 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 65561 const { 65562 getActiveBlockVariation, 65563 getBlockVariations 65564 } = select(external_wp_blocks_namespaceObject.store); 65565 const { 65566 getBlockName, 65567 getBlockAttributes, 65568 getBlockEditingMode 65569 } = select(store); 65570 const name = blockClientId && getBlockName(blockClientId); 65571 const { 65572 hasContentRoleAttribute 65573 } = unlock(select(external_wp_blocks_namespaceObject.store)); 65574 const isContentBlock = hasContentRoleAttribute(name); 65575 return { 65576 activeBlockVariation: getActiveBlockVariation(name, getBlockAttributes(blockClientId)), 65577 variations: name && getBlockVariations(name, 'transform'), 65578 isContentOnly: getBlockEditingMode(blockClientId) === 'contentOnly' && !isContentBlock 65579 }; 65580 }, [blockClientId]); 65581 const selectedValue = activeBlockVariation?.name; 65582 65583 // Check if each variation has a unique icon. 65584 const hasUniqueIcons = (0,external_wp_element_namespaceObject.useMemo)(() => { 65585 const variationIcons = new Set(); 65586 if (!variations) { 65587 return false; 65588 } 65589 variations.forEach(variation => { 65590 if (variation.icon) { 65591 variationIcons.add(variation.icon?.src || variation.icon); 65592 } 65593 }); 65594 return variationIcons.size === variations.length; 65595 }, [variations]); 65596 const onSelectVariation = variationName => { 65597 updateBlockAttributes(blockClientId, { 65598 ...variations.find(({ 65599 name 65600 }) => name === variationName).attributes 65601 }); 65602 }; 65603 if (!variations?.length || isContentOnly) { 65604 return null; 65605 } 65606 const baseClass = 'block-editor-block-variation-transforms'; 65607 65608 // Show buttons if there are more than 5 variations because the ToggleGroupControl does not wrap 65609 const showButtons = variations.length > 5; 65610 const ButtonComponent = showButtons ? VariationsButtons : VariationsToggleGroupControl; 65611 const Component = hasUniqueIcons ? ButtonComponent : VariationsDropdown; 65612 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Component, { 65613 className: baseClass, 65614 onSelectVariation: onSelectVariation, 65615 selectedValue: selectedValue, 65616 variations: variations 65617 }); 65618 } 65619 /* harmony default export */ const block_variation_transforms = (__experimentalBlockVariationTransforms); 65620 65621 ;// ./node_modules/@wordpress/block-editor/build-module/components/color-palette/with-color-context.js 65622 /** 65623 * WordPress dependencies 65624 */ 65625 65626 65627 /** 65628 * Internal dependencies 65629 */ 65630 65631 65632 /* harmony default export */ const with_color_context = ((0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => { 65633 return props => { 65634 // Get the default colors, theme colors, and custom colors 65635 const [defaultColors, themeColors, customColors, enableCustomColors, enableDefaultColors] = use_settings_useSettings('color.palette.default', 'color.palette.theme', 'color.palette.custom', 'color.custom', 'color.defaultPalette'); 65636 const _colors = enableDefaultColors ? [...(themeColors || []), ...(defaultColors || []), ...(customColors || [])] : [...(themeColors || []), ...(customColors || [])]; 65637 const { 65638 colors = _colors, 65639 disableCustomColors = !enableCustomColors 65640 } = props; 65641 const hasColorsToChoose = colors && colors.length > 0 || !disableCustomColors; 65642 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WrappedComponent, { 65643 ...props, 65644 colors, 65645 disableCustomColors, 65646 hasColorsToChoose 65647 }); 65648 }; 65649 }, 'withColorContext')); 65650 65651 ;// ./node_modules/@wordpress/block-editor/build-module/components/color-palette/index.js 65652 /** 65653 * WordPress dependencies 65654 */ 65655 65656 65657 /** 65658 * Internal dependencies 65659 */ 65660 65661 /* harmony default export */ const color_palette = (with_color_context(external_wp_components_namespaceObject.ColorPalette)); 65662 65663 ;// ./node_modules/@wordpress/block-editor/build-module/components/color-palette/control.js 65664 /** 65665 * Internal dependencies 65666 */ 65667 65668 65669 function ColorPaletteControl({ 65670 onChange, 65671 value, 65672 ...otherProps 65673 }) { 65674 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(control, { 65675 ...otherProps, 65676 onColorChange: onChange, 65677 colorValue: value, 65678 gradients: [], 65679 disableCustomGradients: true 65680 }); 65681 } 65682 65683 ;// external ["wp","date"] 65684 const external_wp_date_namespaceObject = window["wp"]["date"]; 65685 ;// ./node_modules/@wordpress/block-editor/build-module/components/date-format-picker/index.js 65686 /** 65687 * WordPress dependencies 65688 */ 65689 65690 65691 65692 65693 65694 // So that we illustrate the different formats in the dropdown properly, show a date that is 65695 // somewhat recent, has a day greater than 12, and a month with more than three letters. 65696 65697 const exampleDate = new Date(); 65698 exampleDate.setDate(20); 65699 exampleDate.setMonth(exampleDate.getMonth() - 3); 65700 if (exampleDate.getMonth() === 4) { 65701 // May has three letters, so use March. 65702 exampleDate.setMonth(3); 65703 } 65704 65705 /** 65706 * The `DateFormatPicker` component renders controls that let the user choose a 65707 * _date format_. That is, how they want their dates to be formatted. 65708 * 65709 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/date-format-picker/README.md 65710 * 65711 * @param {Object} props 65712 * @param {string|null} props.format The selected date format. If `null`, _Default_ is selected. 65713 * @param {string} props.defaultFormat The date format that will be used if the user selects 'Default'. 65714 * @param {Function} props.onChange Called when a selection is made. If `null`, _Default_ is selected. 65715 */ 65716 function DateFormatPicker({ 65717 format, 65718 defaultFormat, 65719 onChange 65720 }) { 65721 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 65722 as: "fieldset", 65723 spacing: 4, 65724 className: "block-editor-date-format-picker", 65725 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 65726 as: "legend", 65727 children: (0,external_wp_i18n_namespaceObject.__)('Date format') 65728 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 65729 __nextHasNoMarginBottom: true, 65730 label: (0,external_wp_i18n_namespaceObject.__)('Default format'), 65731 help: `${(0,external_wp_i18n_namespaceObject.__)('Example:')} ${(0,external_wp_date_namespaceObject.dateI18n)(defaultFormat, exampleDate)}`, 65732 checked: !format, 65733 onChange: checked => onChange(checked ? null : defaultFormat) 65734 }), format && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(NonDefaultControls, { 65735 format: format, 65736 onChange: onChange 65737 })] 65738 }); 65739 } 65740 function NonDefaultControls({ 65741 format, 65742 onChange 65743 }) { 65744 var _suggestedOptions$fin; 65745 // Suggest a short format, medium format, long format, and a standardised 65746 // (YYYY-MM-DD) format. The short, medium, and long formats are localised as 65747 // different languages have different ways of writing these. For example, 'F 65748 // j, Y' (April 20, 2022) in American English (en_US) is 'j. F Y' (20. April 65749 // 2022) in German (de). The resultant array is de-duplicated as some 65750 // languages will use the same format string for short, medium, and long 65751 // formats. 65752 const suggestedFormats = [...new Set([/* translators: See https://www.php.net/manual/datetime.format.php */ 65753 'Y-m-d', /* translators: See https://www.php.net/manual/datetime.format.php */ 65754 (0,external_wp_i18n_namespaceObject._x)('n/j/Y', 'short date format'), /* translators: See https://www.php.net/manual/datetime.format.php */ 65755 (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 */ 65756 (0,external_wp_i18n_namespaceObject._x)('M j, Y', 'medium date format'), /* translators: See https://www.php.net/manual/datetime.format.php */ 65757 (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 */ 65758 (0,external_wp_i18n_namespaceObject._x)('F j, Y', 'long date format'), /* translators: See https://www.php.net/manual/datetime.format.php */ 65759 (0,external_wp_i18n_namespaceObject._x)('M j', 'short date format without the year')])]; 65760 const suggestedOptions = [...suggestedFormats.map((suggestedFormat, index) => ({ 65761 key: `suggested-$index}`, 65762 name: (0,external_wp_date_namespaceObject.dateI18n)(suggestedFormat, exampleDate), 65763 format: suggestedFormat 65764 })), { 65765 key: 'human-diff', 65766 name: (0,external_wp_date_namespaceObject.humanTimeDiff)(exampleDate), 65767 format: 'human-diff' 65768 }]; 65769 const customOption = { 65770 key: 'custom', 65771 name: (0,external_wp_i18n_namespaceObject.__)('Custom'), 65772 className: 'block-editor-date-format-picker__custom-format-select-control__custom-option', 65773 hint: (0,external_wp_i18n_namespaceObject.__)('Enter your own date format') 65774 }; 65775 const [isCustom, setIsCustom] = (0,external_wp_element_namespaceObject.useState)(() => !!format && !suggestedOptions.some(option => option.format === format)); 65776 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 65777 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CustomSelectControl, { 65778 __next40pxDefaultSize: true, 65779 label: (0,external_wp_i18n_namespaceObject.__)('Choose a format'), 65780 options: [...suggestedOptions, customOption], 65781 value: isCustom ? customOption : (_suggestedOptions$fin = suggestedOptions.find(option => option.format === format)) !== null && _suggestedOptions$fin !== void 0 ? _suggestedOptions$fin : customOption, 65782 onChange: ({ 65783 selectedItem 65784 }) => { 65785 if (selectedItem === customOption) { 65786 setIsCustom(true); 65787 } else { 65788 setIsCustom(false); 65789 onChange(selectedItem.format); 65790 } 65791 } 65792 }), isCustom && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 65793 __next40pxDefaultSize: true, 65794 __nextHasNoMarginBottom: true, 65795 label: (0,external_wp_i18n_namespaceObject.__)('Custom format'), 65796 hideLabelFromVision: true, 65797 help: (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Enter a date or time <Link>format string</Link>.'), { 65798 Link: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ExternalLink, { 65799 href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/documentation/article/customize-date-and-time-format/') 65800 }) 65801 }), 65802 value: format, 65803 onChange: value => onChange(value) 65804 })] 65805 }); 65806 } 65807 65808 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/dropdown.js 65809 /** 65810 * External dependencies 65811 */ 65812 65813 65814 /** 65815 * WordPress dependencies 65816 */ 65817 65818 65819 65820 65821 /** 65822 * Internal dependencies 65823 */ 65824 65825 65826 /** 65827 * Internal dependencies 65828 */ 65829 65830 65831 // When the `ColorGradientSettingsDropdown` controls are being rendered to a 65832 // `ToolsPanel` they must be wrapped in a `ToolsPanelItem`. 65833 65834 const WithToolsPanelItem = ({ 65835 setting, 65836 children, 65837 panelId, 65838 ...props 65839 }) => { 65840 const clearValue = () => { 65841 if (setting.colorValue) { 65842 setting.onColorChange(); 65843 } else if (setting.gradientValue) { 65844 setting.onGradientChange(); 65845 } 65846 }; 65847 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 65848 hasValue: () => { 65849 return !!setting.colorValue || !!setting.gradientValue; 65850 }, 65851 label: setting.label, 65852 onDeselect: clearValue, 65853 isShownByDefault: setting.isShownByDefault !== undefined ? setting.isShownByDefault : true, 65854 ...props, 65855 className: "block-editor-tools-panel-color-gradient-settings__item", 65856 panelId: panelId 65857 // Pass resetAllFilter if supplied due to rendering via SlotFill 65858 // into parent ToolsPanel. 65859 , 65860 resetAllFilter: setting.resetAllFilter, 65861 children: children 65862 }); 65863 }; 65864 const dropdown_LabeledColorIndicator = ({ 65865 colorValue, 65866 label 65867 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 65868 justify: "flex-start", 65869 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ColorIndicator, { 65870 className: "block-editor-panel-color-gradient-settings__color-indicator", 65871 colorValue: colorValue 65872 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 65873 className: "block-editor-panel-color-gradient-settings__color-name", 65874 title: label, 65875 children: label 65876 })] 65877 }); 65878 65879 // Renders a color dropdown's toggle as an `Item` if it is within an `ItemGroup` 65880 // or as a `Button` if it isn't e.g. the controls are being rendered in 65881 // a `ToolsPanel`. 65882 const dropdown_renderToggle = settings => ({ 65883 onToggle, 65884 isOpen 65885 }) => { 65886 const { 65887 clearable, 65888 colorValue, 65889 gradientValue, 65890 onColorChange, 65891 onGradientChange, 65892 label 65893 } = settings; 65894 const colorButtonRef = (0,external_wp_element_namespaceObject.useRef)(undefined); 65895 const toggleProps = { 65896 onClick: onToggle, 65897 className: dist_clsx('block-editor-panel-color-gradient-settings__dropdown', { 65898 'is-open': isOpen 65899 }), 65900 'aria-expanded': isOpen, 65901 ref: colorButtonRef 65902 }; 65903 const clearValue = () => { 65904 if (colorValue) { 65905 onColorChange(); 65906 } else if (gradientValue) { 65907 onGradientChange(); 65908 } 65909 }; 65910 const value = colorValue !== null && colorValue !== void 0 ? colorValue : gradientValue; 65911 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 65912 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65913 __next40pxDefaultSize: true, 65914 ...toggleProps, 65915 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(dropdown_LabeledColorIndicator, { 65916 colorValue: value, 65917 label: label 65918 }) 65919 }), clearable && value && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 65920 __next40pxDefaultSize: true, 65921 label: (0,external_wp_i18n_namespaceObject.__)('Reset'), 65922 className: "block-editor-panel-color-gradient-settings__reset", 65923 size: "small", 65924 icon: library_reset, 65925 onClick: () => { 65926 clearValue(); 65927 if (isOpen) { 65928 onToggle(); 65929 } 65930 // Return focus to parent button 65931 colorButtonRef.current?.focus(); 65932 } 65933 })] 65934 }); 65935 }; 65936 65937 // Renders a collection of color controls as dropdowns. Depending upon the 65938 // context in which these dropdowns are being rendered, they may be wrapped 65939 // in an `ItemGroup` with each dropdown's toggle as an `Item`, or alternatively, 65940 // the may be individually wrapped in a `ToolsPanelItem` with the toggle as 65941 // a regular `Button`. 65942 // 65943 // For more context see: https://github.com/WordPress/gutenberg/pull/40084 65944 function ColorGradientSettingsDropdown({ 65945 colors, 65946 disableCustomColors, 65947 disableCustomGradients, 65948 enableAlpha, 65949 gradients, 65950 settings, 65951 __experimentalIsRenderedInSidebar, 65952 ...props 65953 }) { 65954 let popoverProps; 65955 if (__experimentalIsRenderedInSidebar) { 65956 popoverProps = { 65957 placement: 'left-start', 65958 offset: 36, 65959 shift: true 65960 }; 65961 } 65962 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 65963 children: settings.map((setting, index) => { 65964 const controlProps = { 65965 clearable: false, 65966 colorValue: setting.colorValue, 65967 colors, 65968 disableCustomColors, 65969 disableCustomGradients, 65970 enableAlpha, 65971 gradientValue: setting.gradientValue, 65972 gradients, 65973 label: setting.label, 65974 onColorChange: setting.onColorChange, 65975 onGradientChange: setting.onGradientChange, 65976 showTitle: false, 65977 __experimentalIsRenderedInSidebar, 65978 ...setting 65979 }; 65980 const toggleSettings = { 65981 clearable: setting.clearable, 65982 label: setting.label, 65983 colorValue: setting.colorValue, 65984 gradientValue: setting.gradientValue, 65985 onColorChange: setting.onColorChange, 65986 onGradientChange: setting.onGradientChange 65987 }; 65988 return setting && 65989 /*#__PURE__*/ 65990 // If not in an `ItemGroup` wrap the dropdown in a 65991 // `ToolsPanelItem` 65992 (0,external_ReactJSXRuntime_namespaceObject.jsx)(WithToolsPanelItem, { 65993 setting: setting, 65994 ...props, 65995 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 65996 popoverProps: popoverProps, 65997 className: "block-editor-tools-panel-color-gradient-settings__dropdown", 65998 renderToggle: dropdown_renderToggle(toggleSettings), 65999 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 66000 paddingSize: "none", 66001 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 66002 className: "block-editor-panel-color-gradient-settings__dropdown-content", 66003 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(control, { 66004 ...controlProps 66005 }) 66006 }) 66007 }) 66008 }) 66009 }, index); 66010 }) 66011 }); 66012 } 66013 66014 ;// ./node_modules/@wordpress/block-editor/build-module/components/colors-gradients/panel-color-gradient-settings.js 66015 /** 66016 * External dependencies 66017 */ 66018 66019 66020 /** 66021 * WordPress dependencies 66022 */ 66023 66024 66025 66026 66027 /** 66028 * Internal dependencies 66029 */ 66030 66031 66032 66033 const panel_color_gradient_settings_colorsAndGradientKeys = ['colors', 'disableCustomColors', 'gradients', 'disableCustomGradients']; 66034 const PanelColorGradientSettingsInner = ({ 66035 className, 66036 colors, 66037 gradients, 66038 disableCustomColors, 66039 disableCustomGradients, 66040 children, 66041 settings, 66042 title, 66043 showTitle = true, 66044 __experimentalIsRenderedInSidebar, 66045 enableAlpha 66046 }) => { 66047 const panelId = (0,external_wp_compose_namespaceObject.useInstanceId)(PanelColorGradientSettingsInner); 66048 const { 66049 batch 66050 } = (0,external_wp_data_namespaceObject.useRegistry)(); 66051 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))) { 66052 return null; 66053 } 66054 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 66055 className: dist_clsx('block-editor-panel-color-gradient-settings', className), 66056 label: showTitle ? title : undefined, 66057 resetAll: () => { 66058 batch(() => { 66059 settings.forEach(({ 66060 colorValue, 66061 gradientValue, 66062 onColorChange, 66063 onGradientChange 66064 }) => { 66065 if (colorValue) { 66066 onColorChange(); 66067 } else if (gradientValue) { 66068 onGradientChange(); 66069 } 66070 }); 66071 }); 66072 }, 66073 panelId: panelId, 66074 __experimentalFirstVisibleItemClass: "first", 66075 __experimentalLastVisibleItemClass: "last", 66076 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ColorGradientSettingsDropdown, { 66077 settings: settings, 66078 panelId: panelId, 66079 colors, 66080 gradients, 66081 disableCustomColors, 66082 disableCustomGradients, 66083 __experimentalIsRenderedInSidebar, 66084 enableAlpha 66085 }), !!children && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 66086 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalSpacer, { 66087 marginY: 4 66088 }), " ", children] 66089 })] 66090 }); 66091 }; 66092 const PanelColorGradientSettingsSelect = props => { 66093 const colorGradientSettings = useMultipleOriginColorsAndGradients(); 66094 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PanelColorGradientSettingsInner, { 66095 ...colorGradientSettings, 66096 ...props 66097 }); 66098 }; 66099 const PanelColorGradientSettings = props => { 66100 if (panel_color_gradient_settings_colorsAndGradientKeys.every(key => props.hasOwnProperty(key))) { 66101 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PanelColorGradientSettingsInner, { 66102 ...props 66103 }); 66104 } 66105 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PanelColorGradientSettingsSelect, { 66106 ...props 66107 }); 66108 }; 66109 /* harmony default export */ const panel_color_gradient_settings = (PanelColorGradientSettings); 66110 66111 ;// ./node_modules/@wordpress/icons/build-module/library/aspect-ratio.js 66112 /** 66113 * WordPress dependencies 66114 */ 66115 66116 66117 const aspectRatio = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 66118 xmlns: "http://www.w3.org/2000/svg", 66119 viewBox: "0 0 24 24", 66120 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 66121 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" 66122 }) 66123 }); 66124 /* harmony default export */ const aspect_ratio = (aspectRatio); 66125 66126 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/constants.js 66127 const MIN_ZOOM = 100; 66128 const MAX_ZOOM = 300; 66129 const constants_POPOVER_PROPS = { 66130 placement: 'bottom-start' 66131 }; 66132 66133 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/use-save-image.js 66134 /** 66135 * WordPress dependencies 66136 */ 66137 // Disable Reason: Needs to be refactored. 66138 // eslint-disable-next-line no-restricted-imports 66139 66140 66141 66142 66143 66144 66145 const messages = { 66146 crop: (0,external_wp_i18n_namespaceObject.__)('Image cropped.'), 66147 rotate: (0,external_wp_i18n_namespaceObject.__)('Image rotated.'), 66148 cropAndRotate: (0,external_wp_i18n_namespaceObject.__)('Image cropped and rotated.') 66149 }; 66150 function useSaveImage({ 66151 crop, 66152 rotation, 66153 url, 66154 id, 66155 onSaveImage, 66156 onFinishEditing 66157 }) { 66158 const { 66159 createErrorNotice, 66160 createSuccessNotice 66161 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store); 66162 const [isInProgress, setIsInProgress] = (0,external_wp_element_namespaceObject.useState)(false); 66163 const cancel = (0,external_wp_element_namespaceObject.useCallback)(() => { 66164 setIsInProgress(false); 66165 onFinishEditing(); 66166 }, [onFinishEditing]); 66167 const apply = (0,external_wp_element_namespaceObject.useCallback)(() => { 66168 setIsInProgress(true); 66169 const modifiers = []; 66170 if (rotation > 0) { 66171 modifiers.push({ 66172 type: 'rotate', 66173 args: { 66174 angle: rotation 66175 } 66176 }); 66177 } 66178 66179 // The crop script may return some very small, sub-pixel values when the image was not cropped. 66180 // Crop only when the new size has changed by more than 0.1%. 66181 if (crop.width < 99.9 || crop.height < 99.9) { 66182 modifiers.push({ 66183 type: 'crop', 66184 args: { 66185 left: crop.x, 66186 top: crop.y, 66187 width: crop.width, 66188 height: crop.height 66189 } 66190 }); 66191 } 66192 if (modifiers.length === 0) { 66193 // No changes to apply. 66194 setIsInProgress(false); 66195 onFinishEditing(); 66196 return; 66197 } 66198 const modifierType = modifiers.length === 1 ? modifiers[0].type : 'cropAndRotate'; 66199 external_wp_apiFetch_default()({ 66200 path: `/wp/v2/media/$id}/edit`, 66201 method: 'POST', 66202 data: { 66203 src: url, 66204 modifiers 66205 } 66206 }).then(response => { 66207 onSaveImage({ 66208 id: response.id, 66209 url: response.source_url 66210 }); 66211 createSuccessNotice(messages[modifierType], { 66212 type: 'snackbar', 66213 actions: [{ 66214 label: (0,external_wp_i18n_namespaceObject.__)('Undo'), 66215 onClick: () => { 66216 onSaveImage({ 66217 id, 66218 url 66219 }); 66220 } 66221 }] 66222 }); 66223 }).catch(error => { 66224 createErrorNotice((0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Error message. */ 66225 (0,external_wp_i18n_namespaceObject.__)('Could not edit image. %s'), (0,external_wp_dom_namespaceObject.__unstableStripHTML)(error.message)), { 66226 id: 'image-editing-error', 66227 type: 'snackbar' 66228 }); 66229 }).finally(() => { 66230 setIsInProgress(false); 66231 onFinishEditing(); 66232 }); 66233 }, [crop, rotation, id, url, onSaveImage, createErrorNotice, createSuccessNotice, onFinishEditing]); 66234 return (0,external_wp_element_namespaceObject.useMemo)(() => ({ 66235 isInProgress, 66236 apply, 66237 cancel 66238 }), [isInProgress, apply, cancel]); 66239 } 66240 66241 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/use-transform-image.js 66242 /* wp:polyfill */ 66243 /** 66244 * WordPress dependencies 66245 */ 66246 66247 66248 function useTransformImage({ 66249 url, 66250 naturalWidth, 66251 naturalHeight 66252 }) { 66253 const [editedUrl, setEditedUrl] = (0,external_wp_element_namespaceObject.useState)(); 66254 const [crop, setCrop] = (0,external_wp_element_namespaceObject.useState)(); 66255 const [position, setPosition] = (0,external_wp_element_namespaceObject.useState)({ 66256 x: 0, 66257 y: 0 66258 }); 66259 const [zoom, setZoom] = (0,external_wp_element_namespaceObject.useState)(100); 66260 const [rotation, setRotation] = (0,external_wp_element_namespaceObject.useState)(0); 66261 const defaultAspect = naturalWidth / naturalHeight; 66262 const [aspect, setAspect] = (0,external_wp_element_namespaceObject.useState)(defaultAspect); 66263 const rotateClockwise = (0,external_wp_element_namespaceObject.useCallback)(() => { 66264 const angle = (rotation + 90) % 360; 66265 let naturalAspectRatio = defaultAspect; 66266 if (rotation % 180 === 90) { 66267 naturalAspectRatio = 1 / defaultAspect; 66268 } 66269 if (angle === 0) { 66270 setEditedUrl(); 66271 setRotation(angle); 66272 setAspect(defaultAspect); 66273 setPosition(prevPosition => ({ 66274 x: -(prevPosition.y * naturalAspectRatio), 66275 y: prevPosition.x * naturalAspectRatio 66276 })); 66277 return; 66278 } 66279 function editImage(event) { 66280 const canvas = document.createElement('canvas'); 66281 let translateX = 0; 66282 let translateY = 0; 66283 if (angle % 180) { 66284 canvas.width = event.target.height; 66285 canvas.height = event.target.width; 66286 } else { 66287 canvas.width = event.target.width; 66288 canvas.height = event.target.height; 66289 } 66290 if (angle === 90 || angle === 180) { 66291 translateX = canvas.width; 66292 } 66293 if (angle === 270 || angle === 180) { 66294 translateY = canvas.height; 66295 } 66296 const context = canvas.getContext('2d'); 66297 context.translate(translateX, translateY); 66298 context.rotate(angle * Math.PI / 180); 66299 context.drawImage(event.target, 0, 0); 66300 canvas.toBlob(blob => { 66301 setEditedUrl(URL.createObjectURL(blob)); 66302 setRotation(angle); 66303 setAspect(canvas.width / canvas.height); 66304 setPosition(prevPosition => ({ 66305 x: -(prevPosition.y * naturalAspectRatio), 66306 y: prevPosition.x * naturalAspectRatio 66307 })); 66308 }); 66309 } 66310 const el = new window.Image(); 66311 el.src = url; 66312 el.onload = editImage; 66313 const imgCrossOrigin = (0,external_wp_hooks_namespaceObject.applyFilters)('media.crossOrigin', undefined, url); 66314 if (typeof imgCrossOrigin === 'string') { 66315 el.crossOrigin = imgCrossOrigin; 66316 } 66317 }, [rotation, defaultAspect, url]); 66318 return (0,external_wp_element_namespaceObject.useMemo)(() => ({ 66319 editedUrl, 66320 setEditedUrl, 66321 crop, 66322 setCrop, 66323 position, 66324 setPosition, 66325 zoom, 66326 setZoom, 66327 rotation, 66328 setRotation, 66329 rotateClockwise, 66330 aspect, 66331 setAspect, 66332 defaultAspect 66333 }), [editedUrl, crop, position, zoom, rotation, rotateClockwise, aspect, defaultAspect]); 66334 } 66335 66336 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/context.js 66337 /** 66338 * WordPress dependencies 66339 */ 66340 66341 66342 /** 66343 * Internal dependencies 66344 */ 66345 66346 66347 66348 const ImageEditingContext = (0,external_wp_element_namespaceObject.createContext)({}); 66349 const useImageEditingContext = () => (0,external_wp_element_namespaceObject.useContext)(ImageEditingContext); 66350 function ImageEditingProvider({ 66351 id, 66352 url, 66353 naturalWidth, 66354 naturalHeight, 66355 onFinishEditing, 66356 onSaveImage, 66357 children 66358 }) { 66359 const transformImage = useTransformImage({ 66360 url, 66361 naturalWidth, 66362 naturalHeight 66363 }); 66364 const saveImage = useSaveImage({ 66365 id, 66366 url, 66367 onSaveImage, 66368 onFinishEditing, 66369 ...transformImage 66370 }); 66371 const providerValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({ 66372 ...transformImage, 66373 ...saveImage 66374 }), [transformImage, saveImage]); 66375 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ImageEditingContext.Provider, { 66376 value: providerValue, 66377 children: children 66378 }); 66379 } 66380 66381 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/aspect-ratio-dropdown.js 66382 /** 66383 * WordPress dependencies 66384 */ 66385 66386 66387 66388 66389 /** 66390 * Internal dependencies 66391 */ 66392 66393 66394 66395 66396 function AspectRatioGroup({ 66397 aspectRatios, 66398 isDisabled, 66399 label, 66400 onClick, 66401 value 66402 }) { 66403 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuGroup, { 66404 label: label, 66405 children: aspectRatios.map(({ 66406 name, 66407 slug, 66408 ratio 66409 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 66410 disabled: isDisabled, 66411 onClick: () => { 66412 onClick(ratio); 66413 }, 66414 role: "menuitemradio", 66415 isSelected: ratio === value, 66416 icon: ratio === value ? library_check : undefined, 66417 children: name 66418 }, slug)) 66419 }); 66420 } 66421 function ratioToNumber(str) { 66422 // TODO: support two-value aspect ratio? 66423 // https://css-tricks.com/almanac/properties/a/aspect-ratio/#aa-it-can-take-two-values 66424 const [a, b, ...rest] = str.split('/').map(Number); 66425 if (a <= 0 || b <= 0 || Number.isNaN(a) || Number.isNaN(b) || rest.length) { 66426 return NaN; 66427 } 66428 return b ? a / b : a; 66429 } 66430 function presetRatioAsNumber({ 66431 ratio, 66432 ...rest 66433 }) { 66434 return { 66435 ratio: ratioToNumber(ratio), 66436 ...rest 66437 }; 66438 } 66439 function AspectRatioDropdown({ 66440 toggleProps 66441 }) { 66442 const { 66443 isInProgress, 66444 aspect, 66445 setAspect, 66446 defaultAspect 66447 } = useImageEditingContext(); 66448 const [defaultRatios, themeRatios, showDefaultRatios] = use_settings_useSettings('dimensions.aspectRatios.default', 'dimensions.aspectRatios.theme', 'dimensions.defaultAspectRatios'); 66449 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 66450 icon: aspect_ratio, 66451 label: (0,external_wp_i18n_namespaceObject.__)('Aspect Ratio'), 66452 popoverProps: constants_POPOVER_PROPS, 66453 toggleProps: toggleProps, 66454 children: ({ 66455 onClose 66456 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 66457 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioGroup, { 66458 isDisabled: isInProgress, 66459 onClick: newAspect => { 66460 setAspect(newAspect); 66461 onClose(); 66462 }, 66463 value: aspect, 66464 aspectRatios: [ 66465 // All ratios should be mirrored in AspectRatioTool in @wordpress/block-editor. 66466 { 66467 slug: 'original', 66468 name: (0,external_wp_i18n_namespaceObject.__)('Original'), 66469 ratio: defaultAspect 66470 }, ...(showDefaultRatios ? defaultRatios.map(presetRatioAsNumber).filter(({ 66471 ratio 66472 }) => ratio === 1) : [])] 66473 }), themeRatios?.length > 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioGroup, { 66474 label: (0,external_wp_i18n_namespaceObject.__)('Theme'), 66475 isDisabled: isInProgress, 66476 onClick: newAspect => { 66477 setAspect(newAspect); 66478 onClose(); 66479 }, 66480 value: aspect, 66481 aspectRatios: themeRatios 66482 }), showDefaultRatios && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioGroup, { 66483 label: (0,external_wp_i18n_namespaceObject.__)('Landscape'), 66484 isDisabled: isInProgress, 66485 onClick: newAspect => { 66486 setAspect(newAspect); 66487 onClose(); 66488 }, 66489 value: aspect, 66490 aspectRatios: defaultRatios.map(presetRatioAsNumber).filter(({ 66491 ratio 66492 }) => ratio > 1) 66493 }), showDefaultRatios && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioGroup, { 66494 label: (0,external_wp_i18n_namespaceObject.__)('Portrait'), 66495 isDisabled: isInProgress, 66496 onClick: newAspect => { 66497 setAspect(newAspect); 66498 onClose(); 66499 }, 66500 value: aspect, 66501 aspectRatios: defaultRatios.map(presetRatioAsNumber).filter(({ 66502 ratio 66503 }) => ratio < 1) 66504 })] 66505 }) 66506 }); 66507 } 66508 66509 ;// ./node_modules/tslib/tslib.es6.mjs 66510 /****************************************************************************** 66511 Copyright (c) Microsoft Corporation. 66512 66513 Permission to use, copy, modify, and/or distribute this software for any 66514 purpose with or without fee is hereby granted. 66515 66516 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 66517 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 66518 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 66519 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 66520 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 66521 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 66522 PERFORMANCE OF THIS SOFTWARE. 66523 ***************************************************************************** */ 66524 /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ 66525 66526 var extendStatics = function(d, b) { 66527 extendStatics = Object.setPrototypeOf || 66528 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 66529 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 66530 return extendStatics(d, b); 66531 }; 66532 66533 function __extends(d, b) { 66534 if (typeof b !== "function" && b !== null) 66535 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 66536 extendStatics(d, b); 66537 function __() { this.constructor = d; } 66538 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 66539 } 66540 66541 var __assign = function() { 66542 __assign = Object.assign || function __assign(t) { 66543 for (var s, i = 1, n = arguments.length; i < n; i++) { 66544 s = arguments[i]; 66545 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 66546 } 66547 return t; 66548 } 66549 return __assign.apply(this, arguments); 66550 } 66551 66552 function __rest(s, e) { 66553 var t = {}; 66554 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 66555 t[p] = s[p]; 66556 if (s != null && typeof Object.getOwnPropertySymbols === "function") 66557 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 66558 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 66559 t[p[i]] = s[p[i]]; 66560 } 66561 return t; 66562 } 66563 66564 function __decorate(decorators, target, key, desc) { 66565 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 66566 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 66567 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; 66568 return c > 3 && r && Object.defineProperty(target, key, r), r; 66569 } 66570 66571 function __param(paramIndex, decorator) { 66572 return function (target, key) { decorator(target, key, paramIndex); } 66573 } 66574 66575 function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 66576 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 66577 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 66578 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 66579 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 66580 var _, done = false; 66581 for (var i = decorators.length - 1; i >= 0; i--) { 66582 var context = {}; 66583 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 66584 for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 66585 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 66586 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 66587 if (kind === "accessor") { 66588 if (result === void 0) continue; 66589 if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 66590 if (_ = accept(result.get)) descriptor.get = _; 66591 if (_ = accept(result.set)) descriptor.set = _; 66592 if (_ = accept(result.init)) initializers.unshift(_); 66593 } 66594 else if (_ = accept(result)) { 66595 if (kind === "field") initializers.unshift(_); 66596 else descriptor[key] = _; 66597 } 66598 } 66599 if (target) Object.defineProperty(target, contextIn.name, descriptor); 66600 done = true; 66601 }; 66602 66603 function __runInitializers(thisArg, initializers, value) { 66604 var useValue = arguments.length > 2; 66605 for (var i = 0; i < initializers.length; i++) { 66606 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 66607 } 66608 return useValue ? value : void 0; 66609 }; 66610 66611 function __propKey(x) { 66612 return typeof x === "symbol" ? x : "".concat(x); 66613 }; 66614 66615 function __setFunctionName(f, name, prefix) { 66616 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; 66617 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); 66618 }; 66619 66620 function __metadata(metadataKey, metadataValue) { 66621 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 66622 } 66623 66624 function __awaiter(thisArg, _arguments, P, generator) { 66625 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 66626 return new (P || (P = Promise))(function (resolve, reject) { 66627 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 66628 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 66629 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 66630 step((generator = generator.apply(thisArg, _arguments || [])).next()); 66631 }); 66632 } 66633 66634 function __generator(thisArg, body) { 66635 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); 66636 return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 66637 function verb(n) { return function (v) { return step([n, v]); }; } 66638 function step(op) { 66639 if (f) throw new TypeError("Generator is already executing."); 66640 while (g && (g = 0, op[0] && (_ = 0)), _) try { 66641 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; 66642 if (y = 0, t) op = [op[0] & 2, t.value]; 66643 switch (op[0]) { 66644 case 0: case 1: t = op; break; 66645 case 4: _.label++; return { value: op[1], done: false }; 66646 case 5: _.label++; y = op[1]; op = [0]; continue; 66647 case 7: op = _.ops.pop(); _.trys.pop(); continue; 66648 default: 66649 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 66650 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 66651 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 66652 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 66653 if (t[2]) _.ops.pop(); 66654 _.trys.pop(); continue; 66655 } 66656 op = body.call(thisArg, _); 66657 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 66658 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 66659 } 66660 } 66661 66662 var __createBinding = Object.create ? (function(o, m, k, k2) { 66663 if (k2 === undefined) k2 = k; 66664 var desc = Object.getOwnPropertyDescriptor(m, k); 66665 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 66666 desc = { enumerable: true, get: function() { return m[k]; } }; 66667 } 66668 Object.defineProperty(o, k2, desc); 66669 }) : (function(o, m, k, k2) { 66670 if (k2 === undefined) k2 = k; 66671 o[k2] = m[k]; 66672 }); 66673 66674 function __exportStar(m, o) { 66675 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 66676 } 66677 66678 function __values(o) { 66679 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 66680 if (m) return m.call(o); 66681 if (o && typeof o.length === "number") return { 66682 next: function () { 66683 if (o && i >= o.length) o = void 0; 66684 return { value: o && o[i++], done: !o }; 66685 } 66686 }; 66687 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 66688 } 66689 66690 function __read(o, n) { 66691 var m = typeof Symbol === "function" && o[Symbol.iterator]; 66692 if (!m) return o; 66693 var i = m.call(o), r, ar = [], e; 66694 try { 66695 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 66696 } 66697 catch (error) { e = { error: error }; } 66698 finally { 66699 try { 66700 if (r && !r.done && (m = i["return"])) m.call(i); 66701 } 66702 finally { if (e) throw e.error; } 66703 } 66704 return ar; 66705 } 66706 66707 /** @deprecated */ 66708 function __spread() { 66709 for (var ar = [], i = 0; i < arguments.length; i++) 66710 ar = ar.concat(__read(arguments[i])); 66711 return ar; 66712 } 66713 66714 /** @deprecated */ 66715 function __spreadArrays() { 66716 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 66717 for (var r = Array(s), k = 0, i = 0; i < il; i++) 66718 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 66719 r[k] = a[j]; 66720 return r; 66721 } 66722 66723 function __spreadArray(to, from, pack) { 66724 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 66725 if (ar || !(i in from)) { 66726 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 66727 ar[i] = from[i]; 66728 } 66729 } 66730 return to.concat(ar || Array.prototype.slice.call(from)); 66731 } 66732 66733 function __await(v) { 66734 return this instanceof __await ? (this.v = v, this) : new __await(v); 66735 } 66736 66737 function __asyncGenerator(thisArg, _arguments, generator) { 66738 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 66739 var g = generator.apply(thisArg, _arguments || []), i, q = []; 66740 return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; 66741 function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } 66742 function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } 66743 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 66744 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 66745 function fulfill(value) { resume("next", value); } 66746 function reject(value) { resume("throw", value); } 66747 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 66748 } 66749 66750 function __asyncDelegator(o) { 66751 var i, p; 66752 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 66753 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } 66754 } 66755 66756 function __asyncValues(o) { 66757 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 66758 var m = o[Symbol.asyncIterator], i; 66759 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); 66760 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); }); }; } 66761 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 66762 } 66763 66764 function __makeTemplateObject(cooked, raw) { 66765 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 66766 return cooked; 66767 }; 66768 66769 var __setModuleDefault = Object.create ? (function(o, v) { 66770 Object.defineProperty(o, "default", { enumerable: true, value: v }); 66771 }) : function(o, v) { 66772 o["default"] = v; 66773 }; 66774 66775 var ownKeys = function(o) { 66776 ownKeys = Object.getOwnPropertyNames || function (o) { 66777 var ar = []; 66778 for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; 66779 return ar; 66780 }; 66781 return ownKeys(o); 66782 }; 66783 66784 function __importStar(mod) { 66785 if (mod && mod.__esModule) return mod; 66786 var result = {}; 66787 if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); 66788 __setModuleDefault(result, mod); 66789 return result; 66790 } 66791 66792 function __importDefault(mod) { 66793 return (mod && mod.__esModule) ? mod : { default: mod }; 66794 } 66795 66796 function __classPrivateFieldGet(receiver, state, kind, f) { 66797 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 66798 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); 66799 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 66800 } 66801 66802 function __classPrivateFieldSet(receiver, state, value, kind, f) { 66803 if (kind === "m") throw new TypeError("Private method is not writable"); 66804 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 66805 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); 66806 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 66807 } 66808 66809 function __classPrivateFieldIn(state, receiver) { 66810 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); 66811 return typeof state === "function" ? receiver === state : state.has(receiver); 66812 } 66813 66814 function __addDisposableResource(env, value, async) { 66815 if (value !== null && value !== void 0) { 66816 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 66817 var dispose, inner; 66818 if (async) { 66819 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 66820 dispose = value[Symbol.asyncDispose]; 66821 } 66822 if (dispose === void 0) { 66823 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 66824 dispose = value[Symbol.dispose]; 66825 if (async) inner = dispose; 66826 } 66827 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 66828 if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; 66829 env.stack.push({ value: value, dispose: dispose, async: async }); 66830 } 66831 else if (async) { 66832 env.stack.push({ async: true }); 66833 } 66834 return value; 66835 } 66836 66837 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 66838 var e = new Error(message); 66839 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 66840 }; 66841 66842 function __disposeResources(env) { 66843 function fail(e) { 66844 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 66845 env.hasError = true; 66846 } 66847 var r, s = 0; 66848 function next() { 66849 while (r = env.stack.pop()) { 66850 try { 66851 if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); 66852 if (r.dispose) { 66853 var result = r.dispose.call(r.value); 66854 if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 66855 } 66856 else s |= 1; 66857 } 66858 catch (e) { 66859 fail(e); 66860 } 66861 } 66862 if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); 66863 if (env.hasError) throw env.error; 66864 } 66865 return next(); 66866 } 66867 66868 function __rewriteRelativeImportExtension(path, preserveJsx) { 66869 if (typeof path === "string" && /^\.\.?\//.test(path)) { 66870 return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { 66871 return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); 66872 }); 66873 } 66874 return path; 66875 } 66876 66877 /* harmony default export */ const tslib_es6 = ({ 66878 __extends, 66879 __assign, 66880 __rest, 66881 __decorate, 66882 __param, 66883 __esDecorate, 66884 __runInitializers, 66885 __propKey, 66886 __setFunctionName, 66887 __metadata, 66888 __awaiter, 66889 __generator, 66890 __createBinding, 66891 __exportStar, 66892 __values, 66893 __read, 66894 __spread, 66895 __spreadArrays, 66896 __spreadArray, 66897 __await, 66898 __asyncGenerator, 66899 __asyncDelegator, 66900 __asyncValues, 66901 __makeTemplateObject, 66902 __importStar, 66903 __importDefault, 66904 __classPrivateFieldGet, 66905 __classPrivateFieldSet, 66906 __classPrivateFieldIn, 66907 __addDisposableResource, 66908 __disposeResources, 66909 __rewriteRelativeImportExtension, 66910 }); 66911 66912 // EXTERNAL MODULE: ./node_modules/normalize-wheel/index.js 66913 var normalize_wheel = __webpack_require__(7520); 66914 var normalize_wheel_default = /*#__PURE__*/__webpack_require__.n(normalize_wheel); 66915 ;// ./node_modules/react-easy-crop/index.module.js 66916 66917 66918 66919 66920 /** 66921 * Compute the dimension of the crop area based on media size, 66922 * aspect ratio and optionally rotation 66923 */ 66924 function getCropSize(mediaWidth, mediaHeight, containerWidth, containerHeight, aspect, rotation) { 66925 if (rotation === void 0) { 66926 rotation = 0; 66927 } 66928 var _a = rotateSize(mediaWidth, mediaHeight, rotation), 66929 width = _a.width, 66930 height = _a.height; 66931 var fittingWidth = Math.min(width, containerWidth); 66932 var fittingHeight = Math.min(height, containerHeight); 66933 if (fittingWidth > fittingHeight * aspect) { 66934 return { 66935 width: fittingHeight * aspect, 66936 height: fittingHeight 66937 }; 66938 } 66939 return { 66940 width: fittingWidth, 66941 height: fittingWidth / aspect 66942 }; 66943 } 66944 /** 66945 * Compute media zoom. 66946 * We fit the media into the container with "max-width: 100%; max-height: 100%;" 66947 */ 66948 function getMediaZoom(mediaSize) { 66949 // Take the axis with more pixels to improve accuracy 66950 return mediaSize.width > mediaSize.height ? mediaSize.width / mediaSize.naturalWidth : mediaSize.height / mediaSize.naturalHeight; 66951 } 66952 /** 66953 * Ensure a new media position stays in the crop area. 66954 */ 66955 function restrictPosition(position, mediaSize, cropSize, zoom, rotation) { 66956 if (rotation === void 0) { 66957 rotation = 0; 66958 } 66959 var _a = rotateSize(mediaSize.width, mediaSize.height, rotation), 66960 width = _a.width, 66961 height = _a.height; 66962 return { 66963 x: restrictPositionCoord(position.x, width, cropSize.width, zoom), 66964 y: restrictPositionCoord(position.y, height, cropSize.height, zoom) 66965 }; 66966 } 66967 function restrictPositionCoord(position, mediaSize, cropSize, zoom) { 66968 var maxPosition = mediaSize * zoom / 2 - cropSize / 2; 66969 return clamp(position, -maxPosition, maxPosition); 66970 } 66971 function getDistanceBetweenPoints(pointA, pointB) { 66972 return Math.sqrt(Math.pow(pointA.y - pointB.y, 2) + Math.pow(pointA.x - pointB.x, 2)); 66973 } 66974 function getRotationBetweenPoints(pointA, pointB) { 66975 return Math.atan2(pointB.y - pointA.y, pointB.x - pointA.x) * 180 / Math.PI; 66976 } 66977 /** 66978 * Compute the output cropped area of the media in percentages and pixels. 66979 * x/y are the top-left coordinates on the src media 66980 */ 66981 function computeCroppedArea(crop, mediaSize, cropSize, aspect, zoom, rotation, restrictPosition) { 66982 if (rotation === void 0) { 66983 rotation = 0; 66984 } 66985 if (restrictPosition === void 0) { 66986 restrictPosition = true; 66987 } 66988 // if the media is rotated by the user, we cannot limit the position anymore 66989 // as it might need to be negative. 66990 var limitAreaFn = restrictPosition ? limitArea : noOp; 66991 var mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation); 66992 var mediaNaturalBBoxSize = rotateSize(mediaSize.naturalWidth, mediaSize.naturalHeight, rotation); 66993 // calculate the crop area in percentages 66994 // in the rotated space 66995 var croppedAreaPercentages = { 66996 x: limitAreaFn(100, ((mediaBBoxSize.width - cropSize.width / zoom) / 2 - crop.x / zoom) / mediaBBoxSize.width * 100), 66997 y: limitAreaFn(100, ((mediaBBoxSize.height - cropSize.height / zoom) / 2 - crop.y / zoom) / mediaBBoxSize.height * 100), 66998 width: limitAreaFn(100, cropSize.width / mediaBBoxSize.width * 100 / zoom), 66999 height: limitAreaFn(100, cropSize.height / mediaBBoxSize.height * 100 / zoom) 67000 }; 67001 // we compute the pixels size naively 67002 var widthInPixels = Math.round(limitAreaFn(mediaNaturalBBoxSize.width, croppedAreaPercentages.width * mediaNaturalBBoxSize.width / 100)); 67003 var heightInPixels = Math.round(limitAreaFn(mediaNaturalBBoxSize.height, croppedAreaPercentages.height * mediaNaturalBBoxSize.height / 100)); 67004 var isImgWiderThanHigh = mediaNaturalBBoxSize.width >= mediaNaturalBBoxSize.height * aspect; 67005 // then we ensure the width and height exactly match the aspect (to avoid rounding approximations) 67006 // if the media is wider than high, when zoom is 0, the crop height will be equals to image height 67007 // thus we want to compute the width from the height and aspect for accuracy. 67008 // Otherwise, we compute the height from width and aspect. 67009 var sizePixels = isImgWiderThanHigh ? { 67010 width: Math.round(heightInPixels * aspect), 67011 height: heightInPixels 67012 } : { 67013 width: widthInPixels, 67014 height: Math.round(widthInPixels / aspect) 67015 }; 67016 var croppedAreaPixels = __assign(__assign({}, sizePixels), { 67017 x: Math.round(limitAreaFn(mediaNaturalBBoxSize.width - sizePixels.width, croppedAreaPercentages.x * mediaNaturalBBoxSize.width / 100)), 67018 y: Math.round(limitAreaFn(mediaNaturalBBoxSize.height - sizePixels.height, croppedAreaPercentages.y * mediaNaturalBBoxSize.height / 100)) 67019 }); 67020 return { 67021 croppedAreaPercentages: croppedAreaPercentages, 67022 croppedAreaPixels: croppedAreaPixels 67023 }; 67024 } 67025 /** 67026 * Ensure the returned value is between 0 and max 67027 */ 67028 function limitArea(max, value) { 67029 return Math.min(max, Math.max(0, value)); 67030 } 67031 function noOp(_max, value) { 67032 return value; 67033 } 67034 /** 67035 * Compute crop and zoom from the croppedAreaPercentages. 67036 */ 67037 function getInitialCropFromCroppedAreaPercentages(croppedAreaPercentages, mediaSize, rotation, cropSize, minZoom, maxZoom) { 67038 var mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation); 67039 // This is the inverse process of computeCroppedArea 67040 var zoom = clamp(cropSize.width / mediaBBoxSize.width * (100 / croppedAreaPercentages.width), minZoom, maxZoom); 67041 var crop = { 67042 x: zoom * mediaBBoxSize.width / 2 - cropSize.width / 2 - mediaBBoxSize.width * zoom * (croppedAreaPercentages.x / 100), 67043 y: zoom * mediaBBoxSize.height / 2 - cropSize.height / 2 - mediaBBoxSize.height * zoom * (croppedAreaPercentages.y / 100) 67044 }; 67045 return { 67046 crop: crop, 67047 zoom: zoom 67048 }; 67049 } 67050 /** 67051 * Compute zoom from the croppedAreaPixels 67052 */ 67053 function getZoomFromCroppedAreaPixels(croppedAreaPixels, mediaSize, cropSize) { 67054 var mediaZoom = getMediaZoom(mediaSize); 67055 return cropSize.height > cropSize.width ? cropSize.height / (croppedAreaPixels.height * mediaZoom) : cropSize.width / (croppedAreaPixels.width * mediaZoom); 67056 } 67057 /** 67058 * Compute crop and zoom from the croppedAreaPixels 67059 */ 67060 function getInitialCropFromCroppedAreaPixels(croppedAreaPixels, mediaSize, rotation, cropSize, minZoom, maxZoom) { 67061 if (rotation === void 0) { 67062 rotation = 0; 67063 } 67064 var mediaNaturalBBoxSize = rotateSize(mediaSize.naturalWidth, mediaSize.naturalHeight, rotation); 67065 var zoom = clamp(getZoomFromCroppedAreaPixels(croppedAreaPixels, mediaSize, cropSize), minZoom, maxZoom); 67066 var cropZoom = cropSize.height > cropSize.width ? cropSize.height / croppedAreaPixels.height : cropSize.width / croppedAreaPixels.width; 67067 var crop = { 67068 x: ((mediaNaturalBBoxSize.width - croppedAreaPixels.width) / 2 - croppedAreaPixels.x) * cropZoom, 67069 y: ((mediaNaturalBBoxSize.height - croppedAreaPixels.height) / 2 - croppedAreaPixels.y) * cropZoom 67070 }; 67071 return { 67072 crop: crop, 67073 zoom: zoom 67074 }; 67075 } 67076 /** 67077 * Return the point that is the center of point a and b 67078 */ 67079 function getCenter(a, b) { 67080 return { 67081 x: (b.x + a.x) / 2, 67082 y: (b.y + a.y) / 2 67083 }; 67084 } 67085 function getRadianAngle(degreeValue) { 67086 return degreeValue * Math.PI / 180; 67087 } 67088 /** 67089 * Returns the new bounding area of a rotated rectangle. 67090 */ 67091 function rotateSize(width, height, rotation) { 67092 var rotRad = getRadianAngle(rotation); 67093 return { 67094 width: Math.abs(Math.cos(rotRad) * width) + Math.abs(Math.sin(rotRad) * height), 67095 height: Math.abs(Math.sin(rotRad) * width) + Math.abs(Math.cos(rotRad) * height) 67096 }; 67097 } 67098 /** 67099 * Clamp value between min and max 67100 */ 67101 function clamp(value, min, max) { 67102 return Math.min(Math.max(value, min), max); 67103 } 67104 /** 67105 * Combine multiple class names into a single string. 67106 */ 67107 function classNames() { 67108 var args = []; 67109 for (var _i = 0; _i < arguments.length; _i++) { 67110 args[_i] = arguments[_i]; 67111 } 67112 return args.filter(function (value) { 67113 if (typeof value === 'string' && value.length > 0) { 67114 return true; 67115 } 67116 return false; 67117 }).join(' ').trim(); 67118 } 67119 67120 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"; 67121 67122 var index_module_MIN_ZOOM = 1; 67123 var index_module_MAX_ZOOM = 3; 67124 var Cropper = /** @class */function (_super) { 67125 __extends(Cropper, _super); 67126 function Cropper() { 67127 var _this = _super !== null && _super.apply(this, arguments) || this; 67128 _this.imageRef = external_React_.createRef(); 67129 _this.videoRef = external_React_.createRef(); 67130 _this.containerPosition = { 67131 x: 0, 67132 y: 0 67133 }; 67134 _this.containerRef = null; 67135 _this.styleRef = null; 67136 _this.containerRect = null; 67137 _this.mediaSize = { 67138 width: 0, 67139 height: 0, 67140 naturalWidth: 0, 67141 naturalHeight: 0 67142 }; 67143 _this.dragStartPosition = { 67144 x: 0, 67145 y: 0 67146 }; 67147 _this.dragStartCrop = { 67148 x: 0, 67149 y: 0 67150 }; 67151 _this.gestureZoomStart = 0; 67152 _this.gestureRotationStart = 0; 67153 _this.isTouching = false; 67154 _this.lastPinchDistance = 0; 67155 _this.lastPinchRotation = 0; 67156 _this.rafDragTimeout = null; 67157 _this.rafPinchTimeout = null; 67158 _this.wheelTimer = null; 67159 _this.currentDoc = typeof document !== 'undefined' ? document : null; 67160 _this.currentWindow = typeof window !== 'undefined' ? window : null; 67161 _this.resizeObserver = null; 67162 _this.state = { 67163 cropSize: null, 67164 hasWheelJustStarted: false, 67165 mediaObjectFit: undefined 67166 }; 67167 _this.initResizeObserver = function () { 67168 if (typeof window.ResizeObserver === 'undefined' || !_this.containerRef) { 67169 return; 67170 } 67171 var isFirstResize = true; 67172 _this.resizeObserver = new window.ResizeObserver(function (entries) { 67173 if (isFirstResize) { 67174 isFirstResize = false; // observe() is called on mount, we don't want to trigger a recompute on mount 67175 return; 67176 } 67177 _this.computeSizes(); 67178 }); 67179 _this.resizeObserver.observe(_this.containerRef); 67180 }; 67181 // this is to prevent Safari on iOS >= 10 to zoom the page 67182 _this.preventZoomSafari = function (e) { 67183 return e.preventDefault(); 67184 }; 67185 _this.cleanEvents = function () { 67186 if (!_this.currentDoc) return; 67187 _this.currentDoc.removeEventListener('mousemove', _this.onMouseMove); 67188 _this.currentDoc.removeEventListener('mouseup', _this.onDragStopped); 67189 _this.currentDoc.removeEventListener('touchmove', _this.onTouchMove); 67190 _this.currentDoc.removeEventListener('touchend', _this.onDragStopped); 67191 _this.currentDoc.removeEventListener('gesturemove', _this.onGestureMove); 67192 _this.currentDoc.removeEventListener('gestureend', _this.onGestureEnd); 67193 _this.currentDoc.removeEventListener('scroll', _this.onScroll); 67194 }; 67195 _this.clearScrollEvent = function () { 67196 if (_this.containerRef) _this.containerRef.removeEventListener('wheel', _this.onWheel); 67197 if (_this.wheelTimer) { 67198 clearTimeout(_this.wheelTimer); 67199 } 67200 }; 67201 _this.onMediaLoad = function () { 67202 var cropSize = _this.computeSizes(); 67203 if (cropSize) { 67204 _this.emitCropData(); 67205 _this.setInitialCrop(cropSize); 67206 } 67207 if (_this.props.onMediaLoaded) { 67208 _this.props.onMediaLoaded(_this.mediaSize); 67209 } 67210 }; 67211 _this.setInitialCrop = function (cropSize) { 67212 if (_this.props.initialCroppedAreaPercentages) { 67213 var _a = getInitialCropFromCroppedAreaPercentages(_this.props.initialCroppedAreaPercentages, _this.mediaSize, _this.props.rotation, cropSize, _this.props.minZoom, _this.props.maxZoom), 67214 crop = _a.crop, 67215 zoom = _a.zoom; 67216 _this.props.onCropChange(crop); 67217 _this.props.onZoomChange && _this.props.onZoomChange(zoom); 67218 } else if (_this.props.initialCroppedAreaPixels) { 67219 var _b = getInitialCropFromCroppedAreaPixels(_this.props.initialCroppedAreaPixels, _this.mediaSize, _this.props.rotation, cropSize, _this.props.minZoom, _this.props.maxZoom), 67220 crop = _b.crop, 67221 zoom = _b.zoom; 67222 _this.props.onCropChange(crop); 67223 _this.props.onZoomChange && _this.props.onZoomChange(zoom); 67224 } 67225 }; 67226 _this.computeSizes = function () { 67227 var _a, _b, _c, _d, _e, _f; 67228 var mediaRef = _this.imageRef.current || _this.videoRef.current; 67229 if (mediaRef && _this.containerRef) { 67230 _this.containerRect = _this.containerRef.getBoundingClientRect(); 67231 _this.saveContainerPosition(); 67232 var containerAspect = _this.containerRect.width / _this.containerRect.height; 67233 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; 67234 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; 67235 var isMediaScaledDown = mediaRef.offsetWidth < naturalWidth || mediaRef.offsetHeight < naturalHeight; 67236 var mediaAspect = naturalWidth / naturalHeight; 67237 // We do not rely on the offsetWidth/offsetHeight if the media is scaled down 67238 // as the values they report are rounded. That will result in precision losses 67239 // when calculating zoom. We use the fact that the media is positionned relative 67240 // to the container. That allows us to use the container's dimensions 67241 // and natural aspect ratio of the media to calculate accurate media size. 67242 // However, for this to work, the container should not be rotated 67243 var renderedMediaSize = void 0; 67244 if (isMediaScaledDown) { 67245 switch (_this.state.mediaObjectFit) { 67246 default: 67247 case 'contain': 67248 renderedMediaSize = containerAspect > mediaAspect ? { 67249 width: _this.containerRect.height * mediaAspect, 67250 height: _this.containerRect.height 67251 } : { 67252 width: _this.containerRect.width, 67253 height: _this.containerRect.width / mediaAspect 67254 }; 67255 break; 67256 case 'horizontal-cover': 67257 renderedMediaSize = { 67258 width: _this.containerRect.width, 67259 height: _this.containerRect.width / mediaAspect 67260 }; 67261 break; 67262 case 'vertical-cover': 67263 renderedMediaSize = { 67264 width: _this.containerRect.height * mediaAspect, 67265 height: _this.containerRect.height 67266 }; 67267 break; 67268 } 67269 } else { 67270 renderedMediaSize = { 67271 width: mediaRef.offsetWidth, 67272 height: mediaRef.offsetHeight 67273 }; 67274 } 67275 _this.mediaSize = __assign(__assign({}, renderedMediaSize), { 67276 naturalWidth: naturalWidth, 67277 naturalHeight: naturalHeight 67278 }); 67279 // set media size in the parent 67280 if (_this.props.setMediaSize) { 67281 _this.props.setMediaSize(_this.mediaSize); 67282 } 67283 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); 67284 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) { 67285 _this.props.onCropSizeChange && _this.props.onCropSizeChange(cropSize); 67286 } 67287 _this.setState({ 67288 cropSize: cropSize 67289 }, _this.recomputeCropPosition); 67290 // pass crop size to parent 67291 if (_this.props.setCropSize) { 67292 _this.props.setCropSize(cropSize); 67293 } 67294 return cropSize; 67295 } 67296 }; 67297 _this.saveContainerPosition = function () { 67298 if (_this.containerRef) { 67299 var bounds = _this.containerRef.getBoundingClientRect(); 67300 _this.containerPosition = { 67301 x: bounds.left, 67302 y: bounds.top 67303 }; 67304 } 67305 }; 67306 _this.onMouseDown = function (e) { 67307 if (!_this.currentDoc) return; 67308 e.preventDefault(); 67309 _this.currentDoc.addEventListener('mousemove', _this.onMouseMove); 67310 _this.currentDoc.addEventListener('mouseup', _this.onDragStopped); 67311 _this.saveContainerPosition(); 67312 _this.onDragStart(Cropper.getMousePoint(e)); 67313 }; 67314 _this.onMouseMove = function (e) { 67315 return _this.onDrag(Cropper.getMousePoint(e)); 67316 }; 67317 _this.onScroll = function (e) { 67318 if (!_this.currentDoc) return; 67319 e.preventDefault(); 67320 _this.saveContainerPosition(); 67321 }; 67322 _this.onTouchStart = function (e) { 67323 if (!_this.currentDoc) return; 67324 _this.isTouching = true; 67325 if (_this.props.onTouchRequest && !_this.props.onTouchRequest(e)) { 67326 return; 67327 } 67328 _this.currentDoc.addEventListener('touchmove', _this.onTouchMove, { 67329 passive: false 67330 }); // iOS 11 now defaults to passive: true 67331 _this.currentDoc.addEventListener('touchend', _this.onDragStopped); 67332 _this.saveContainerPosition(); 67333 if (e.touches.length === 2) { 67334 _this.onPinchStart(e); 67335 } else if (e.touches.length === 1) { 67336 _this.onDragStart(Cropper.getTouchPoint(e.touches[0])); 67337 } 67338 }; 67339 _this.onTouchMove = function (e) { 67340 // Prevent whole page from scrolling on iOS. 67341 e.preventDefault(); 67342 if (e.touches.length === 2) { 67343 _this.onPinchMove(e); 67344 } else if (e.touches.length === 1) { 67345 _this.onDrag(Cropper.getTouchPoint(e.touches[0])); 67346 } 67347 }; 67348 _this.onGestureStart = function (e) { 67349 if (!_this.currentDoc) return; 67350 e.preventDefault(); 67351 _this.currentDoc.addEventListener('gesturechange', _this.onGestureMove); 67352 _this.currentDoc.addEventListener('gestureend', _this.onGestureEnd); 67353 _this.gestureZoomStart = _this.props.zoom; 67354 _this.gestureRotationStart = _this.props.rotation; 67355 }; 67356 _this.onGestureMove = function (e) { 67357 e.preventDefault(); 67358 if (_this.isTouching) { 67359 // this is to avoid conflict between gesture and touch events 67360 return; 67361 } 67362 var point = Cropper.getMousePoint(e); 67363 var newZoom = _this.gestureZoomStart - 1 + e.scale; 67364 _this.setNewZoom(newZoom, point, { 67365 shouldUpdatePosition: true 67366 }); 67367 if (_this.props.onRotationChange) { 67368 var newRotation = _this.gestureRotationStart + e.rotation; 67369 _this.props.onRotationChange(newRotation); 67370 } 67371 }; 67372 _this.onGestureEnd = function (e) { 67373 _this.cleanEvents(); 67374 }; 67375 _this.onDragStart = function (_a) { 67376 var _b, _c; 67377 var x = _a.x, 67378 y = _a.y; 67379 _this.dragStartPosition = { 67380 x: x, 67381 y: y 67382 }; 67383 _this.dragStartCrop = __assign({}, _this.props.crop); 67384 (_c = (_b = _this.props).onInteractionStart) === null || _c === void 0 ? void 0 : _c.call(_b); 67385 }; 67386 _this.onDrag = function (_a) { 67387 var x = _a.x, 67388 y = _a.y; 67389 if (!_this.currentWindow) return; 67390 if (_this.rafDragTimeout) _this.currentWindow.cancelAnimationFrame(_this.rafDragTimeout); 67391 _this.rafDragTimeout = _this.currentWindow.requestAnimationFrame(function () { 67392 if (!_this.state.cropSize) return; 67393 if (x === undefined || y === undefined) return; 67394 var offsetX = x - _this.dragStartPosition.x; 67395 var offsetY = y - _this.dragStartPosition.y; 67396 var requestedPosition = { 67397 x: _this.dragStartCrop.x + offsetX, 67398 y: _this.dragStartCrop.y + offsetY 67399 }; 67400 var newPosition = _this.props.restrictPosition ? restrictPosition(requestedPosition, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : requestedPosition; 67401 _this.props.onCropChange(newPosition); 67402 }); 67403 }; 67404 _this.onDragStopped = function () { 67405 var _a, _b; 67406 _this.isTouching = false; 67407 _this.cleanEvents(); 67408 _this.emitCropData(); 67409 (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a); 67410 }; 67411 _this.onWheel = function (e) { 67412 if (!_this.currentWindow) return; 67413 if (_this.props.onWheelRequest && !_this.props.onWheelRequest(e)) { 67414 return; 67415 } 67416 e.preventDefault(); 67417 var point = Cropper.getMousePoint(e); 67418 var pixelY = normalize_wheel_default()(e).pixelY; 67419 var newZoom = _this.props.zoom - pixelY * _this.props.zoomSpeed / 200; 67420 _this.setNewZoom(newZoom, point, { 67421 shouldUpdatePosition: true 67422 }); 67423 if (!_this.state.hasWheelJustStarted) { 67424 _this.setState({ 67425 hasWheelJustStarted: true 67426 }, function () { 67427 var _a, _b; 67428 return (_b = (_a = _this.props).onInteractionStart) === null || _b === void 0 ? void 0 : _b.call(_a); 67429 }); 67430 } 67431 if (_this.wheelTimer) { 67432 clearTimeout(_this.wheelTimer); 67433 } 67434 _this.wheelTimer = _this.currentWindow.setTimeout(function () { 67435 return _this.setState({ 67436 hasWheelJustStarted: false 67437 }, function () { 67438 var _a, _b; 67439 return (_b = (_a = _this.props).onInteractionEnd) === null || _b === void 0 ? void 0 : _b.call(_a); 67440 }); 67441 }, 250); 67442 }; 67443 _this.getPointOnContainer = function (_a, containerTopLeft) { 67444 var x = _a.x, 67445 y = _a.y; 67446 if (!_this.containerRect) { 67447 throw new Error('The Cropper is not mounted'); 67448 } 67449 return { 67450 x: _this.containerRect.width / 2 - (x - containerTopLeft.x), 67451 y: _this.containerRect.height / 2 - (y - containerTopLeft.y) 67452 }; 67453 }; 67454 _this.getPointOnMedia = function (_a) { 67455 var x = _a.x, 67456 y = _a.y; 67457 var _b = _this.props, 67458 crop = _b.crop, 67459 zoom = _b.zoom; 67460 return { 67461 x: (x + crop.x) / zoom, 67462 y: (y + crop.y) / zoom 67463 }; 67464 }; 67465 _this.setNewZoom = function (zoom, point, _a) { 67466 var _b = _a === void 0 ? {} : _a, 67467 _c = _b.shouldUpdatePosition, 67468 shouldUpdatePosition = _c === void 0 ? true : _c; 67469 if (!_this.state.cropSize || !_this.props.onZoomChange) return; 67470 var newZoom = clamp(zoom, _this.props.minZoom, _this.props.maxZoom); 67471 if (shouldUpdatePosition) { 67472 var zoomPoint = _this.getPointOnContainer(point, _this.containerPosition); 67473 var zoomTarget = _this.getPointOnMedia(zoomPoint); 67474 var requestedPosition = { 67475 x: zoomTarget.x * newZoom - zoomPoint.x, 67476 y: zoomTarget.y * newZoom - zoomPoint.y 67477 }; 67478 var newPosition = _this.props.restrictPosition ? restrictPosition(requestedPosition, _this.mediaSize, _this.state.cropSize, newZoom, _this.props.rotation) : requestedPosition; 67479 _this.props.onCropChange(newPosition); 67480 } 67481 _this.props.onZoomChange(newZoom); 67482 }; 67483 _this.getCropData = function () { 67484 if (!_this.state.cropSize) { 67485 return null; 67486 } 67487 // this is to ensure the crop is correctly restricted after a zoom back (https://github.com/ValentinH/react-easy-crop/issues/6) 67488 var restrictedPosition = _this.props.restrictPosition ? restrictPosition(_this.props.crop, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : _this.props.crop; 67489 return computeCroppedArea(restrictedPosition, _this.mediaSize, _this.state.cropSize, _this.getAspect(), _this.props.zoom, _this.props.rotation, _this.props.restrictPosition); 67490 }; 67491 _this.emitCropData = function () { 67492 var cropData = _this.getCropData(); 67493 if (!cropData) return; 67494 var croppedAreaPercentages = cropData.croppedAreaPercentages, 67495 croppedAreaPixels = cropData.croppedAreaPixels; 67496 if (_this.props.onCropComplete) { 67497 _this.props.onCropComplete(croppedAreaPercentages, croppedAreaPixels); 67498 } 67499 if (_this.props.onCropAreaChange) { 67500 _this.props.onCropAreaChange(croppedAreaPercentages, croppedAreaPixels); 67501 } 67502 }; 67503 _this.emitCropAreaChange = function () { 67504 var cropData = _this.getCropData(); 67505 if (!cropData) return; 67506 var croppedAreaPercentages = cropData.croppedAreaPercentages, 67507 croppedAreaPixels = cropData.croppedAreaPixels; 67508 if (_this.props.onCropAreaChange) { 67509 _this.props.onCropAreaChange(croppedAreaPercentages, croppedAreaPixels); 67510 } 67511 }; 67512 _this.recomputeCropPosition = function () { 67513 if (!_this.state.cropSize) return; 67514 var newPosition = _this.props.restrictPosition ? restrictPosition(_this.props.crop, _this.mediaSize, _this.state.cropSize, _this.props.zoom, _this.props.rotation) : _this.props.crop; 67515 _this.props.onCropChange(newPosition); 67516 _this.emitCropData(); 67517 }; 67518 return _this; 67519 } 67520 Cropper.prototype.componentDidMount = function () { 67521 if (!this.currentDoc || !this.currentWindow) return; 67522 if (this.containerRef) { 67523 if (this.containerRef.ownerDocument) { 67524 this.currentDoc = this.containerRef.ownerDocument; 67525 } 67526 if (this.currentDoc.defaultView) { 67527 this.currentWindow = this.currentDoc.defaultView; 67528 } 67529 this.initResizeObserver(); 67530 // only add window resize listener if ResizeObserver is not supported. Otherwise, it would be redundant 67531 if (typeof window.ResizeObserver === 'undefined') { 67532 this.currentWindow.addEventListener('resize', this.computeSizes); 67533 } 67534 this.props.zoomWithScroll && this.containerRef.addEventListener('wheel', this.onWheel, { 67535 passive: false 67536 }); 67537 this.containerRef.addEventListener('gesturestart', this.onGestureStart); 67538 } 67539 this.currentDoc.addEventListener('scroll', this.onScroll); 67540 if (!this.props.disableAutomaticStylesInjection) { 67541 this.styleRef = this.currentDoc.createElement('style'); 67542 this.styleRef.setAttribute('type', 'text/css'); 67543 if (this.props.nonce) { 67544 this.styleRef.setAttribute('nonce', this.props.nonce); 67545 } 67546 this.styleRef.innerHTML = css_248z; 67547 this.currentDoc.head.appendChild(this.styleRef); 67548 } 67549 // when rendered via SSR, the image can already be loaded and its onLoad callback will never be called 67550 if (this.imageRef.current && this.imageRef.current.complete) { 67551 this.onMediaLoad(); 67552 } 67553 // set image and video refs in the parent if the callbacks exist 67554 if (this.props.setImageRef) { 67555 this.props.setImageRef(this.imageRef); 67556 } 67557 if (this.props.setVideoRef) { 67558 this.props.setVideoRef(this.videoRef); 67559 } 67560 }; 67561 Cropper.prototype.componentWillUnmount = function () { 67562 var _a, _b; 67563 if (!this.currentDoc || !this.currentWindow) return; 67564 if (typeof window.ResizeObserver === 'undefined') { 67565 this.currentWindow.removeEventListener('resize', this.computeSizes); 67566 } 67567 (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); 67568 if (this.containerRef) { 67569 this.containerRef.removeEventListener('gesturestart', this.preventZoomSafari); 67570 } 67571 if (this.styleRef) { 67572 (_b = this.styleRef.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.styleRef); 67573 } 67574 this.cleanEvents(); 67575 this.props.zoomWithScroll && this.clearScrollEvent(); 67576 }; 67577 Cropper.prototype.componentDidUpdate = function (prevProps) { 67578 var _a, _b, _c, _d, _e, _f, _g, _h, _j; 67579 if (prevProps.rotation !== this.props.rotation) { 67580 this.computeSizes(); 67581 this.recomputeCropPosition(); 67582 } else if (prevProps.aspect !== this.props.aspect) { 67583 this.computeSizes(); 67584 } else if (prevProps.objectFit !== this.props.objectFit) { 67585 this.computeSizes(); 67586 } else if (prevProps.zoom !== this.props.zoom) { 67587 this.recomputeCropPosition(); 67588 } 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)) { 67589 this.computeSizes(); 67590 } 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)) { 67591 this.emitCropAreaChange(); 67592 } 67593 if (prevProps.zoomWithScroll !== this.props.zoomWithScroll && this.containerRef) { 67594 this.props.zoomWithScroll ? this.containerRef.addEventListener('wheel', this.onWheel, { 67595 passive: false 67596 }) : this.clearScrollEvent(); 67597 } 67598 if (prevProps.video !== this.props.video) { 67599 (_j = this.videoRef.current) === null || _j === void 0 ? void 0 : _j.load(); 67600 } 67601 var objectFit = this.getObjectFit(); 67602 if (objectFit !== this.state.mediaObjectFit) { 67603 this.setState({ 67604 mediaObjectFit: objectFit 67605 }, this.computeSizes); 67606 } 67607 }; 67608 Cropper.prototype.getAspect = function () { 67609 var _a = this.props, 67610 cropSize = _a.cropSize, 67611 aspect = _a.aspect; 67612 if (cropSize) { 67613 return cropSize.width / cropSize.height; 67614 } 67615 return aspect; 67616 }; 67617 Cropper.prototype.getObjectFit = function () { 67618 var _a, _b, _c, _d; 67619 if (this.props.objectFit === 'cover') { 67620 var mediaRef = this.imageRef.current || this.videoRef.current; 67621 if (mediaRef && this.containerRef) { 67622 this.containerRect = this.containerRef.getBoundingClientRect(); 67623 var containerAspect = this.containerRect.width / this.containerRect.height; 67624 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; 67625 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; 67626 var mediaAspect = naturalWidth / naturalHeight; 67627 return mediaAspect < containerAspect ? 'horizontal-cover' : 'vertical-cover'; 67628 } 67629 return 'horizontal-cover'; 67630 } 67631 return this.props.objectFit; 67632 }; 67633 Cropper.prototype.onPinchStart = function (e) { 67634 var pointA = Cropper.getTouchPoint(e.touches[0]); 67635 var pointB = Cropper.getTouchPoint(e.touches[1]); 67636 this.lastPinchDistance = getDistanceBetweenPoints(pointA, pointB); 67637 this.lastPinchRotation = getRotationBetweenPoints(pointA, pointB); 67638 this.onDragStart(getCenter(pointA, pointB)); 67639 }; 67640 Cropper.prototype.onPinchMove = function (e) { 67641 var _this = this; 67642 if (!this.currentDoc || !this.currentWindow) return; 67643 var pointA = Cropper.getTouchPoint(e.touches[0]); 67644 var pointB = Cropper.getTouchPoint(e.touches[1]); 67645 var center = getCenter(pointA, pointB); 67646 this.onDrag(center); 67647 if (this.rafPinchTimeout) this.currentWindow.cancelAnimationFrame(this.rafPinchTimeout); 67648 this.rafPinchTimeout = this.currentWindow.requestAnimationFrame(function () { 67649 var distance = getDistanceBetweenPoints(pointA, pointB); 67650 var newZoom = _this.props.zoom * (distance / _this.lastPinchDistance); 67651 _this.setNewZoom(newZoom, center, { 67652 shouldUpdatePosition: false 67653 }); 67654 _this.lastPinchDistance = distance; 67655 var rotation = getRotationBetweenPoints(pointA, pointB); 67656 var newRotation = _this.props.rotation + (rotation - _this.lastPinchRotation); 67657 _this.props.onRotationChange && _this.props.onRotationChange(newRotation); 67658 _this.lastPinchRotation = rotation; 67659 }); 67660 }; 67661 Cropper.prototype.render = function () { 67662 var _this = this; 67663 var _a = this.props, 67664 image = _a.image, 67665 video = _a.video, 67666 mediaProps = _a.mediaProps, 67667 transform = _a.transform, 67668 _b = _a.crop, 67669 x = _b.x, 67670 y = _b.y, 67671 rotation = _a.rotation, 67672 zoom = _a.zoom, 67673 cropShape = _a.cropShape, 67674 showGrid = _a.showGrid, 67675 _c = _a.style, 67676 containerStyle = _c.containerStyle, 67677 cropAreaStyle = _c.cropAreaStyle, 67678 mediaStyle = _c.mediaStyle, 67679 _d = _a.classes, 67680 containerClassName = _d.containerClassName, 67681 cropAreaClassName = _d.cropAreaClassName, 67682 mediaClassName = _d.mediaClassName; 67683 var objectFit = this.state.mediaObjectFit; 67684 return external_React_.createElement("div", { 67685 onMouseDown: this.onMouseDown, 67686 onTouchStart: this.onTouchStart, 67687 ref: function ref(el) { 67688 return _this.containerRef = el; 67689 }, 67690 "data-testid": "container", 67691 style: containerStyle, 67692 className: classNames('reactEasyCrop_Container', containerClassName) 67693 }, image ? external_React_.createElement("img", __assign({ 67694 alt: "", 67695 className: classNames('reactEasyCrop_Image', objectFit === 'contain' && 'reactEasyCrop_Contain', objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal', objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical', mediaClassName) 67696 }, mediaProps, { 67697 src: image, 67698 ref: this.imageRef, 67699 style: __assign(__assign({}, mediaStyle), { 67700 transform: transform || "translate(".concat(x, "px, ").concat(y, "px) rotate(").concat(rotation, "deg) scale(").concat(zoom, ")") 67701 }), 67702 onLoad: this.onMediaLoad 67703 })) : video && external_React_.createElement("video", __assign({ 67704 autoPlay: true, 67705 loop: true, 67706 muted: true, 67707 className: classNames('reactEasyCrop_Video', objectFit === 'contain' && 'reactEasyCrop_Contain', objectFit === 'horizontal-cover' && 'reactEasyCrop_Cover_Horizontal', objectFit === 'vertical-cover' && 'reactEasyCrop_Cover_Vertical', mediaClassName) 67708 }, mediaProps, { 67709 ref: this.videoRef, 67710 onLoadedMetadata: this.onMediaLoad, 67711 style: __assign(__assign({}, mediaStyle), { 67712 transform: transform || "translate(".concat(x, "px, ").concat(y, "px) rotate(").concat(rotation, "deg) scale(").concat(zoom, ")") 67713 }), 67714 controls: false 67715 }), (Array.isArray(video) ? video : [{ 67716 src: video 67717 }]).map(function (item) { 67718 return external_React_.createElement("source", __assign({ 67719 key: item.src 67720 }, item)); 67721 })), this.state.cropSize && external_React_.createElement("div", { 67722 style: __assign(__assign({}, cropAreaStyle), { 67723 width: this.state.cropSize.width, 67724 height: this.state.cropSize.height 67725 }), 67726 "data-testid": "cropper", 67727 className: classNames('reactEasyCrop_CropArea', cropShape === 'round' && 'reactEasyCrop_CropAreaRound', showGrid && 'reactEasyCrop_CropAreaGrid', cropAreaClassName) 67728 })); 67729 }; 67730 Cropper.defaultProps = { 67731 zoom: 1, 67732 rotation: 0, 67733 aspect: 4 / 3, 67734 maxZoom: index_module_MAX_ZOOM, 67735 minZoom: index_module_MIN_ZOOM, 67736 cropShape: 'rect', 67737 objectFit: 'contain', 67738 showGrid: true, 67739 style: {}, 67740 classes: {}, 67741 mediaProps: {}, 67742 zoomSpeed: 1, 67743 restrictPosition: true, 67744 zoomWithScroll: true 67745 }; 67746 Cropper.getMousePoint = function (e) { 67747 return { 67748 x: Number(e.clientX), 67749 y: Number(e.clientY) 67750 }; 67751 }; 67752 Cropper.getTouchPoint = function (touch) { 67753 return { 67754 x: Number(touch.clientX), 67755 y: Number(touch.clientY) 67756 }; 67757 }; 67758 return Cropper; 67759 }(external_React_.Component); 67760 67761 67762 67763 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/cropper.js 67764 /** 67765 * External dependencies 67766 */ 67767 67768 67769 67770 /** 67771 * WordPress dependencies 67772 */ 67773 67774 67775 67776 /** 67777 * Internal dependencies 67778 */ 67779 67780 67781 67782 function ImageCropper({ 67783 url, 67784 width, 67785 height, 67786 naturalHeight, 67787 naturalWidth, 67788 borderProps 67789 }) { 67790 const { 67791 isInProgress, 67792 editedUrl, 67793 position, 67794 zoom, 67795 aspect, 67796 setPosition, 67797 setCrop, 67798 setZoom, 67799 rotation 67800 } = useImageEditingContext(); 67801 const [contentResizeListener, { 67802 width: clientWidth 67803 }] = (0,external_wp_compose_namespaceObject.useResizeObserver)(); 67804 let editedHeight = height || clientWidth * naturalHeight / naturalWidth; 67805 if (rotation % 180 === 90) { 67806 editedHeight = clientWidth * naturalWidth / naturalHeight; 67807 } 67808 const area = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 67809 className: dist_clsx('wp-block-image__crop-area', borderProps?.className, { 67810 'is-applying': isInProgress 67811 }), 67812 style: { 67813 ...borderProps?.style, 67814 width: width || clientWidth, 67815 height: editedHeight 67816 }, 67817 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Cropper, { 67818 image: editedUrl || url, 67819 disabled: isInProgress, 67820 minZoom: MIN_ZOOM / 100, 67821 maxZoom: MAX_ZOOM / 100, 67822 crop: position, 67823 zoom: zoom / 100, 67824 aspect: aspect, 67825 onCropChange: pos => { 67826 setPosition(pos); 67827 }, 67828 onCropComplete: newCropPercent => { 67829 setCrop(newCropPercent); 67830 }, 67831 onZoomChange: newZoom => { 67832 setZoom(newZoom * 100); 67833 } 67834 }), isInProgress && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Spinner, {})] 67835 }); 67836 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 67837 children: [contentResizeListener, area] 67838 }); 67839 } 67840 67841 ;// ./node_modules/@wordpress/icons/build-module/library/search.js 67842 /** 67843 * WordPress dependencies 67844 */ 67845 67846 67847 const search = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 67848 xmlns: "http://www.w3.org/2000/svg", 67849 viewBox: "0 0 24 24", 67850 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 67851 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" 67852 }) 67853 }); 67854 /* harmony default export */ const library_search = (search); 67855 67856 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/zoom-dropdown.js 67857 /** 67858 * WordPress dependencies 67859 */ 67860 67861 67862 67863 67864 /** 67865 * Internal dependencies 67866 */ 67867 67868 67869 67870 function ZoomDropdown() { 67871 const { 67872 isInProgress, 67873 zoom, 67874 setZoom 67875 } = useImageEditingContext(); 67876 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 67877 contentClassName: "wp-block-image__zoom", 67878 popoverProps: constants_POPOVER_PROPS, 67879 renderToggle: ({ 67880 isOpen, 67881 onToggle 67882 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 67883 icon: library_search, 67884 label: (0,external_wp_i18n_namespaceObject.__)('Zoom'), 67885 onClick: onToggle, 67886 "aria-expanded": isOpen, 67887 disabled: isInProgress 67888 }), 67889 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalDropdownContentWrapper, { 67890 paddingSize: "medium", 67891 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.RangeControl, { 67892 __next40pxDefaultSize: true, 67893 __nextHasNoMarginBottom: true, 67894 label: (0,external_wp_i18n_namespaceObject.__)('Zoom'), 67895 min: MIN_ZOOM, 67896 max: MAX_ZOOM, 67897 value: Math.round(zoom), 67898 onChange: setZoom 67899 }) 67900 }) 67901 }); 67902 } 67903 67904 ;// ./node_modules/@wordpress/icons/build-module/library/rotate-right.js 67905 /** 67906 * WordPress dependencies 67907 */ 67908 67909 67910 const rotateRight = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 67911 xmlns: "http://www.w3.org/2000/svg", 67912 viewBox: "0 0 24 24", 67913 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 67914 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" 67915 }) 67916 }); 67917 /* harmony default export */ const rotate_right = (rotateRight); 67918 67919 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/rotation-button.js 67920 /** 67921 * WordPress dependencies 67922 */ 67923 67924 67925 67926 67927 67928 /** 67929 * Internal dependencies 67930 */ 67931 67932 67933 function RotationButton() { 67934 const { 67935 isInProgress, 67936 rotateClockwise 67937 } = useImageEditingContext(); 67938 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 67939 icon: rotate_right, 67940 label: (0,external_wp_i18n_namespaceObject.__)('Rotate'), 67941 onClick: rotateClockwise, 67942 disabled: isInProgress 67943 }); 67944 } 67945 67946 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/form-controls.js 67947 /** 67948 * WordPress dependencies 67949 */ 67950 67951 67952 67953 /** 67954 * Internal dependencies 67955 */ 67956 67957 67958 function FormControls() { 67959 const { 67960 isInProgress, 67961 apply, 67962 cancel 67963 } = useImageEditingContext(); 67964 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 67965 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 67966 onClick: apply, 67967 disabled: isInProgress, 67968 children: (0,external_wp_i18n_namespaceObject.__)('Apply') 67969 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 67970 onClick: cancel, 67971 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 67972 })] 67973 }); 67974 } 67975 67976 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-editor/index.js 67977 /** 67978 * WordPress dependencies 67979 */ 67980 67981 67982 /** 67983 * Internal dependencies 67984 */ 67985 67986 67987 67988 67989 67990 67991 67992 67993 function ImageEditor({ 67994 id, 67995 url, 67996 width, 67997 height, 67998 naturalHeight, 67999 naturalWidth, 68000 onSaveImage, 68001 onFinishEditing, 68002 borderProps 68003 }) { 68004 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(ImageEditingProvider, { 68005 id: id, 68006 url: url, 68007 naturalWidth: naturalWidth, 68008 naturalHeight: naturalHeight, 68009 onSaveImage: onSaveImage, 68010 onFinishEditing: onFinishEditing, 68011 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ImageCropper, { 68012 borderProps: borderProps, 68013 url: url, 68014 width: width, 68015 height: height, 68016 naturalHeight: naturalHeight, 68017 naturalWidth: naturalWidth 68018 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(block_controls, { 68019 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.ToolbarGroup, { 68020 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ZoomDropdown, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarItem, { 68021 children: toggleProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioDropdown, { 68022 toggleProps: toggleProps 68023 }) 68024 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RotationButton, {})] 68025 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 68026 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FormControls, {}) 68027 })] 68028 })] 68029 }); 68030 } 68031 68032 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-size-control/use-dimension-handler.js 68033 /** 68034 * WordPress dependencies 68035 */ 68036 68037 function useDimensionHandler(customHeight, customWidth, defaultHeight, defaultWidth, onChange) { 68038 var _ref, _ref2; 68039 const [currentWidth, setCurrentWidth] = (0,external_wp_element_namespaceObject.useState)((_ref = customWidth !== null && customWidth !== void 0 ? customWidth : defaultWidth) !== null && _ref !== void 0 ? _ref : ''); 68040 const [currentHeight, setCurrentHeight] = (0,external_wp_element_namespaceObject.useState)((_ref2 = customHeight !== null && customHeight !== void 0 ? customHeight : defaultHeight) !== null && _ref2 !== void 0 ? _ref2 : ''); 68041 68042 // When an image is first inserted, the default dimensions are initially 68043 // undefined. This effect updates the dimensions when the default values 68044 // come through. 68045 (0,external_wp_element_namespaceObject.useEffect)(() => { 68046 if (customWidth === undefined && defaultWidth !== undefined) { 68047 setCurrentWidth(defaultWidth); 68048 } 68049 if (customHeight === undefined && defaultHeight !== undefined) { 68050 setCurrentHeight(defaultHeight); 68051 } 68052 }, [defaultWidth, defaultHeight]); 68053 68054 // If custom values change, it means an outsider has resized the image using some other method (eg resize box) 68055 // this keeps track of these values too. We need to parse before comparing; custom values can be strings. 68056 (0,external_wp_element_namespaceObject.useEffect)(() => { 68057 if (customWidth !== undefined && Number.parseInt(customWidth) !== Number.parseInt(currentWidth)) { 68058 setCurrentWidth(customWidth); 68059 } 68060 if (customHeight !== undefined && Number.parseInt(customHeight) !== Number.parseInt(currentHeight)) { 68061 setCurrentHeight(customHeight); 68062 } 68063 }, [customWidth, customHeight]); 68064 const updateDimension = (dimension, value) => { 68065 const parsedValue = value === '' ? undefined : parseInt(value, 10); 68066 if (dimension === 'width') { 68067 setCurrentWidth(parsedValue); 68068 } else { 68069 setCurrentHeight(parsedValue); 68070 } 68071 onChange({ 68072 [dimension]: parsedValue 68073 }); 68074 }; 68075 const updateDimensions = (nextHeight, nextWidth) => { 68076 setCurrentHeight(nextHeight !== null && nextHeight !== void 0 ? nextHeight : defaultHeight); 68077 setCurrentWidth(nextWidth !== null && nextWidth !== void 0 ? nextWidth : defaultWidth); 68078 onChange({ 68079 height: nextHeight, 68080 width: nextWidth 68081 }); 68082 }; 68083 return { 68084 currentHeight, 68085 currentWidth, 68086 updateDimension, 68087 updateDimensions 68088 }; 68089 } 68090 68091 ;// ./node_modules/@wordpress/block-editor/build-module/components/image-size-control/index.js 68092 /** 68093 * WordPress dependencies 68094 */ 68095 68096 68097 68098 /** 68099 * Internal dependencies 68100 */ 68101 68102 68103 const IMAGE_SIZE_PRESETS = [25, 50, 75, 100]; 68104 const image_size_control_noop = () => {}; 68105 68106 /** 68107 * Get scaled width and height for the given scale. 68108 * 68109 * @param {number} scale The scale to get the scaled width and height for. 68110 * @param {number} imageWidth The image width. 68111 * @param {number} imageHeight The image height. 68112 * 68113 * @return {Object} The scaled width and height. 68114 */ 68115 function getScaledWidthAndHeight(scale, imageWidth, imageHeight) { 68116 const scaledWidth = Math.round(imageWidth * (scale / 100)); 68117 const scaledHeight = Math.round(imageHeight * (scale / 100)); 68118 return { 68119 scaledWidth, 68120 scaledHeight 68121 }; 68122 } 68123 function ImageSizeControl({ 68124 imageSizeHelp, 68125 imageWidth, 68126 imageHeight, 68127 imageSizeOptions = [], 68128 isResizable = true, 68129 slug, 68130 width, 68131 height, 68132 onChange, 68133 onChangeImage = image_size_control_noop 68134 }) { 68135 const { 68136 currentHeight, 68137 currentWidth, 68138 updateDimension, 68139 updateDimensions 68140 } = useDimensionHandler(height, width, imageHeight, imageWidth, onChange); 68141 68142 /** 68143 * Updates the dimensions for the given scale. 68144 * Handler for toggle group control change. 68145 * 68146 * @param {number} scale The scale to update the dimensions for. 68147 */ 68148 const handleUpdateDimensions = scale => { 68149 if (undefined === scale) { 68150 updateDimensions(); 68151 return; 68152 } 68153 const { 68154 scaledWidth, 68155 scaledHeight 68156 } = getScaledWidthAndHeight(scale, imageWidth, imageHeight); 68157 updateDimensions(scaledHeight, scaledWidth); 68158 }; 68159 68160 /** 68161 * Add the stored image preset value to toggle group control. 68162 */ 68163 const selectedValue = IMAGE_SIZE_PRESETS.find(scale => { 68164 const { 68165 scaledWidth, 68166 scaledHeight 68167 } = getScaledWidthAndHeight(scale, imageWidth, imageHeight); 68168 return currentWidth === scaledWidth && currentHeight === scaledHeight; 68169 }); 68170 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 68171 children: [imageSizeOptions && imageSizeOptions.length > 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SelectControl, { 68172 __nextHasNoMarginBottom: true, 68173 label: (0,external_wp_i18n_namespaceObject.__)('Resolution'), 68174 value: slug, 68175 options: imageSizeOptions, 68176 onChange: onChangeImage, 68177 help: imageSizeHelp, 68178 size: "__unstable-large" 68179 }), isResizable && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 68180 className: "block-editor-image-size-control", 68181 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 68182 align: "baseline", 68183 spacing: "3", 68184 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, { 68185 className: "block-editor-image-size-control__width", 68186 label: (0,external_wp_i18n_namespaceObject.__)('Width'), 68187 value: currentWidth, 68188 min: 1, 68189 onChange: value => updateDimension('width', value), 68190 size: "__unstable-large" 68191 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalNumberControl, { 68192 className: "block-editor-image-size-control__height", 68193 label: (0,external_wp_i18n_namespaceObject.__)('Height'), 68194 value: currentHeight, 68195 min: 1, 68196 onChange: value => updateDimension('height', value), 68197 size: "__unstable-large" 68198 })] 68199 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 68200 label: (0,external_wp_i18n_namespaceObject.__)('Image size presets'), 68201 hideLabelFromVision: true, 68202 onChange: handleUpdateDimensions, 68203 value: selectedValue, 68204 isBlock: true, 68205 __next40pxDefaultSize: true, 68206 __nextHasNoMarginBottom: true, 68207 children: IMAGE_SIZE_PRESETS.map(scale => { 68208 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 68209 value: scale, 68210 label: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: Percentage value. */ 68211 (0,external_wp_i18n_namespaceObject.__)('%d%%'), scale) 68212 }, scale); 68213 }) 68214 })] 68215 })] 68216 }); 68217 } 68218 68219 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-popover/link-viewer-url.js 68220 /** 68221 * External dependencies 68222 */ 68223 68224 68225 /** 68226 * WordPress dependencies 68227 */ 68228 68229 68230 68231 function LinkViewerURL({ 68232 url, 68233 urlLabel, 68234 className 68235 }) { 68236 const linkClassName = dist_clsx(className, 'block-editor-url-popover__link-viewer-url'); 68237 if (!url) { 68238 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 68239 className: linkClassName 68240 }); 68241 } 68242 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ExternalLink, { 68243 className: linkClassName, 68244 href: url, 68245 children: urlLabel || (0,external_wp_url_namespaceObject.filterURLForDisplay)((0,external_wp_url_namespaceObject.safeDecodeURI)(url)) 68246 }); 68247 } 68248 68249 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-popover/link-viewer.js 68250 /** 68251 * External dependencies 68252 */ 68253 68254 68255 /** 68256 * WordPress dependencies 68257 */ 68258 68259 68260 68261 68262 /** 68263 * Internal dependencies 68264 */ 68265 68266 68267 function LinkViewer({ 68268 className, 68269 linkClassName, 68270 onEditLinkClick, 68271 url, 68272 urlLabel, 68273 ...props 68274 }) { 68275 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 68276 className: dist_clsx('block-editor-url-popover__link-viewer', className), 68277 ...props, 68278 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(LinkViewerURL, { 68279 url: url, 68280 urlLabel: urlLabel, 68281 className: linkClassName 68282 }), onEditLinkClick && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68283 icon: edit, 68284 label: (0,external_wp_i18n_namespaceObject.__)('Edit'), 68285 onClick: onEditLinkClick, 68286 size: "compact" 68287 })] 68288 }); 68289 } 68290 68291 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-popover/link-editor.js 68292 /** 68293 * External dependencies 68294 */ 68295 68296 68297 /** 68298 * WordPress dependencies 68299 */ 68300 68301 68302 68303 68304 /** 68305 * Internal dependencies 68306 */ 68307 68308 68309 function LinkEditor({ 68310 autocompleteRef, 68311 className, 68312 onChangeInputValue, 68313 value, 68314 ...props 68315 }) { 68316 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("form", { 68317 className: dist_clsx('block-editor-url-popover__link-editor', className), 68318 ...props, 68319 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_input, { 68320 value: value, 68321 onChange: onChangeInputValue, 68322 autocompleteRef: autocompleteRef 68323 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68324 icon: keyboard_return, 68325 label: (0,external_wp_i18n_namespaceObject.__)('Apply'), 68326 type: "submit", 68327 size: "compact" 68328 })] 68329 }); 68330 } 68331 68332 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-popover/index.js 68333 /** 68334 * WordPress dependencies 68335 */ 68336 68337 68338 68339 68340 68341 68342 /** 68343 * Internal dependencies 68344 */ 68345 68346 68347 68348 68349 const { 68350 __experimentalPopoverLegacyPositionToPlacement 68351 } = unlock(external_wp_components_namespaceObject.privateApis); 68352 const DEFAULT_PLACEMENT = 'bottom'; 68353 const URLPopover = (0,external_wp_element_namespaceObject.forwardRef)(({ 68354 additionalControls, 68355 children, 68356 renderSettings, 68357 // The DEFAULT_PLACEMENT value is assigned inside the function's body 68358 placement, 68359 focusOnMount = 'firstElement', 68360 // Deprecated 68361 position, 68362 // Rest 68363 ...popoverProps 68364 }, ref) => { 68365 if (position !== undefined) { 68366 external_wp_deprecated_default()('`position` prop in wp.blockEditor.URLPopover', { 68367 since: '6.2', 68368 alternative: '`placement` prop' 68369 }); 68370 } 68371 68372 // Compute popover's placement: 68373 // - give priority to `placement` prop, if defined 68374 // - otherwise, compute it from the legacy `position` prop (if defined) 68375 // - finally, fallback to the DEFAULT_PLACEMENT. 68376 let computedPlacement; 68377 if (placement !== undefined) { 68378 computedPlacement = placement; 68379 } else if (position !== undefined) { 68380 computedPlacement = __experimentalPopoverLegacyPositionToPlacement(position); 68381 } 68382 computedPlacement = computedPlacement || DEFAULT_PLACEMENT; 68383 const [isSettingsExpanded, setIsSettingsExpanded] = (0,external_wp_element_namespaceObject.useState)(false); 68384 const showSettings = !!renderSettings && isSettingsExpanded; 68385 const toggleSettingsVisibility = () => { 68386 setIsSettingsExpanded(!isSettingsExpanded); 68387 }; 68388 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Popover, { 68389 ref: ref, 68390 role: "dialog", 68391 "aria-modal": "true", 68392 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Edit URL'), 68393 className: "block-editor-url-popover", 68394 focusOnMount: focusOnMount, 68395 placement: computedPlacement, 68396 shift: true, 68397 variant: "toolbar", 68398 ...popoverProps, 68399 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 68400 className: "block-editor-url-popover__input-container", 68401 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 68402 className: "block-editor-url-popover__row", 68403 children: [children, !!renderSettings && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68404 className: "block-editor-url-popover__settings-toggle", 68405 icon: chevron_down, 68406 label: (0,external_wp_i18n_namespaceObject.__)('Link settings'), 68407 onClick: toggleSettingsVisibility, 68408 "aria-expanded": isSettingsExpanded, 68409 size: "compact" 68410 })] 68411 }) 68412 }), showSettings && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 68413 className: "block-editor-url-popover__settings", 68414 children: renderSettings() 68415 }), additionalControls && !showSettings && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 68416 className: "block-editor-url-popover__additional-controls", 68417 children: additionalControls 68418 })] 68419 }); 68420 }); 68421 URLPopover.LinkEditor = LinkEditor; 68422 URLPopover.LinkViewer = LinkViewer; 68423 68424 /** 68425 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-popover/README.md 68426 */ 68427 /* harmony default export */ const url_popover = (URLPopover); 68428 68429 ;// ./node_modules/@wordpress/block-editor/build-module/components/media-placeholder/index.js 68430 /** 68431 * External dependencies 68432 */ 68433 68434 68435 /** 68436 * WordPress dependencies 68437 */ 68438 68439 68440 68441 68442 68443 68444 68445 /** 68446 * Internal dependencies 68447 */ 68448 68449 68450 68451 68452 68453 68454 const media_placeholder_noop = () => {}; 68455 const InsertFromURLPopover = ({ 68456 src, 68457 onChange, 68458 onSubmit, 68459 onClose, 68460 popoverAnchor 68461 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_popover, { 68462 anchor: popoverAnchor, 68463 onClose: onClose, 68464 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("form", { 68465 className: "block-editor-media-placeholder__url-input-form", 68466 onSubmit: onSubmit, 68467 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControl, { 68468 __next40pxDefaultSize: true, 68469 label: (0,external_wp_i18n_namespaceObject.__)('URL'), 68470 type: "url", 68471 hideLabelFromVision: true, 68472 placeholder: (0,external_wp_i18n_namespaceObject.__)('Paste or type URL'), 68473 onChange: onChange, 68474 value: src, 68475 suffix: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlSuffixWrapper, { 68476 variant: "control", 68477 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68478 size: "small", 68479 icon: keyboard_return, 68480 label: (0,external_wp_i18n_namespaceObject.__)('Apply'), 68481 type: "submit" 68482 }) 68483 }) 68484 }) 68485 }) 68486 }); 68487 const URLSelectionUI = ({ 68488 src, 68489 onChangeSrc, 68490 onSelectURL 68491 }) => { 68492 // Use internal state instead of a ref to make sure that the component 68493 // re-renders when the popover's anchor updates. 68494 const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null); 68495 const [isURLInputVisible, setIsURLInputVisible] = (0,external_wp_element_namespaceObject.useState)(false); 68496 const openURLInput = () => { 68497 setIsURLInputVisible(true); 68498 }; 68499 const closeURLInput = () => { 68500 setIsURLInputVisible(false); 68501 popoverAnchor?.focus(); 68502 }; 68503 const onSubmitSrc = event => { 68504 event.preventDefault(); 68505 if (src && onSelectURL) { 68506 onSelectURL(src); 68507 closeURLInput(); 68508 } 68509 }; 68510 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 68511 className: "block-editor-media-placeholder__url-input-container", 68512 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68513 __next40pxDefaultSize: true, 68514 className: "block-editor-media-placeholder__button", 68515 onClick: openURLInput, 68516 isPressed: isURLInputVisible, 68517 variant: "secondary", 68518 "aria-haspopup": "dialog", 68519 ref: setPopoverAnchor, 68520 children: (0,external_wp_i18n_namespaceObject.__)('Insert from URL') 68521 }), isURLInputVisible && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InsertFromURLPopover, { 68522 src: src, 68523 onChange: onChangeSrc, 68524 onSubmit: onSubmitSrc, 68525 onClose: closeURLInput, 68526 popoverAnchor: popoverAnchor 68527 })] 68528 }); 68529 }; 68530 function MediaPlaceholder({ 68531 value = {}, 68532 allowedTypes, 68533 className, 68534 icon, 68535 labels = {}, 68536 mediaPreview, 68537 notices, 68538 isAppender, 68539 accept, 68540 addToGallery, 68541 multiple = false, 68542 handleUpload = true, 68543 disableDropZone, 68544 disableMediaButtons, 68545 onError, 68546 onSelect, 68547 onCancel, 68548 onSelectURL, 68549 onToggleFeaturedImage, 68550 onDoubleClick, 68551 onFilesPreUpload = media_placeholder_noop, 68552 onHTMLDrop: deprecatedOnHTMLDrop, 68553 children, 68554 mediaLibraryButton, 68555 placeholder, 68556 style 68557 }) { 68558 if (deprecatedOnHTMLDrop) { 68559 external_wp_deprecated_default()('wp.blockEditor.MediaPlaceholder onHTMLDrop prop', { 68560 since: '6.2', 68561 version: '6.4' 68562 }); 68563 } 68564 const mediaUpload = (0,external_wp_data_namespaceObject.useSelect)(select => { 68565 const { 68566 getSettings 68567 } = select(store); 68568 return getSettings().mediaUpload; 68569 }, []); 68570 const [src, setSrc] = (0,external_wp_element_namespaceObject.useState)(''); 68571 (0,external_wp_element_namespaceObject.useEffect)(() => { 68572 var _value$src; 68573 setSrc((_value$src = value?.src) !== null && _value$src !== void 0 ? _value$src : ''); 68574 }, [value?.src]); 68575 const onlyAllowsImages = () => { 68576 if (!allowedTypes || allowedTypes.length === 0) { 68577 return false; 68578 } 68579 return allowedTypes.every(allowedType => allowedType === 'image' || allowedType.startsWith('image/')); 68580 }; 68581 const onFilesUpload = files => { 68582 if (!handleUpload || typeof handleUpload === 'function' && !handleUpload(files)) { 68583 return onSelect(files); 68584 } 68585 onFilesPreUpload(files); 68586 let setMedia; 68587 if (multiple) { 68588 if (addToGallery) { 68589 // Since the setMedia function runs multiple times per upload group 68590 // and is passed newMedia containing every item in its group each time, we must 68591 // filter out whatever this upload group had previously returned to the 68592 // gallery before adding and returning the image array with replacement newMedia 68593 // values. 68594 68595 // Define an array to store urls from newMedia between subsequent function calls. 68596 let lastMediaPassed = []; 68597 setMedia = newMedia => { 68598 // Remove any images this upload group is responsible for (lastMediaPassed). 68599 // Their replacements are contained in newMedia. 68600 const filteredMedia = (value !== null && value !== void 0 ? value : []).filter(item => { 68601 // If Item has id, only remove it if lastMediaPassed has an item with that id. 68602 if (item.id) { 68603 return !lastMediaPassed.some( 68604 // Be sure to convert to number for comparison. 68605 ({ 68606 id 68607 }) => Number(id) === Number(item.id)); 68608 } 68609 // Compare transient images via .includes since gallery may append extra info onto the url. 68610 return !lastMediaPassed.some(({ 68611 urlSlug 68612 }) => item.url.includes(urlSlug)); 68613 }); 68614 // Return the filtered media array along with newMedia. 68615 onSelect(filteredMedia.concat(newMedia)); 68616 // Reset lastMediaPassed and set it with ids and urls from newMedia. 68617 lastMediaPassed = newMedia.map(media => { 68618 // Add everything up to '.fileType' to compare via .includes. 68619 const cutOffIndex = media.url.lastIndexOf('.'); 68620 const urlSlug = media.url.slice(0, cutOffIndex); 68621 return { 68622 id: media.id, 68623 urlSlug 68624 }; 68625 }); 68626 }; 68627 } else { 68628 setMedia = onSelect; 68629 } 68630 } else { 68631 setMedia = ([media]) => onSelect(media); 68632 } 68633 mediaUpload({ 68634 allowedTypes, 68635 filesList: files, 68636 onFileChange: setMedia, 68637 onError, 68638 multiple 68639 }); 68640 }; 68641 async function handleBlocksDrop(event) { 68642 const { 68643 blocks 68644 } = parseDropEvent(event); 68645 if (!blocks?.length) { 68646 return; 68647 } 68648 const uploadedMediaList = await Promise.all(blocks.map(block => { 68649 const blockType = block.name.split('/')[1]; 68650 if (block.attributes.id) { 68651 block.attributes.type = blockType; 68652 return block.attributes; 68653 } 68654 return new Promise((resolve, reject) => { 68655 window.fetch(block.attributes.url).then(response => response.blob()).then(blob => mediaUpload({ 68656 filesList: [blob], 68657 additionalData: { 68658 title: block.attributes.title, 68659 alt_text: block.attributes.alt, 68660 caption: block.attributes.caption, 68661 type: blockType 68662 }, 68663 onFileChange: ([media]) => { 68664 if (media.id) { 68665 resolve(media); 68666 } 68667 }, 68668 allowedTypes, 68669 onError: reject 68670 })).catch(() => resolve(block.attributes.url)); 68671 }); 68672 })).catch(err => onError(err)); 68673 if (multiple) { 68674 onSelect(uploadedMediaList); 68675 } else { 68676 onSelect(uploadedMediaList[0]); 68677 } 68678 } 68679 const onUpload = event => { 68680 onFilesUpload(event.target.files); 68681 }; 68682 const defaultRenderPlaceholder = content => { 68683 let { 68684 instructions, 68685 title 68686 } = labels; 68687 if (!mediaUpload && !onSelectURL) { 68688 instructions = (0,external_wp_i18n_namespaceObject.__)('To edit this block, you need permission to upload media.'); 68689 } 68690 if (instructions === undefined || title === undefined) { 68691 const typesAllowed = allowedTypes !== null && allowedTypes !== void 0 ? allowedTypes : []; 68692 const [firstAllowedType] = typesAllowed; 68693 const isOneType = 1 === typesAllowed.length; 68694 const isAudio = isOneType && 'audio' === firstAllowedType; 68695 const isImage = isOneType && 'image' === firstAllowedType; 68696 const isVideo = isOneType && 'video' === firstAllowedType; 68697 if (instructions === undefined && mediaUpload) { 68698 instructions = (0,external_wp_i18n_namespaceObject.__)('Drag and drop an image or video, upload, or choose from your library.'); 68699 if (isAudio) { 68700 instructions = (0,external_wp_i18n_namespaceObject.__)('Drag and drop an audio file, upload, or choose from your library.'); 68701 } else if (isImage) { 68702 instructions = (0,external_wp_i18n_namespaceObject.__)('Drag and drop an image, upload, or choose from your library.'); 68703 } else if (isVideo) { 68704 instructions = (0,external_wp_i18n_namespaceObject.__)('Drag and drop a video, upload, or choose from your library.'); 68705 } 68706 } 68707 if (title === undefined) { 68708 title = (0,external_wp_i18n_namespaceObject.__)('Media'); 68709 if (isAudio) { 68710 title = (0,external_wp_i18n_namespaceObject.__)('Audio'); 68711 } else if (isImage) { 68712 title = (0,external_wp_i18n_namespaceObject.__)('Image'); 68713 } else if (isVideo) { 68714 title = (0,external_wp_i18n_namespaceObject.__)('Video'); 68715 } 68716 } 68717 } 68718 const placeholderClassName = dist_clsx('block-editor-media-placeholder', className, { 68719 'is-appender': isAppender 68720 }); 68721 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Placeholder, { 68722 icon: icon, 68723 label: title, 68724 instructions: instructions, 68725 className: placeholderClassName, 68726 notices: notices, 68727 onDoubleClick: onDoubleClick, 68728 preview: mediaPreview, 68729 style: style, 68730 children: [content, children] 68731 }); 68732 }; 68733 const renderPlaceholder = placeholder !== null && placeholder !== void 0 ? placeholder : defaultRenderPlaceholder; 68734 const renderDropZone = () => { 68735 if (disableDropZone) { 68736 return null; 68737 } 68738 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropZone, { 68739 onFilesDrop: onFilesUpload, 68740 onDrop: handleBlocksDrop, 68741 isEligible: dataTransfer => { 68742 const prefix = 'wp-block:core/'; 68743 const types = []; 68744 for (const type of dataTransfer.types) { 68745 if (type.startsWith(prefix)) { 68746 types.push(type.slice(prefix.length)); 68747 } 68748 } 68749 return types.every(type => allowedTypes.includes(type)) && (multiple ? true : types.length === 1); 68750 } 68751 }); 68752 }; 68753 const renderCancelLink = () => { 68754 return onCancel && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68755 __next40pxDefaultSize: true, 68756 className: "block-editor-media-placeholder__cancel-button", 68757 title: (0,external_wp_i18n_namespaceObject.__)('Cancel'), 68758 variant: "link", 68759 onClick: onCancel, 68760 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 68761 }); 68762 }; 68763 const renderUrlSelectionUI = () => { 68764 return onSelectURL && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(URLSelectionUI, { 68765 src: src, 68766 onChangeSrc: setSrc, 68767 onSelectURL: onSelectURL 68768 }); 68769 }; 68770 const renderFeaturedImageToggle = () => { 68771 return onToggleFeaturedImage && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 68772 className: "block-editor-media-placeholder__url-input-container", 68773 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68774 __next40pxDefaultSize: true, 68775 className: "block-editor-media-placeholder__button", 68776 onClick: onToggleFeaturedImage, 68777 variant: "secondary", 68778 children: (0,external_wp_i18n_namespaceObject.__)('Use featured image') 68779 }) 68780 }); 68781 }; 68782 const renderMediaUploadChecked = () => { 68783 const defaultButton = ({ 68784 open 68785 }) => { 68786 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68787 __next40pxDefaultSize: true, 68788 variant: "secondary", 68789 onClick: () => { 68790 open(); 68791 }, 68792 children: (0,external_wp_i18n_namespaceObject.__)('Media Library') 68793 }); 68794 }; 68795 const libraryButton = mediaLibraryButton !== null && mediaLibraryButton !== void 0 ? mediaLibraryButton : defaultButton; 68796 const uploadMediaLibraryButton = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(media_upload, { 68797 addToGallery: addToGallery, 68798 gallery: multiple && onlyAllowsImages(), 68799 multiple: multiple, 68800 onSelect: onSelect, 68801 allowedTypes: allowedTypes, 68802 mode: "browse", 68803 value: Array.isArray(value) ? value.map(({ 68804 id 68805 }) => id) : value.id, 68806 render: libraryButton 68807 }); 68808 if (mediaUpload && isAppender) { 68809 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 68810 children: [renderDropZone(), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FormFileUpload, { 68811 onChange: onUpload, 68812 accept: accept, 68813 multiple: !!multiple, 68814 render: ({ 68815 openFileDialog 68816 }) => { 68817 const content = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 68818 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68819 __next40pxDefaultSize: true, 68820 variant: "primary", 68821 className: dist_clsx('block-editor-media-placeholder__button', 'block-editor-media-placeholder__upload-button'), 68822 onClick: openFileDialog, 68823 children: (0,external_wp_i18n_namespaceObject._x)('Upload', 'verb') 68824 }), uploadMediaLibraryButton, renderUrlSelectionUI(), renderFeaturedImageToggle(), renderCancelLink()] 68825 }); 68826 return renderPlaceholder(content); 68827 } 68828 })] 68829 }); 68830 } 68831 if (mediaUpload) { 68832 const content = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 68833 children: [renderDropZone(), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FormFileUpload, { 68834 render: ({ 68835 openFileDialog 68836 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 68837 __next40pxDefaultSize: true, 68838 onClick: openFileDialog, 68839 variant: "primary", 68840 className: dist_clsx('block-editor-media-placeholder__button', 'block-editor-media-placeholder__upload-button'), 68841 children: (0,external_wp_i18n_namespaceObject._x)('Upload', 'verb') 68842 }), 68843 onChange: onUpload, 68844 accept: accept, 68845 multiple: !!multiple 68846 }), uploadMediaLibraryButton, renderUrlSelectionUI(), renderFeaturedImageToggle(), renderCancelLink()] 68847 }); 68848 return renderPlaceholder(content); 68849 } 68850 return renderPlaceholder(uploadMediaLibraryButton); 68851 }; 68852 if (disableMediaButtons) { 68853 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(check, { 68854 children: renderDropZone() 68855 }); 68856 } 68857 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(check, { 68858 fallback: renderPlaceholder(renderUrlSelectionUI()), 68859 children: renderMediaUploadChecked() 68860 }); 68861 } 68862 68863 /** 68864 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-placeholder/README.md 68865 */ 68866 /* harmony default export */ const media_placeholder = ((0,external_wp_components_namespaceObject.withFilters)('editor.MediaPlaceholder')(MediaPlaceholder)); 68867 68868 ;// ./node_modules/@wordpress/block-editor/build-module/components/panel-color-settings/index.js 68869 /** 68870 * Internal dependencies 68871 */ 68872 68873 68874 const PanelColorSettings = ({ 68875 colorSettings, 68876 ...props 68877 }) => { 68878 const settings = colorSettings.map(setting => { 68879 if (!setting) { 68880 return setting; 68881 } 68882 const { 68883 value, 68884 onChange, 68885 ...otherSettings 68886 } = setting; 68887 return { 68888 ...otherSettings, 68889 colorValue: value, 68890 onColorChange: onChange 68891 }; 68892 }); 68893 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(panel_color_gradient_settings, { 68894 settings: settings, 68895 gradients: [], 68896 disableCustomGradients: true, 68897 ...props 68898 }); 68899 }; 68900 /* harmony default export */ const panel_color_settings = (PanelColorSettings); 68901 68902 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/format-toolbar/index.js 68903 /** 68904 * External dependencies 68905 */ 68906 68907 68908 /** 68909 * WordPress dependencies 68910 */ 68911 68912 68913 68914 68915 /** 68916 * Internal dependencies 68917 */ 68918 68919 68920 const format_toolbar_POPOVER_PROPS = { 68921 placement: 'bottom-start' 68922 }; 68923 const FormatToolbar = () => { 68924 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 68925 children: [['bold', 'italic', 'link', 'unknown'].map(format => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Slot, { 68926 name: `RichText.ToolbarControls.$format}` 68927 }, format)), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Slot, { 68928 name: "RichText.ToolbarControls", 68929 children: fills => { 68930 if (!fills.length) { 68931 return null; 68932 } 68933 const allProps = fills.map(([{ 68934 props 68935 }]) => props); 68936 const hasActive = allProps.some(({ 68937 isActive 68938 }) => isActive); 68939 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarItem, { 68940 children: toggleProps => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.DropdownMenu, { 68941 icon: chevron_down 68942 /* translators: button label text should, if possible, be under 16 characters. */, 68943 label: (0,external_wp_i18n_namespaceObject.__)('More'), 68944 toggleProps: { 68945 ...toggleProps, 68946 className: dist_clsx(toggleProps.className, { 68947 'is-pressed': hasActive 68948 }), 68949 description: (0,external_wp_i18n_namespaceObject.__)('Displays more block tools') 68950 }, 68951 controls: orderBy(fills.map(([{ 68952 props 68953 }]) => props), 'title'), 68954 popoverProps: format_toolbar_POPOVER_PROPS 68955 }) 68956 }); 68957 } 68958 })] 68959 }); 68960 }; 68961 /* harmony default export */ const format_toolbar = (FormatToolbar); 68962 68963 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/format-toolbar-container.js 68964 /** 68965 * WordPress dependencies 68966 */ 68967 68968 68969 68970 /** 68971 * Internal dependencies 68972 */ 68973 68974 68975 68976 68977 function InlineToolbar({ 68978 popoverAnchor 68979 }) { 68980 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Popover, { 68981 placement: "top", 68982 focusOnMount: false, 68983 anchor: popoverAnchor, 68984 className: "block-editor-rich-text__inline-format-toolbar", 68985 __unstableSlotName: "block-toolbar", 68986 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(NavigableToolbar, { 68987 className: "block-editor-rich-text__inline-format-toolbar-group" 68988 /* translators: accessibility text for the inline format toolbar */, 68989 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Format tools'), 68990 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, { 68991 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(format_toolbar, {}) 68992 }) 68993 }) 68994 }); 68995 } 68996 const FormatToolbarContainer = ({ 68997 inline, 68998 editableContentElement 68999 }) => { 69000 if (inline) { 69001 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InlineToolbar, { 69002 popoverAnchor: editableContentElement 69003 }); 69004 } 69005 69006 // Render regular toolbar. 69007 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_controls, { 69008 group: "inline", 69009 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(format_toolbar, {}) 69010 }); 69011 }; 69012 /* harmony default export */ const format_toolbar_container = (FormatToolbarContainer); 69013 69014 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-mark-persistent.js 69015 /** 69016 * WordPress dependencies 69017 */ 69018 69019 69020 69021 /** 69022 * Internal dependencies 69023 */ 69024 69025 function useMarkPersistent({ 69026 html, 69027 value 69028 }) { 69029 const previousTextRef = (0,external_wp_element_namespaceObject.useRef)(); 69030 const hasActiveFormats = !!value.activeFormats?.length; 69031 const { 69032 __unstableMarkLastChangeAsPersistent 69033 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 69034 69035 // Must be set synchronously to make sure it applies to the last change. 69036 (0,external_wp_element_namespaceObject.useLayoutEffect)(() => { 69037 // Ignore mount. 69038 if (!previousTextRef.current) { 69039 previousTextRef.current = value.text; 69040 return; 69041 } 69042 69043 // Text input, so don't create an undo level for every character. 69044 // Create an undo level after 1 second of no input. 69045 if (previousTextRef.current !== value.text) { 69046 const timeout = window.setTimeout(() => { 69047 __unstableMarkLastChangeAsPersistent(); 69048 }, 1000); 69049 previousTextRef.current = value.text; 69050 return () => { 69051 window.clearTimeout(timeout); 69052 }; 69053 } 69054 __unstableMarkLastChangeAsPersistent(); 69055 }, [html, hasActiveFormats]); 69056 } 69057 69058 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/use-format-types.js 69059 /** 69060 * WordPress dependencies 69061 */ 69062 69063 69064 69065 function formatTypesSelector(select) { 69066 return select(external_wp_richText_namespaceObject.store).getFormatTypes(); 69067 } 69068 69069 /** 69070 * Set of all interactive content tags. 69071 * 69072 * @see https://html.spec.whatwg.org/multipage/dom.html#interactive-content 69073 */ 69074 const interactiveContentTags = new Set(['a', 'audio', 'button', 'details', 'embed', 'iframe', 'input', 'label', 'select', 'textarea', 'video']); 69075 function prefixSelectKeys(selected, prefix) { 69076 if (typeof selected !== 'object') { 69077 return { 69078 [prefix]: selected 69079 }; 69080 } 69081 return Object.fromEntries(Object.entries(selected).map(([key, value]) => [`$prefix}.$key}`, value])); 69082 } 69083 function getPrefixedSelectKeys(selected, prefix) { 69084 if (selected[prefix]) { 69085 return selected[prefix]; 69086 } 69087 return Object.keys(selected).filter(key => key.startsWith(prefix + '.')).reduce((accumulator, key) => { 69088 accumulator[key.slice(prefix.length + 1)] = selected[key]; 69089 return accumulator; 69090 }, {}); 69091 } 69092 69093 /** 69094 * This hook provides RichText with the `formatTypes` and its derived props from 69095 * experimental format type settings. 69096 * 69097 * @param {Object} $0 Options 69098 * @param {string} $0.clientId Block client ID. 69099 * @param {string} $0.identifier Block attribute. 69100 * @param {boolean} $0.withoutInteractiveFormatting Whether to clean the interactive formatting or not. 69101 * @param {Array} $0.allowedFormats Allowed formats 69102 */ 69103 function useFormatTypes({ 69104 clientId, 69105 identifier, 69106 withoutInteractiveFormatting, 69107 allowedFormats 69108 }) { 69109 const allFormatTypes = (0,external_wp_data_namespaceObject.useSelect)(formatTypesSelector, []); 69110 const formatTypes = (0,external_wp_element_namespaceObject.useMemo)(() => { 69111 return allFormatTypes.filter(({ 69112 name, 69113 interactive, 69114 tagName 69115 }) => { 69116 if (allowedFormats && !allowedFormats.includes(name)) { 69117 return false; 69118 } 69119 if (withoutInteractiveFormatting && (interactive || interactiveContentTags.has(tagName))) { 69120 return false; 69121 } 69122 return true; 69123 }); 69124 }, [allFormatTypes, allowedFormats, withoutInteractiveFormatting]); 69125 const keyedSelected = (0,external_wp_data_namespaceObject.useSelect)(select => formatTypes.reduce((accumulator, type) => { 69126 if (!type.__experimentalGetPropsForEditableTreePreparation) { 69127 return accumulator; 69128 } 69129 return { 69130 ...accumulator, 69131 ...prefixSelectKeys(type.__experimentalGetPropsForEditableTreePreparation(select, { 69132 richTextIdentifier: identifier, 69133 blockClientId: clientId 69134 }), type.name) 69135 }; 69136 }, {}), [formatTypes, clientId, identifier]); 69137 const dispatch = (0,external_wp_data_namespaceObject.useDispatch)(); 69138 const prepareHandlers = []; 69139 const valueHandlers = []; 69140 const changeHandlers = []; 69141 const dependencies = []; 69142 for (const key in keyedSelected) { 69143 dependencies.push(keyedSelected[key]); 69144 } 69145 formatTypes.forEach(type => { 69146 if (type.__experimentalCreatePrepareEditableTree) { 69147 const handler = type.__experimentalCreatePrepareEditableTree(getPrefixedSelectKeys(keyedSelected, type.name), { 69148 richTextIdentifier: identifier, 69149 blockClientId: clientId 69150 }); 69151 if (type.__experimentalCreateOnChangeEditableValue) { 69152 valueHandlers.push(handler); 69153 } else { 69154 prepareHandlers.push(handler); 69155 } 69156 } 69157 if (type.__experimentalCreateOnChangeEditableValue) { 69158 let dispatchers = {}; 69159 if (type.__experimentalGetPropsForEditableTreeChangeHandler) { 69160 dispatchers = type.__experimentalGetPropsForEditableTreeChangeHandler(dispatch, { 69161 richTextIdentifier: identifier, 69162 blockClientId: clientId 69163 }); 69164 } 69165 const selected = getPrefixedSelectKeys(keyedSelected, type.name); 69166 changeHandlers.push(type.__experimentalCreateOnChangeEditableValue({ 69167 ...(typeof selected === 'object' ? selected : {}), 69168 ...dispatchers 69169 }, { 69170 richTextIdentifier: identifier, 69171 blockClientId: clientId 69172 })); 69173 } 69174 }); 69175 return { 69176 formatTypes, 69177 prepareHandlers, 69178 valueHandlers, 69179 changeHandlers, 69180 dependencies 69181 }; 69182 } 69183 69184 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/before-input-rules.js 69185 /** 69186 * WordPress dependencies 69187 */ 69188 69189 69190 69191 /** 69192 * Internal dependencies 69193 */ 69194 69195 69196 /** 69197 * When typing over a selection, the selection will we wrapped by a matching 69198 * character pair. The second character is optional, it defaults to the first 69199 * character. 69200 * 69201 * @type {string[]} Array of character pairs. 69202 */ 69203 const wrapSelectionSettings = ['`', '"', "'", '“”', '‘’']; 69204 /* harmony default export */ const before_input_rules = (props => element => { 69205 function onInput(event) { 69206 const { 69207 inputType, 69208 data 69209 } = event; 69210 const { 69211 value, 69212 onChange, 69213 registry 69214 } = props.current; 69215 69216 // Only run the rules when inserting text. 69217 if (inputType !== 'insertText') { 69218 return; 69219 } 69220 if ((0,external_wp_richText_namespaceObject.isCollapsed)(value)) { 69221 return; 69222 } 69223 const pair = (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.wrapSelectionSettings', wrapSelectionSettings).find(([startChar, endChar]) => startChar === data || endChar === data); 69224 if (!pair) { 69225 return; 69226 } 69227 const [startChar, endChar = startChar] = pair; 69228 const start = value.start; 69229 const end = value.end + startChar.length; 69230 let newValue = (0,external_wp_richText_namespaceObject.insert)(value, startChar, start, start); 69231 newValue = (0,external_wp_richText_namespaceObject.insert)(newValue, endChar, end, end); 69232 const { 69233 __unstableMarkLastChangeAsPersistent, 69234 __unstableMarkAutomaticChange 69235 } = registry.dispatch(store); 69236 __unstableMarkLastChangeAsPersistent(); 69237 onChange(newValue); 69238 __unstableMarkAutomaticChange(); 69239 const init = {}; 69240 for (const key in event) { 69241 init[key] = event[key]; 69242 } 69243 init.data = endChar; 69244 const { 69245 ownerDocument 69246 } = element; 69247 const { 69248 defaultView 69249 } = ownerDocument; 69250 const newEvent = new defaultView.InputEvent('input', init); 69251 69252 // Dispatch an `input` event with the new data. This will trigger the 69253 // input rules. 69254 // Postpone the `input` to the next event loop tick so that the dispatch 69255 // doesn't happen synchronously in the middle of `beforeinput` dispatch. 69256 // This is closer to how native `input` event would be timed, and also 69257 // makes sure that the `input` event is dispatched only after the `onChange` 69258 // call few lines above has fully updated the data store state and rerendered 69259 // all affected components. 69260 window.queueMicrotask(() => { 69261 event.target.dispatchEvent(newEvent); 69262 }); 69263 event.preventDefault(); 69264 } 69265 element.addEventListener('beforeinput', onInput); 69266 return () => { 69267 element.removeEventListener('beforeinput', onInput); 69268 }; 69269 }); 69270 69271 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/prevent-event-discovery.js 69272 /** 69273 * WordPress dependencies 69274 */ 69275 69276 function preventEventDiscovery(value) { 69277 const searchText = 'tales of gutenberg'; 69278 const addText = ' 🐡🐢🦀🐤🦋🐘🐧🐹🦁🦄🦍🐼🐿🎃🐴🐝🐆🦕🦔🌱🍇π🍌🐉💧🥨🌌🍂🍠🥦🥚🥝🎟🥥🥒🛵🥖🍒🍯🎾🎲🐺🐚🐮⌛️'; 69279 const { 69280 start, 69281 text 69282 } = value; 69283 if (start < searchText.length) { 69284 return value; 69285 } 69286 const charactersBefore = text.slice(start - searchText.length, start); 69287 if (charactersBefore.toLowerCase() !== searchText) { 69288 return value; 69289 } 69290 return (0,external_wp_richText_namespaceObject.insert)(value, addText); 69291 } 69292 69293 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/input-rules.js 69294 /** 69295 * WordPress dependencies 69296 */ 69297 69298 69299 69300 /** 69301 * Internal dependencies 69302 */ 69303 69304 69305 69306 function findSelection(blocks) { 69307 let i = blocks.length; 69308 while (i--) { 69309 const attributeKey = retrieveSelectedAttribute(blocks[i].attributes); 69310 if (attributeKey) { 69311 blocks[i].attributes[attributeKey] = blocks[i].attributes[attributeKey] 69312 // To do: refactor this to use rich text's selection instead, so 69313 // we no longer have to use on this hack inserting a special 69314 // character. 69315 .toString().replace(START_OF_SELECTED_AREA, ''); 69316 return [blocks[i].clientId, attributeKey, 0, 0]; 69317 } 69318 const nestedSelection = findSelection(blocks[i].innerBlocks); 69319 if (nestedSelection) { 69320 return nestedSelection; 69321 } 69322 } 69323 return []; 69324 } 69325 /* harmony default export */ const input_rules = (props => element => { 69326 function inputRule() { 69327 const { 69328 getValue, 69329 onReplace, 69330 selectionChange, 69331 registry 69332 } = props.current; 69333 if (!onReplace) { 69334 return; 69335 } 69336 69337 // We must use getValue() here because value may be update 69338 // asynchronously. 69339 const value = getValue(); 69340 const { 69341 start, 69342 text 69343 } = value; 69344 const characterBefore = text.slice(start - 1, start); 69345 69346 // The character right before the caret must be a plain space. 69347 if (characterBefore !== ' ') { 69348 return; 69349 } 69350 const trimmedTextBefore = text.slice(0, start).trim(); 69351 const prefixTransforms = (0,external_wp_blocks_namespaceObject.getBlockTransforms)('from').filter(({ 69352 type 69353 }) => type === 'prefix'); 69354 const transformation = (0,external_wp_blocks_namespaceObject.findTransform)(prefixTransforms, ({ 69355 prefix 69356 }) => { 69357 return trimmedTextBefore === prefix; 69358 }); 69359 if (!transformation) { 69360 return; 69361 } 69362 const content = (0,external_wp_richText_namespaceObject.toHTMLString)({ 69363 value: (0,external_wp_richText_namespaceObject.insert)(value, START_OF_SELECTED_AREA, 0, start) 69364 }); 69365 const block = transformation.transform(content); 69366 selectionChange(...findSelection([block])); 69367 onReplace([block]); 69368 registry.dispatch(store).__unstableMarkAutomaticChange(); 69369 return true; 69370 } 69371 function onInput(event) { 69372 const { 69373 inputType, 69374 type 69375 } = event; 69376 const { 69377 getValue, 69378 onChange, 69379 __unstableAllowPrefixTransformations, 69380 formatTypes, 69381 registry 69382 } = props.current; 69383 69384 // Only run input rules when inserting text. 69385 if (inputType !== 'insertText' && type !== 'compositionend') { 69386 return; 69387 } 69388 if (__unstableAllowPrefixTransformations && inputRule()) { 69389 return; 69390 } 69391 const value = getValue(); 69392 const transformed = formatTypes.reduce((accumulator, { 69393 __unstableInputRule 69394 }) => { 69395 if (__unstableInputRule) { 69396 accumulator = __unstableInputRule(accumulator); 69397 } 69398 return accumulator; 69399 }, preventEventDiscovery(value)); 69400 const { 69401 __unstableMarkLastChangeAsPersistent, 69402 __unstableMarkAutomaticChange 69403 } = registry.dispatch(store); 69404 if (transformed !== value) { 69405 __unstableMarkLastChangeAsPersistent(); 69406 onChange({ 69407 ...transformed, 69408 activeFormats: value.activeFormats 69409 }); 69410 __unstableMarkAutomaticChange(); 69411 } 69412 } 69413 element.addEventListener('input', onInput); 69414 element.addEventListener('compositionend', onInput); 69415 return () => { 69416 element.removeEventListener('input', onInput); 69417 element.removeEventListener('compositionend', onInput); 69418 }; 69419 }); 69420 69421 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/insert-replacement-text.js 69422 /** 69423 * Internal dependencies 69424 */ 69425 69426 69427 /** 69428 * When the browser is about to auto correct, add an undo level so the user can 69429 * revert the change. 69430 * 69431 * @param {Object} props 69432 */ 69433 /* harmony default export */ const insert_replacement_text = (props => element => { 69434 function onInput(event) { 69435 if (event.inputType !== 'insertReplacementText') { 69436 return; 69437 } 69438 const { 69439 registry 69440 } = props.current; 69441 registry.dispatch(store).__unstableMarkLastChangeAsPersistent(); 69442 } 69443 element.addEventListener('beforeinput', onInput); 69444 return () => { 69445 element.removeEventListener('beforeinput', onInput); 69446 }; 69447 }); 69448 69449 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/remove-browser-shortcuts.js 69450 /** 69451 * WordPress dependencies 69452 */ 69453 69454 69455 /** 69456 * Hook to prevent default behaviors for key combinations otherwise handled 69457 * internally by RichText. 69458 */ 69459 /* harmony default export */ const remove_browser_shortcuts = (() => node => { 69460 function onKeydown(event) { 69461 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')) { 69462 event.preventDefault(); 69463 } 69464 } 69465 node.addEventListener('keydown', onKeydown); 69466 return () => { 69467 node.removeEventListener('keydown', onKeydown); 69468 }; 69469 }); 69470 69471 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/shortcuts.js 69472 /* harmony default export */ const shortcuts = (props => element => { 69473 const { 69474 keyboardShortcuts 69475 } = props.current; 69476 function onKeyDown(event) { 69477 for (const keyboardShortcut of keyboardShortcuts.current) { 69478 keyboardShortcut(event); 69479 } 69480 } 69481 element.addEventListener('keydown', onKeyDown); 69482 return () => { 69483 element.removeEventListener('keydown', onKeyDown); 69484 }; 69485 }); 69486 69487 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/input-events.js 69488 /* harmony default export */ const input_events = (props => element => { 69489 const { 69490 inputEvents 69491 } = props.current; 69492 function onInput(event) { 69493 for (const keyboardShortcut of inputEvents.current) { 69494 keyboardShortcut(event); 69495 } 69496 } 69497 element.addEventListener('input', onInput); 69498 return () => { 69499 element.removeEventListener('input', onInput); 69500 }; 69501 }); 69502 69503 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/undo-automatic-change.js 69504 /** 69505 * WordPress dependencies 69506 */ 69507 69508 69509 /** 69510 * Internal dependencies 69511 */ 69512 69513 /* harmony default export */ const undo_automatic_change = (props => element => { 69514 function onKeyDown(event) { 69515 const { 69516 keyCode 69517 } = event; 69518 if (event.defaultPrevented) { 69519 return; 69520 } 69521 if (keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE && keyCode !== external_wp_keycodes_namespaceObject.ESCAPE) { 69522 return; 69523 } 69524 const { 69525 registry 69526 } = props.current; 69527 const { 69528 didAutomaticChange, 69529 getSettings 69530 } = registry.select(store); 69531 const { 69532 __experimentalUndo 69533 } = getSettings(); 69534 if (!__experimentalUndo) { 69535 return; 69536 } 69537 if (!didAutomaticChange()) { 69538 return; 69539 } 69540 event.preventDefault(); 69541 __experimentalUndo(); 69542 } 69543 element.addEventListener('keydown', onKeyDown); 69544 return () => { 69545 element.removeEventListener('keydown', onKeyDown); 69546 }; 69547 }); 69548 69549 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/utils.js 69550 /** 69551 * WordPress dependencies 69552 */ 69553 69554 69555 69556 function addActiveFormats(value, activeFormats) { 69557 if (activeFormats?.length) { 69558 let index = value.formats.length; 69559 while (index--) { 69560 value.formats[index] = [...activeFormats, ...(value.formats[index] || [])]; 69561 } 69562 } 69563 } 69564 69565 /** 69566 * Get the multiline tag based on the multiline prop. 69567 * 69568 * @param {?(string|boolean)} multiline The multiline prop. 69569 * 69570 * @return {string | undefined} The multiline tag. 69571 */ 69572 function getMultilineTag(multiline) { 69573 if (multiline !== true && multiline !== 'p' && multiline !== 'li') { 69574 return; 69575 } 69576 return multiline === true ? 'p' : multiline; 69577 } 69578 function getAllowedFormats({ 69579 allowedFormats, 69580 disableFormats 69581 }) { 69582 if (disableFormats) { 69583 return getAllowedFormats.EMPTY_ARRAY; 69584 } 69585 return allowedFormats; 69586 } 69587 getAllowedFormats.EMPTY_ARRAY = []; 69588 69589 /** 69590 * Creates a link from pasted URL. 69591 * Creates a paragraph block containing a link to the URL, and calls `onReplace`. 69592 * 69593 * @param {string} url The URL that could not be embedded. 69594 * @param {Function} onReplace Function to call with the created fallback block. 69595 */ 69596 function createLinkInParagraph(url, onReplace) { 69597 const link = /*#__PURE__*/_jsx("a", { 69598 href: url, 69599 children: url 69600 }); 69601 onReplace(createBlock('core/paragraph', { 69602 content: renderToString(link) 69603 })); 69604 } 69605 69606 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/paste-handler.js 69607 /** 69608 * WordPress dependencies 69609 */ 69610 69611 69612 69613 69614 /** 69615 * Internal dependencies 69616 */ 69617 69618 69619 69620 /** @typedef {import('@wordpress/rich-text').RichTextValue} RichTextValue */ 69621 69622 /* harmony default export */ const paste_handler = (props => element => { 69623 function _onPaste(event) { 69624 const { 69625 disableFormats, 69626 onChange, 69627 value, 69628 formatTypes, 69629 tagName, 69630 onReplace, 69631 __unstableEmbedURLOnPaste, 69632 preserveWhiteSpace, 69633 pastePlainText 69634 } = props.current; 69635 69636 // The event listener is attached to the window, so we need to check if 69637 // the target is the element or inside the element. 69638 if (!element.contains(event.target)) { 69639 return; 69640 } 69641 if (event.defaultPrevented) { 69642 return; 69643 } 69644 const { 69645 plainText, 69646 html 69647 } = getPasteEventData(event); 69648 event.preventDefault(); 69649 69650 // Allows us to ask for this information when we get a report. 69651 window.console.log('Received HTML:\n\n', html); 69652 window.console.log('Received plain text:\n\n', plainText); 69653 if (disableFormats) { 69654 onChange((0,external_wp_richText_namespaceObject.insert)(value, plainText)); 69655 return; 69656 } 69657 const isInternal = event.clipboardData.getData('rich-text') === 'true'; 69658 function pasteInline(content) { 69659 const transformed = formatTypes.reduce((accumulator, { 69660 __unstablePasteRule 69661 }) => { 69662 // Only allow one transform. 69663 if (__unstablePasteRule && accumulator === value) { 69664 accumulator = __unstablePasteRule(value, { 69665 html, 69666 plainText 69667 }); 69668 } 69669 return accumulator; 69670 }, value); 69671 if (transformed !== value) { 69672 onChange(transformed); 69673 } else { 69674 const valueToInsert = (0,external_wp_richText_namespaceObject.create)({ 69675 html: content 69676 }); 69677 addActiveFormats(valueToInsert, value.activeFormats); 69678 onChange((0,external_wp_richText_namespaceObject.insert)(value, valueToInsert)); 69679 } 69680 } 69681 69682 // If the data comes from a rich text instance, we can directly use it 69683 // without filtering the data. The filters are only meant for externally 69684 // pasted content and remove inline styles. 69685 if (isInternal) { 69686 pasteInline(html); 69687 return; 69688 } 69689 if (pastePlainText) { 69690 onChange((0,external_wp_richText_namespaceObject.insert)(value, (0,external_wp_richText_namespaceObject.create)({ 69691 text: plainText 69692 }))); 69693 return; 69694 } 69695 let mode = 'INLINE'; 69696 const trimmedPlainText = plainText.trim(); 69697 if (__unstableEmbedURLOnPaste && (0,external_wp_richText_namespaceObject.isEmpty)(value) && (0,external_wp_url_namespaceObject.isURL)(trimmedPlainText) && 69698 // For the link pasting feature, allow only http(s) protocols. 69699 /^https?:/.test(trimmedPlainText)) { 69700 mode = 'BLOCKS'; 69701 } 69702 const content = (0,external_wp_blocks_namespaceObject.pasteHandler)({ 69703 HTML: html, 69704 plainText, 69705 mode, 69706 tagName, 69707 preserveWhiteSpace 69708 }); 69709 if (typeof content === 'string') { 69710 pasteInline(content); 69711 } else if (content.length > 0) { 69712 if (onReplace && (0,external_wp_richText_namespaceObject.isEmpty)(value)) { 69713 onReplace(content, content.length - 1, -1); 69714 } 69715 } 69716 } 69717 const { 69718 defaultView 69719 } = element.ownerDocument; 69720 69721 // Attach the listener to the window so parent elements have the chance to 69722 // prevent the default behavior. 69723 defaultView.addEventListener('paste', _onPaste); 69724 return () => { 69725 defaultView.removeEventListener('paste', _onPaste); 69726 }; 69727 }); 69728 69729 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/delete.js 69730 /** 69731 * WordPress dependencies 69732 */ 69733 69734 69735 /* harmony default export */ const event_listeners_delete = (props => element => { 69736 function onKeyDown(event) { 69737 const { 69738 keyCode, 69739 shiftKey, 69740 ctrlKey, 69741 metaKey 69742 } = event; 69743 if (event.defaultPrevented) { 69744 return; 69745 } 69746 const { 69747 value, 69748 onMerge, 69749 onRemove 69750 } = props.current; 69751 if (keyCode === external_wp_keycodes_namespaceObject.DELETE || keyCode === external_wp_keycodes_namespaceObject.BACKSPACE) { 69752 const { 69753 start, 69754 end, 69755 text 69756 } = value; 69757 const isReverse = keyCode === external_wp_keycodes_namespaceObject.BACKSPACE; 69758 const hasActiveFormats = value.activeFormats && !!value.activeFormats.length; 69759 69760 // Only process delete if the key press occurs at an uncollapsed edge. 69761 if (!(0,external_wp_richText_namespaceObject.isCollapsed)(value) || hasActiveFormats || isReverse && start !== 0 || !isReverse && end !== text.length) { 69762 return; 69763 } 69764 69765 // Exclude (command|ctrl)+shift+backspace as they are shortcuts for deleting blocks. 69766 if (shiftKey && (ctrlKey || metaKey)) { 69767 return; 69768 } 69769 if (onMerge) { 69770 onMerge(!isReverse); 69771 } 69772 69773 // Only handle remove on Backspace. This serves dual-purpose of being 69774 // an intentional user interaction distinguishing between Backspace and 69775 // Delete to remove the empty field, but also to avoid merge & remove 69776 // causing destruction of two fields (merge, then removed merged). 69777 else if (onRemove && (0,external_wp_richText_namespaceObject.isEmpty)(value) && isReverse) { 69778 onRemove(!isReverse); 69779 } 69780 event.preventDefault(); 69781 } 69782 } 69783 element.addEventListener('keydown', onKeyDown); 69784 return () => { 69785 element.removeEventListener('keydown', onKeyDown); 69786 }; 69787 }); 69788 69789 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/enter.js 69790 /** 69791 * WordPress dependencies 69792 */ 69793 69794 69795 /* harmony default export */ const enter = (props => element => { 69796 function onKeyDownDeprecated(event) { 69797 if (event.keyCode !== external_wp_keycodes_namespaceObject.ENTER) { 69798 return; 69799 } 69800 const { 69801 onReplace, 69802 onSplit 69803 } = props.current; 69804 if (onReplace && onSplit) { 69805 event.__deprecatedOnSplit = true; 69806 } 69807 } 69808 function onKeyDown(event) { 69809 if (event.defaultPrevented) { 69810 return; 69811 } 69812 69813 // The event listener is attached to the window, so we need to check if 69814 // the target is the element. 69815 if (event.target !== element) { 69816 return; 69817 } 69818 if (event.keyCode !== external_wp_keycodes_namespaceObject.ENTER) { 69819 return; 69820 } 69821 const { 69822 value, 69823 onChange, 69824 disableLineBreaks, 69825 onSplitAtEnd, 69826 onSplitAtDoubleLineEnd, 69827 registry 69828 } = props.current; 69829 event.preventDefault(); 69830 const { 69831 text, 69832 start, 69833 end 69834 } = value; 69835 if (event.shiftKey) { 69836 if (!disableLineBreaks) { 69837 onChange((0,external_wp_richText_namespaceObject.insert)(value, '\n')); 69838 } 69839 } else if (onSplitAtEnd && start === end && end === text.length) { 69840 onSplitAtEnd(); 69841 } else if ( 69842 // For some blocks it's desirable to split at the end of the 69843 // block when there are two line breaks at the end of the 69844 // block, so triple Enter exits the block. 69845 onSplitAtDoubleLineEnd && start === end && end === text.length && text.slice(-2) === '\n\n') { 69846 registry.batch(() => { 69847 const _value = { 69848 ...value 69849 }; 69850 _value.start = _value.end - 2; 69851 onChange((0,external_wp_richText_namespaceObject.remove)(_value)); 69852 onSplitAtDoubleLineEnd(); 69853 }); 69854 } else if (!disableLineBreaks) { 69855 onChange((0,external_wp_richText_namespaceObject.insert)(value, '\n')); 69856 } 69857 } 69858 const { 69859 defaultView 69860 } = element.ownerDocument; 69861 69862 // Attach the listener to the window so parent elements have the chance to 69863 // prevent the default behavior. 69864 defaultView.addEventListener('keydown', onKeyDown); 69865 element.addEventListener('keydown', onKeyDownDeprecated); 69866 return () => { 69867 defaultView.removeEventListener('keydown', onKeyDown); 69868 element.removeEventListener('keydown', onKeyDownDeprecated); 69869 }; 69870 }); 69871 69872 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/firefox-compat.js 69873 /** 69874 * Internal dependencies 69875 */ 69876 69877 /* harmony default export */ const firefox_compat = (props => element => { 69878 function onFocus() { 69879 const { 69880 registry 69881 } = props.current; 69882 if (!registry.select(store).isMultiSelecting()) { 69883 return; 69884 } 69885 69886 // This is a little hack to work around focus issues with nested 69887 // editable elements in Firefox. For some reason the editable child 69888 // element sometimes regains focus, while it should not be focusable 69889 // and focus should remain on the editable parent element. 69890 // To do: try to find the cause of the shifting focus. 69891 const parentEditable = element.parentElement.closest('[contenteditable="true"]'); 69892 if (parentEditable) { 69893 parentEditable.focus(); 69894 } 69895 } 69896 element.addEventListener('focus', onFocus); 69897 return () => { 69898 element.removeEventListener('focus', onFocus); 69899 }; 69900 }); 69901 69902 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/event-listeners/index.js 69903 /** 69904 * WordPress dependencies 69905 */ 69906 69907 69908 69909 /** 69910 * Internal dependencies 69911 */ 69912 69913 69914 69915 69916 69917 69918 69919 69920 69921 69922 69923 const allEventListeners = [before_input_rules, input_rules, insert_replacement_text, remove_browser_shortcuts, shortcuts, input_events, undo_automatic_change, paste_handler, event_listeners_delete, enter, firefox_compat]; 69924 function useEventListeners(props) { 69925 const propsRef = (0,external_wp_element_namespaceObject.useRef)(props); 69926 (0,external_wp_element_namespaceObject.useInsertionEffect)(() => { 69927 propsRef.current = props; 69928 }); 69929 const refEffects = (0,external_wp_element_namespaceObject.useMemo)(() => allEventListeners.map(refEffect => refEffect(propsRef)), [propsRef]); 69930 return (0,external_wp_compose_namespaceObject.useRefEffect)(element => { 69931 if (!props.isSelected) { 69932 return; 69933 } 69934 const cleanups = refEffects.map(effect => effect(element)); 69935 return () => { 69936 cleanups.forEach(cleanup => cleanup()); 69937 }; 69938 }, [refEffects, props.isSelected]); 69939 } 69940 69941 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/format-edit.js 69942 /** 69943 * WordPress dependencies 69944 */ 69945 69946 69947 69948 /** 69949 * Internal dependencies 69950 */ 69951 69952 69953 69954 const format_edit_DEFAULT_BLOCK_CONTEXT = {}; 69955 const usesContextKey = Symbol('usesContext'); 69956 function format_edit_Edit({ 69957 onChange, 69958 onFocus, 69959 value, 69960 forwardedRef, 69961 settings 69962 }) { 69963 const { 69964 name, 69965 edit: EditFunction, 69966 [usesContextKey]: usesContext 69967 } = settings; 69968 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 69969 69970 // Assign context values using the block type's declared context needs. 69971 const context = (0,external_wp_element_namespaceObject.useMemo)(() => { 69972 return usesContext ? Object.fromEntries(Object.entries(blockContext).filter(([key]) => usesContext.includes(key))) : format_edit_DEFAULT_BLOCK_CONTEXT; 69973 }, [usesContext, blockContext]); 69974 if (!EditFunction) { 69975 return null; 69976 } 69977 const activeFormat = (0,external_wp_richText_namespaceObject.getActiveFormat)(value, name); 69978 const isActive = activeFormat !== undefined; 69979 const activeObject = (0,external_wp_richText_namespaceObject.getActiveObject)(value); 69980 const isObjectActive = activeObject !== undefined && activeObject.type === name; 69981 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(EditFunction, { 69982 isActive: isActive, 69983 activeAttributes: isActive ? activeFormat.attributes || {} : {}, 69984 isObjectActive: isObjectActive, 69985 activeObjectAttributes: isObjectActive ? activeObject.attributes || {} : {}, 69986 value: value, 69987 onChange: onChange, 69988 onFocus: onFocus, 69989 contentRef: forwardedRef, 69990 context: context 69991 }, name); 69992 } 69993 function FormatEdit({ 69994 formatTypes, 69995 ...props 69996 }) { 69997 return formatTypes.map(settings => /*#__PURE__*/(0,external_React_.createElement)(format_edit_Edit, { 69998 settings: settings, 69999 ...props, 70000 key: settings.name 70001 })); 70002 } 70003 70004 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/content.js 70005 /** 70006 * WordPress dependencies 70007 */ 70008 70009 70010 70011 70012 /** 70013 * Internal dependencies 70014 */ 70015 70016 70017 /** 70018 * Internal dependencies 70019 */ 70020 70021 70022 function valueToHTMLString(value, multiline) { 70023 if (rich_text.isEmpty(value)) { 70024 const multilineTag = getMultilineTag(multiline); 70025 return multilineTag ? `<$multilineTag}></$multilineTag}>` : ''; 70026 } 70027 if (Array.isArray(value)) { 70028 external_wp_deprecated_default()('wp.blockEditor.RichText value prop as children type', { 70029 since: '6.1', 70030 version: '6.3', 70031 alternative: 'value prop as string', 70032 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 70033 }); 70034 return external_wp_blocks_namespaceObject.children.toHTML(value); 70035 } 70036 70037 // To do: deprecate string type. 70038 if (typeof value === 'string') { 70039 return value; 70040 } 70041 70042 // To do: create a toReactComponent method on RichTextData, which we 70043 // might in the future also use for the editable tree. See 70044 // https://github.com/WordPress/gutenberg/pull/41655. 70045 return value.toHTMLString(); 70046 } 70047 function Content({ 70048 value, 70049 tagName: Tag, 70050 multiline, 70051 format, 70052 ...props 70053 }) { 70054 value = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.RawHTML, { 70055 children: valueToHTMLString(value, multiline) 70056 }); 70057 return Tag ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tag, { 70058 ...props, 70059 children: value 70060 }) : value; 70061 } 70062 70063 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/multiline.js 70064 /** 70065 * WordPress dependencies 70066 */ 70067 70068 70069 70070 70071 70072 70073 /** 70074 * Internal dependencies 70075 */ 70076 70077 70078 70079 70080 70081 function RichTextMultiline({ 70082 children, 70083 identifier, 70084 tagName: TagName = 'div', 70085 value = '', 70086 onChange, 70087 multiline, 70088 ...props 70089 }, forwardedRef) { 70090 external_wp_deprecated_default()('wp.blockEditor.RichText multiline prop', { 70091 since: '6.1', 70092 version: '6.3', 70093 alternative: 'nested blocks (InnerBlocks)', 70094 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/' 70095 }); 70096 const { 70097 clientId 70098 } = useBlockEditContext(); 70099 const { 70100 getSelectionStart, 70101 getSelectionEnd 70102 } = (0,external_wp_data_namespaceObject.useSelect)(store); 70103 const { 70104 selectionChange 70105 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 70106 const multilineTagName = getMultilineTag(multiline); 70107 value = value || `<$multilineTagName}></$multilineTagName}>`; 70108 const padded = `</$multilineTagName}>$value}<$multilineTagName}>`; 70109 const values = padded.split(`</$multilineTagName}><$multilineTagName}>`); 70110 values.shift(); 70111 values.pop(); 70112 function _onChange(newValues) { 70113 onChange(`<$multilineTagName}>$newValues.join(`</$multilineTagName}><$multilineTagName}>`)}</$multilineTagName}>`); 70114 } 70115 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TagName, { 70116 ref: forwardedRef, 70117 children: values.map((_value, index) => { 70118 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RichTextWrapper, { 70119 identifier: `$identifier}-$index}`, 70120 tagName: multilineTagName, 70121 value: _value, 70122 onChange: newValue => { 70123 const newValues = values.slice(); 70124 newValues[index] = newValue; 70125 _onChange(newValues); 70126 }, 70127 isSelected: undefined, 70128 onKeyDown: event => { 70129 if (event.keyCode !== external_wp_keycodes_namespaceObject.ENTER) { 70130 return; 70131 } 70132 event.preventDefault(); 70133 const { 70134 offset: start 70135 } = getSelectionStart(); 70136 const { 70137 offset: end 70138 } = getSelectionEnd(); 70139 70140 // Cannot split if there is no selection. 70141 if (typeof start !== 'number' || typeof end !== 'number') { 70142 return; 70143 } 70144 const richTextValue = (0,external_wp_richText_namespaceObject.create)({ 70145 html: _value 70146 }); 70147 richTextValue.start = start; 70148 richTextValue.end = end; 70149 const array = (0,external_wp_richText_namespaceObject.split)(richTextValue).map(v => (0,external_wp_richText_namespaceObject.toHTMLString)({ 70150 value: v 70151 })); 70152 const newValues = values.slice(); 70153 newValues.splice(index, 1, ...array); 70154 _onChange(newValues); 70155 selectionChange(clientId, `$identifier}-$index + 1}`, 0, 0); 70156 }, 70157 onMerge: forward => { 70158 const newValues = values.slice(); 70159 let offset = 0; 70160 if (forward) { 70161 if (!newValues[index + 1]) { 70162 return; 70163 } 70164 newValues.splice(index, 2, newValues[index] + newValues[index + 1]); 70165 offset = newValues[index].length - 1; 70166 } else { 70167 if (!newValues[index - 1]) { 70168 return; 70169 } 70170 newValues.splice(index - 1, 2, newValues[index - 1] + newValues[index]); 70171 offset = newValues[index - 1].length - 1; 70172 } 70173 _onChange(newValues); 70174 selectionChange(clientId, `$identifier}-$index - (forward ? 0 : 1)}`, offset, offset); 70175 }, 70176 ...props 70177 }, index); 70178 }) 70179 }); 70180 } 70181 /* harmony default export */ const multiline = ((0,external_wp_element_namespaceObject.forwardRef)(RichTextMultiline)); 70182 70183 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/with-deprecations.js 70184 /** 70185 * WordPress dependencies 70186 */ 70187 70188 70189 70190 70191 70192 /** 70193 * Internal dependencies 70194 */ 70195 70196 70197 function withDeprecations(Component) { 70198 return (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 70199 let value = props.value; 70200 let onChange = props.onChange; 70201 70202 // Handle deprecated format. 70203 if (Array.isArray(value)) { 70204 external_wp_deprecated_default()('wp.blockEditor.RichText value prop as children type', { 70205 since: '6.1', 70206 version: '6.3', 70207 alternative: 'value prop as string', 70208 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 70209 }); 70210 value = external_wp_blocks_namespaceObject.children.toHTML(props.value); 70211 onChange = newValue => props.onChange(external_wp_blocks_namespaceObject.children.fromDOM((0,external_wp_richText_namespaceObject.__unstableCreateElement)(document, newValue).childNodes)); 70212 } 70213 const NewComponent = props.multiline ? multiline : Component; 70214 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(NewComponent, { 70215 ...props, 70216 value: value, 70217 onChange: onChange, 70218 ref: ref 70219 }); 70220 }); 70221 } 70222 70223 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/index.js 70224 /** 70225 * External dependencies 70226 */ 70227 70228 70229 /** 70230 * WordPress dependencies 70231 */ 70232 70233 70234 70235 70236 70237 70238 70239 70240 70241 /** 70242 * Internal dependencies 70243 */ 70244 70245 70246 70247 70248 70249 70250 70251 70252 70253 70254 70255 70256 70257 70258 70259 const keyboardShortcutContext = (0,external_wp_element_namespaceObject.createContext)(); 70260 const inputEventContext = (0,external_wp_element_namespaceObject.createContext)(); 70261 const instanceIdKey = Symbol('instanceId'); 70262 70263 /** 70264 * Removes props used for the native version of RichText so that they are not 70265 * passed to the DOM element and log warnings. 70266 * 70267 * @param {Object} props Props to filter. 70268 * 70269 * @return {Object} Filtered props. 70270 */ 70271 function removeNativeProps(props) { 70272 const { 70273 __unstableMobileNoFocusOnMount, 70274 deleteEnter, 70275 placeholderTextColor, 70276 textAlign, 70277 selectionColor, 70278 tagsToEliminate, 70279 disableEditingMenu, 70280 fontSize, 70281 fontFamily, 70282 fontWeight, 70283 fontStyle, 70284 minWidth, 70285 maxWidth, 70286 disableSuggestions, 70287 disableAutocorrection, 70288 ...restProps 70289 } = props; 70290 return restProps; 70291 } 70292 function RichTextWrapper({ 70293 children, 70294 tagName = 'div', 70295 value: adjustedValue = '', 70296 onChange: adjustedOnChange, 70297 isSelected: originalIsSelected, 70298 multiline, 70299 inlineToolbar, 70300 wrapperClassName, 70301 autocompleters, 70302 onReplace, 70303 placeholder, 70304 allowedFormats, 70305 withoutInteractiveFormatting, 70306 onRemove, 70307 onMerge, 70308 onSplit, 70309 __unstableOnSplitAtEnd: onSplitAtEnd, 70310 __unstableOnSplitAtDoubleLineEnd: onSplitAtDoubleLineEnd, 70311 identifier, 70312 preserveWhiteSpace, 70313 __unstablePastePlainText: pastePlainText, 70314 __unstableEmbedURLOnPaste, 70315 __unstableDisableFormats: disableFormats, 70316 disableLineBreaks, 70317 __unstableAllowPrefixTransformations, 70318 readOnly, 70319 ...props 70320 }, forwardedRef) { 70321 props = removeNativeProps(props); 70322 if (onSplit) { 70323 external_wp_deprecated_default()('wp.blockEditor.RichText onSplit prop', { 70324 since: '6.4', 70325 alternative: 'block.json support key: "splitting"' 70326 }); 70327 } 70328 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(RichTextWrapper); 70329 const anchorRef = (0,external_wp_element_namespaceObject.useRef)(); 70330 const context = useBlockEditContext(); 70331 const { 70332 clientId, 70333 isSelected: isBlockSelected, 70334 name: blockName 70335 } = context; 70336 const blockBindings = context[blockBindingsKey]; 70337 const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context); 70338 const registry = (0,external_wp_data_namespaceObject.useRegistry)(); 70339 const selector = select => { 70340 // Avoid subscribing to the block editor store if the block is not 70341 // selected. 70342 if (!isBlockSelected) { 70343 return { 70344 isSelected: false 70345 }; 70346 } 70347 const { 70348 getSelectionStart, 70349 getSelectionEnd 70350 } = select(store); 70351 const selectionStart = getSelectionStart(); 70352 const selectionEnd = getSelectionEnd(); 70353 let isSelected; 70354 if (originalIsSelected === undefined) { 70355 isSelected = selectionStart.clientId === clientId && selectionEnd.clientId === clientId && (identifier ? selectionStart.attributeKey === identifier : selectionStart[instanceIdKey] === instanceId); 70356 } else if (originalIsSelected) { 70357 isSelected = selectionStart.clientId === clientId; 70358 } 70359 return { 70360 selectionStart: isSelected ? selectionStart.offset : undefined, 70361 selectionEnd: isSelected ? selectionEnd.offset : undefined, 70362 isSelected 70363 }; 70364 }; 70365 const { 70366 selectionStart, 70367 selectionEnd, 70368 isSelected 70369 } = (0,external_wp_data_namespaceObject.useSelect)(selector, [clientId, identifier, instanceId, originalIsSelected, isBlockSelected]); 70370 const { 70371 disableBoundBlock, 70372 bindingsPlaceholder, 70373 bindingsLabel 70374 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 70375 var _fieldsList$relatedBi; 70376 if (!blockBindings?.[identifier] || !canBindBlock(blockName)) { 70377 return {}; 70378 } 70379 const relatedBinding = blockBindings[identifier]; 70380 const blockBindingsSource = (0,external_wp_blocks_namespaceObject.getBlockBindingsSource)(relatedBinding.source); 70381 const blockBindingsContext = {}; 70382 if (blockBindingsSource?.usesContext?.length) { 70383 for (const key of blockBindingsSource.usesContext) { 70384 blockBindingsContext[key] = blockContext[key]; 70385 } 70386 } 70387 const _disableBoundBlock = !blockBindingsSource?.canUserEditValue?.({ 70388 select, 70389 context: blockBindingsContext, 70390 args: relatedBinding.args 70391 }); 70392 70393 // Don't modify placeholders if value is not empty. 70394 if (adjustedValue.length > 0) { 70395 return { 70396 disableBoundBlock: _disableBoundBlock, 70397 // Null values will make them fall back to the default behavior. 70398 bindingsPlaceholder: null, 70399 bindingsLabel: null 70400 }; 70401 } 70402 const { 70403 getBlockAttributes 70404 } = select(store); 70405 const blockAttributes = getBlockAttributes(clientId); 70406 const fieldsList = blockBindingsSource?.getFieldsList?.({ 70407 select, 70408 context: blockBindingsContext 70409 }); 70410 const bindingKey = (_fieldsList$relatedBi = fieldsList?.[relatedBinding?.args?.key]?.label) !== null && _fieldsList$relatedBi !== void 0 ? _fieldsList$relatedBi : blockBindingsSource?.label; 70411 const _bindingsPlaceholder = _disableBoundBlock ? bindingKey : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: connected field label or source label */ 70412 (0,external_wp_i18n_namespaceObject.__)('Add %s'), bindingKey); 70413 const _bindingsLabel = _disableBoundBlock ? relatedBinding?.args?.key || blockBindingsSource?.label : (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: source label or key */ 70414 (0,external_wp_i18n_namespaceObject.__)('Empty %s; start writing to edit its value'), relatedBinding?.args?.key || blockBindingsSource?.label); 70415 return { 70416 disableBoundBlock: _disableBoundBlock, 70417 bindingsPlaceholder: blockAttributes?.placeholder || _bindingsPlaceholder, 70418 bindingsLabel: _bindingsLabel 70419 }; 70420 }, [blockBindings, identifier, blockName, adjustedValue, clientId, blockContext]); 70421 const shouldDisableEditing = readOnly || disableBoundBlock; 70422 const { 70423 getSelectionStart, 70424 getSelectionEnd, 70425 getBlockRootClientId 70426 } = (0,external_wp_data_namespaceObject.useSelect)(store); 70427 const { 70428 selectionChange 70429 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 70430 const adjustedAllowedFormats = getAllowedFormats({ 70431 allowedFormats, 70432 disableFormats 70433 }); 70434 const hasFormats = !adjustedAllowedFormats || adjustedAllowedFormats.length > 0; 70435 const onSelectionChange = (0,external_wp_element_namespaceObject.useCallback)((start, end) => { 70436 const selection = {}; 70437 const unset = start === undefined && end === undefined; 70438 const baseSelection = { 70439 clientId, 70440 [identifier ? 'attributeKey' : instanceIdKey]: identifier ? identifier : instanceId 70441 }; 70442 if (typeof start === 'number' || unset) { 70443 // If we are only setting the start (or the end below), which 70444 // means a partial selection, and we're not updating a selection 70445 // with the same client ID, abort. This means the selected block 70446 // is a parent block. 70447 if (end === undefined && getBlockRootClientId(clientId) !== getBlockRootClientId(getSelectionEnd().clientId)) { 70448 return; 70449 } 70450 selection.start = { 70451 ...baseSelection, 70452 offset: start 70453 }; 70454 } 70455 if (typeof end === 'number' || unset) { 70456 if (start === undefined && getBlockRootClientId(clientId) !== getBlockRootClientId(getSelectionStart().clientId)) { 70457 return; 70458 } 70459 selection.end = { 70460 ...baseSelection, 70461 offset: end 70462 }; 70463 } 70464 selectionChange(selection); 70465 }, [clientId, getBlockRootClientId, getSelectionEnd, getSelectionStart, identifier, instanceId, selectionChange]); 70466 const { 70467 formatTypes, 70468 prepareHandlers, 70469 valueHandlers, 70470 changeHandlers, 70471 dependencies 70472 } = useFormatTypes({ 70473 clientId, 70474 identifier, 70475 withoutInteractiveFormatting, 70476 allowedFormats: adjustedAllowedFormats 70477 }); 70478 function addEditorOnlyFormats(value) { 70479 return valueHandlers.reduce((accumulator, fn) => fn(accumulator, value.text), value.formats); 70480 } 70481 function removeEditorOnlyFormats(value) { 70482 formatTypes.forEach(formatType => { 70483 // Remove formats created by prepareEditableTree, because they are editor only. 70484 if (formatType.__experimentalCreatePrepareEditableTree) { 70485 value = (0,external_wp_richText_namespaceObject.removeFormat)(value, formatType.name, 0, value.text.length); 70486 } 70487 }); 70488 return value.formats; 70489 } 70490 function addInvisibleFormats(value) { 70491 return prepareHandlers.reduce((accumulator, fn) => fn(accumulator, value.text), value.formats); 70492 } 70493 const { 70494 value, 70495 getValue, 70496 onChange, 70497 ref: richTextRef 70498 } = (0,external_wp_richText_namespaceObject.__unstableUseRichText)({ 70499 value: adjustedValue, 70500 onChange(html, { 70501 __unstableFormats, 70502 __unstableText 70503 }) { 70504 adjustedOnChange(html); 70505 Object.values(changeHandlers).forEach(changeHandler => { 70506 changeHandler(__unstableFormats, __unstableText); 70507 }); 70508 }, 70509 selectionStart, 70510 selectionEnd, 70511 onSelectionChange, 70512 placeholder: bindingsPlaceholder || placeholder, 70513 __unstableIsSelected: isSelected, 70514 __unstableDisableFormats: disableFormats, 70515 preserveWhiteSpace, 70516 __unstableDependencies: [...dependencies, tagName], 70517 __unstableAfterParse: addEditorOnlyFormats, 70518 __unstableBeforeSerialize: removeEditorOnlyFormats, 70519 __unstableAddInvisibleFormats: addInvisibleFormats 70520 }); 70521 const autocompleteProps = useBlockEditorAutocompleteProps({ 70522 onReplace, 70523 completers: autocompleters, 70524 record: value, 70525 onChange 70526 }); 70527 useMarkPersistent({ 70528 html: adjustedValue, 70529 value 70530 }); 70531 const keyboardShortcuts = (0,external_wp_element_namespaceObject.useRef)(new Set()); 70532 const inputEvents = (0,external_wp_element_namespaceObject.useRef)(new Set()); 70533 function onFocus() { 70534 anchorRef.current?.focus(); 70535 } 70536 const TagName = tagName; 70537 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 70538 children: [isSelected && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(keyboardShortcutContext.Provider, { 70539 value: keyboardShortcuts, 70540 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inputEventContext.Provider, { 70541 value: inputEvents, 70542 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Popover.__unstableSlotNameProvider, { 70543 value: "__unstable-block-tools-after", 70544 children: [children && children({ 70545 value, 70546 onChange, 70547 onFocus 70548 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(FormatEdit, { 70549 value: value, 70550 onChange: onChange, 70551 onFocus: onFocus, 70552 formatTypes: formatTypes, 70553 forwardedRef: anchorRef 70554 })] 70555 }) 70556 }) 70557 }), isSelected && hasFormats && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(format_toolbar_container, { 70558 inline: inlineToolbar, 70559 editableContentElement: anchorRef.current 70560 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(TagName 70561 // Overridable props. 70562 , { 70563 role: "textbox", 70564 "aria-multiline": !disableLineBreaks, 70565 "aria-readonly": shouldDisableEditing, 70566 ...props, 70567 // Unset draggable (coming from block props) for contentEditable 70568 // elements because it will interfere with multi block selection 70569 // when the contentEditable and draggable elements are the same 70570 // element. 70571 draggable: undefined, 70572 "aria-label": bindingsLabel || props['aria-label'] || placeholder, 70573 ...autocompleteProps, 70574 ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ 70575 // Rich text ref must be first because its focus listener 70576 // must be set up before any other ref calls .focus() on 70577 // mount. 70578 richTextRef, forwardedRef, autocompleteProps.ref, props.ref, useEventListeners({ 70579 registry, 70580 getValue, 70581 onChange, 70582 __unstableAllowPrefixTransformations, 70583 formatTypes, 70584 onReplace, 70585 selectionChange, 70586 isSelected, 70587 disableFormats, 70588 value, 70589 tagName, 70590 onSplit, 70591 __unstableEmbedURLOnPaste, 70592 pastePlainText, 70593 onMerge, 70594 onRemove, 70595 removeEditorOnlyFormats, 70596 disableLineBreaks, 70597 onSplitAtEnd, 70598 onSplitAtDoubleLineEnd, 70599 keyboardShortcuts, 70600 inputEvents 70601 }), anchorRef]), 70602 contentEditable: !shouldDisableEditing, 70603 suppressContentEditableWarning: true, 70604 className: dist_clsx('block-editor-rich-text__editable', props.className, 'rich-text') 70605 // Setting tabIndex to 0 is unnecessary, the element is already 70606 // focusable because it's contentEditable. This also fixes a 70607 // Safari bug where it's not possible to Shift+Click multi 70608 // select blocks when Shift Clicking into an element with 70609 // tabIndex because Safari will focus the element. However, 70610 // Safari will correctly ignore nested contentEditable elements. 70611 , 70612 tabIndex: props.tabIndex === 0 && !shouldDisableEditing ? null : props.tabIndex, 70613 "data-wp-block-attribute-key": identifier 70614 })] 70615 }); 70616 } 70617 70618 // This is the private API for the RichText component. 70619 // It allows access to all props, not just the public ones. 70620 const PrivateRichText = withDeprecations((0,external_wp_element_namespaceObject.forwardRef)(RichTextWrapper)); 70621 PrivateRichText.Content = Content; 70622 PrivateRichText.isEmpty = value => { 70623 return !value || value.length === 0; 70624 }; 70625 70626 // This is the public API for the RichText component. 70627 // We wrap the PrivateRichText component to hide some props from the public API. 70628 /** 70629 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/rich-text/README.md 70630 */ 70631 const PublicForwardedRichTextContainer = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 70632 const context = useBlockEditContext(); 70633 const isPreviewMode = context[isPreviewModeKey]; 70634 if (isPreviewMode) { 70635 // Remove all non-content props. 70636 const { 70637 children, 70638 tagName: Tag = 'div', 70639 value, 70640 onChange, 70641 isSelected, 70642 multiline, 70643 inlineToolbar, 70644 wrapperClassName, 70645 autocompleters, 70646 onReplace, 70647 placeholder, 70648 allowedFormats, 70649 withoutInteractiveFormatting, 70650 onRemove, 70651 onMerge, 70652 onSplit, 70653 __unstableOnSplitAtEnd, 70654 __unstableOnSplitAtDoubleLineEnd, 70655 identifier, 70656 preserveWhiteSpace, 70657 __unstablePastePlainText, 70658 __unstableEmbedURLOnPaste, 70659 __unstableDisableFormats, 70660 disableLineBreaks, 70661 __unstableAllowPrefixTransformations, 70662 readOnly, 70663 ...contentProps 70664 } = removeNativeProps(props); 70665 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tag, { 70666 ...contentProps, 70667 dangerouslySetInnerHTML: { 70668 __html: valueToHTMLString(value, multiline) 70669 } 70670 }); 70671 } 70672 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateRichText, { 70673 ref: ref, 70674 ...props, 70675 readOnly: false 70676 }); 70677 }); 70678 PublicForwardedRichTextContainer.Content = Content; 70679 PublicForwardedRichTextContainer.isEmpty = value => { 70680 return !value || value.length === 0; 70681 }; 70682 /* harmony default export */ const rich_text = (PublicForwardedRichTextContainer); 70683 70684 70685 70686 70687 ;// ./node_modules/@wordpress/block-editor/build-module/components/editable-text/index.js 70688 /** 70689 * WordPress dependencies 70690 */ 70691 70692 70693 /** 70694 * Internal dependencies 70695 */ 70696 70697 70698 const EditableText = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => { 70699 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(rich_text, { 70700 ref: ref, 70701 ...props, 70702 __unstableDisableFormats: true 70703 }); 70704 }); 70705 EditableText.Content = ({ 70706 value = '', 70707 tagName: Tag = 'div', 70708 ...props 70709 }) => { 70710 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(Tag, { 70711 ...props, 70712 children: value 70713 }); 70714 }; 70715 70716 /** 70717 * Renders an editable text input in which text formatting is not allowed. 70718 */ 70719 /* harmony default export */ const editable_text = (EditableText); 70720 70721 ;// ./node_modules/@wordpress/block-editor/build-module/components/plain-text/index.js 70722 /** 70723 * External dependencies 70724 */ 70725 70726 70727 70728 /** 70729 * WordPress dependencies 70730 */ 70731 70732 70733 /** 70734 * Internal dependencies 70735 */ 70736 70737 70738 /** 70739 * Render an auto-growing textarea allow users to fill any textual content. 70740 * 70741 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/plain-text/README.md 70742 * 70743 * @example 70744 * ```jsx 70745 * import { registerBlockType } from '@wordpress/blocks'; 70746 * import { PlainText } from '@wordpress/block-editor'; 70747 * 70748 * registerBlockType( 'my-plugin/example-block', { 70749 * // ... 70750 * 70751 * attributes: { 70752 * content: { 70753 * type: 'string', 70754 * }, 70755 * }, 70756 * 70757 * edit( { className, attributes, setAttributes } ) { 70758 * return ( 70759 * <PlainText 70760 * className={ className } 70761 * value={ attributes.content } 70762 * onChange={ ( content ) => setAttributes( { content } ) } 70763 * /> 70764 * ); 70765 * }, 70766 * } ); 70767 * ```` 70768 * 70769 * @param {Object} props Component props. 70770 * @param {string} props.value String value of the textarea. 70771 * @param {Function} props.onChange Function called when the text value changes. 70772 * @param {Object} [props.ref] The component forwards the `ref` property to the `TextareaAutosize` component. 70773 * @return {Element} Plain text component 70774 */ 70775 70776 const PlainText = (0,external_wp_element_namespaceObject.forwardRef)(({ 70777 __experimentalVersion, 70778 ...props 70779 }, ref) => { 70780 if (__experimentalVersion === 2) { 70781 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(editable_text, { 70782 ref: ref, 70783 ...props 70784 }); 70785 } 70786 const { 70787 className, 70788 onChange, 70789 ...remainingProps 70790 } = props; 70791 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(lib/* default */.A, { 70792 ref: ref, 70793 className: dist_clsx('block-editor-plain-text', className), 70794 onChange: event => onChange(event.target.value), 70795 ...remainingProps 70796 }); 70797 }); 70798 /* harmony default export */ const plain_text = (PlainText); 70799 70800 ;// ./node_modules/@wordpress/block-editor/build-module/components/responsive-block-control/label.js 70801 /** 70802 * WordPress dependencies 70803 */ 70804 70805 70806 70807 70808 function ResponsiveBlockControlLabel({ 70809 property, 70810 viewport, 70811 desc 70812 }) { 70813 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(ResponsiveBlockControlLabel); 70814 const accessibleLabel = desc || (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: 1: property name. 2: viewport name. */ 70815 (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); 70816 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 70817 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 70818 "aria-describedby": `rbc-desc-$instanceId}`, 70819 children: viewport.label 70820 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.VisuallyHidden, { 70821 as: "span", 70822 id: `rbc-desc-$instanceId}`, 70823 children: accessibleLabel 70824 })] 70825 }); 70826 } 70827 70828 ;// ./node_modules/@wordpress/block-editor/build-module/components/responsive-block-control/index.js 70829 /** 70830 * External dependencies 70831 */ 70832 70833 70834 /** 70835 * WordPress dependencies 70836 */ 70837 70838 70839 70840 70841 /** 70842 * Internal dependencies 70843 */ 70844 70845 70846 function ResponsiveBlockControl(props) { 70847 const { 70848 title, 70849 property, 70850 toggleLabel, 70851 onIsResponsiveChange, 70852 renderDefaultControl, 70853 renderResponsiveControls, 70854 isResponsive = false, 70855 defaultLabel = { 70856 id: 'all', 70857 label: (0,external_wp_i18n_namespaceObject._x)('All', 'screen sizes') 70858 }, 70859 viewports = [{ 70860 id: 'small', 70861 label: (0,external_wp_i18n_namespaceObject.__)('Small screens') 70862 }, { 70863 id: 'medium', 70864 label: (0,external_wp_i18n_namespaceObject.__)('Medium screens') 70865 }, { 70866 id: 'large', 70867 label: (0,external_wp_i18n_namespaceObject.__)('Large screens') 70868 }] 70869 } = props; 70870 if (!title || !property || !renderDefaultControl) { 70871 return null; 70872 } 70873 const toggleControlLabel = toggleLabel || (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %s: Property value for the control (eg: margin, padding, etc.). */ 70874 (0,external_wp_i18n_namespaceObject.__)('Use the same %s on all screen sizes.'), property); 70875 const toggleHelpText = (0,external_wp_i18n_namespaceObject.__)('Choose whether to use the same value for all screen sizes or a unique value for each screen size.'); 70876 const defaultControl = renderDefaultControl(/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ResponsiveBlockControlLabel, { 70877 property: property, 70878 viewport: defaultLabel 70879 }), defaultLabel); 70880 const defaultResponsiveControls = () => { 70881 return viewports.map(viewport => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.Fragment, { 70882 children: renderDefaultControl(/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ResponsiveBlockControlLabel, { 70883 property: property, 70884 viewport: viewport 70885 }), viewport) 70886 }, viewport.id)); 70887 }; 70888 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("fieldset", { 70889 className: "block-editor-responsive-block-control", 70890 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("legend", { 70891 className: "block-editor-responsive-block-control__title", 70892 children: title 70893 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 70894 className: "block-editor-responsive-block-control__inner", 70895 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 70896 __nextHasNoMarginBottom: true, 70897 className: "block-editor-responsive-block-control__toggle", 70898 label: toggleControlLabel, 70899 checked: !isResponsive, 70900 onChange: onIsResponsiveChange, 70901 help: toggleHelpText 70902 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 70903 className: dist_clsx('block-editor-responsive-block-control__group', { 70904 'is-responsive': isResponsive 70905 }), 70906 children: [!isResponsive && defaultControl, isResponsive && (renderResponsiveControls ? renderResponsiveControls(viewports) : defaultResponsiveControls())] 70907 })] 70908 })] 70909 }); 70910 } 70911 /* harmony default export */ const responsive_block_control = (ResponsiveBlockControl); 70912 70913 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/shortcut.js 70914 /** 70915 * WordPress dependencies 70916 */ 70917 70918 70919 70920 /** 70921 * Internal dependencies 70922 */ 70923 70924 function RichTextShortcut({ 70925 character, 70926 type, 70927 onUse 70928 }) { 70929 const keyboardShortcuts = (0,external_wp_element_namespaceObject.useContext)(keyboardShortcutContext); 70930 const onUseRef = (0,external_wp_element_namespaceObject.useRef)(); 70931 onUseRef.current = onUse; 70932 (0,external_wp_element_namespaceObject.useEffect)(() => { 70933 function callback(event) { 70934 if (external_wp_keycodes_namespaceObject.isKeyboardEvent[type](event, character)) { 70935 onUseRef.current(); 70936 event.preventDefault(); 70937 } 70938 } 70939 keyboardShortcuts.current.add(callback); 70940 return () => { 70941 keyboardShortcuts.current.delete(callback); 70942 }; 70943 }, [character, type]); 70944 return null; 70945 } 70946 70947 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/toolbar-button.js 70948 /** 70949 * WordPress dependencies 70950 */ 70951 70952 70953 70954 function RichTextToolbarButton({ 70955 name, 70956 shortcutType, 70957 shortcutCharacter, 70958 ...props 70959 }) { 70960 let shortcut; 70961 let fillName = 'RichText.ToolbarControls'; 70962 if (name) { 70963 fillName += `.$name}`; 70964 } 70965 if (shortcutType && shortcutCharacter) { 70966 shortcut = external_wp_keycodes_namespaceObject.displayShortcut[shortcutType](shortcutCharacter); 70967 } 70968 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Fill, { 70969 name: fillName, 70970 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 70971 ...props, 70972 shortcut: shortcut 70973 }) 70974 }); 70975 } 70976 70977 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/input-event.js 70978 /** 70979 * WordPress dependencies 70980 */ 70981 70982 70983 /** 70984 * Internal dependencies 70985 */ 70986 70987 function __unstableRichTextInputEvent({ 70988 inputType, 70989 onInput 70990 }) { 70991 const callbacks = (0,external_wp_element_namespaceObject.useContext)(inputEventContext); 70992 const onInputRef = (0,external_wp_element_namespaceObject.useRef)(); 70993 onInputRef.current = onInput; 70994 (0,external_wp_element_namespaceObject.useEffect)(() => { 70995 function callback(event) { 70996 if (event.inputType === inputType) { 70997 onInputRef.current(); 70998 event.preventDefault(); 70999 } 71000 } 71001 callbacks.current.add(callback); 71002 return () => { 71003 callbacks.current.delete(callback); 71004 }; 71005 }, [inputType]); 71006 return null; 71007 } 71008 71009 ;// ./node_modules/@wordpress/block-editor/build-module/components/tool-selector/index.js 71010 /** 71011 * WordPress dependencies 71012 */ 71013 71014 71015 71016 71017 71018 71019 /** 71020 * Internal dependencies 71021 */ 71022 71023 71024 const selectIcon = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SVG, { 71025 xmlns: "http://www.w3.org/2000/svg", 71026 width: "24", 71027 height: "24", 71028 viewBox: "0 0 24 24", 71029 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Path, { 71030 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" 71031 }) 71032 }); 71033 function ToolSelector(props, ref) { 71034 const mode = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).__unstableGetEditorMode(), []); 71035 const { 71036 __unstableSetEditorMode 71037 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 71038 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Dropdown, { 71039 renderToggle: ({ 71040 isOpen, 71041 onToggle 71042 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71043 size: "compact", 71044 ...props, 71045 ref: ref, 71046 icon: mode === 'navigation' ? edit : selectIcon, 71047 "aria-expanded": isOpen, 71048 "aria-haspopup": "true", 71049 onClick: onToggle 71050 /* translators: button label text should, if possible, be under 16 characters. */, 71051 label: (0,external_wp_i18n_namespaceObject.__)('Tools') 71052 }), 71053 popoverProps: { 71054 placement: 'bottom-start' 71055 }, 71056 renderContent: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71057 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.NavigableMenu, { 71058 className: "block-editor-tool-selector__menu", 71059 role: "menu", 71060 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Tools'), 71061 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItemsChoice, { 71062 value: mode === 'navigation' ? 'navigation' : 'edit', 71063 onSelect: newMode => { 71064 __unstableSetEditorMode(newMode); 71065 }, 71066 choices: [{ 71067 value: 'navigation', 71068 label: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71069 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 71070 icon: edit 71071 }), (0,external_wp_i18n_namespaceObject.__)('Write')] 71072 }), 71073 info: (0,external_wp_i18n_namespaceObject.__)('Focus on content.'), 71074 'aria-label': (0,external_wp_i18n_namespaceObject.__)('Write') 71075 }, { 71076 value: 'edit', 71077 label: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71078 children: [selectIcon, (0,external_wp_i18n_namespaceObject.__)('Design')] 71079 }), 71080 info: (0,external_wp_i18n_namespaceObject.__)('Edit layout and styles.'), 71081 'aria-label': (0,external_wp_i18n_namespaceObject.__)('Design') 71082 }] 71083 }) 71084 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 71085 className: "block-editor-tool-selector__help", 71086 children: (0,external_wp_i18n_namespaceObject.__)('Tools provide different sets of interactions for blocks. Choose between simplified content tools (Write) and advanced visual editing tools (Design).') 71087 })] 71088 }) 71089 }); 71090 } 71091 /* harmony default export */ const tool_selector = ((0,external_wp_element_namespaceObject.forwardRef)(ToolSelector)); 71092 71093 ;// ./node_modules/@wordpress/block-editor/build-module/components/unit-control/index.js 71094 /** 71095 * WordPress dependencies 71096 */ 71097 71098 71099 /** 71100 * Internal dependencies 71101 */ 71102 71103 71104 function UnitControl({ 71105 units: unitsProp, 71106 ...props 71107 }) { 71108 const [availableUnits] = use_settings_useSettings('spacing.units'); 71109 const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({ 71110 availableUnits: availableUnits || ['%', 'px', 'em', 'rem', 'vw'], 71111 units: unitsProp 71112 }); 71113 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 71114 units: units, 71115 ...props 71116 }); 71117 } 71118 71119 ;// ./node_modules/@wordpress/icons/build-module/library/arrow-left.js 71120 /** 71121 * WordPress dependencies 71122 */ 71123 71124 71125 const arrowLeft = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 71126 xmlns: "http://www.w3.org/2000/svg", 71127 viewBox: "0 0 24 24", 71128 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 71129 d: "M20 11.2H6.8l3.7-3.7-1-1L3.9 12l5.6 5.5 1-1-3.7-3.7H20z" 71130 }) 71131 }); 71132 /* harmony default export */ const arrow_left = (arrowLeft); 71133 71134 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-input/button.js 71135 /** 71136 * WordPress dependencies 71137 */ 71138 71139 71140 71141 71142 71143 /** 71144 * Internal dependencies 71145 */ 71146 71147 71148 class URLInputButton extends external_wp_element_namespaceObject.Component { 71149 constructor() { 71150 super(...arguments); 71151 this.toggle = this.toggle.bind(this); 71152 this.submitLink = this.submitLink.bind(this); 71153 this.state = { 71154 expanded: false 71155 }; 71156 } 71157 toggle() { 71158 this.setState({ 71159 expanded: !this.state.expanded 71160 }); 71161 } 71162 submitLink(event) { 71163 event.preventDefault(); 71164 this.toggle(); 71165 } 71166 render() { 71167 const { 71168 url, 71169 onChange 71170 } = this.props; 71171 const { 71172 expanded 71173 } = this.state; 71174 const buttonLabel = url ? (0,external_wp_i18n_namespaceObject.__)('Edit link') : (0,external_wp_i18n_namespaceObject.__)('Insert link'); 71175 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 71176 className: "block-editor-url-input__button", 71177 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71178 size: "compact", 71179 icon: library_link, 71180 label: buttonLabel, 71181 onClick: this.toggle, 71182 className: "components-toolbar__control", 71183 isPressed: !!url 71184 }), expanded && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("form", { 71185 className: "block-editor-url-input__button-modal", 71186 onSubmit: this.submitLink, 71187 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 71188 className: "block-editor-url-input__button-modal-line", 71189 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71190 __next40pxDefaultSize: true, 71191 className: "block-editor-url-input__back", 71192 icon: arrow_left, 71193 label: (0,external_wp_i18n_namespaceObject.__)('Close'), 71194 onClick: this.toggle 71195 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_input, { 71196 value: url || '', 71197 onChange: onChange, 71198 suffix: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalInputControlSuffixWrapper, { 71199 variant: "control", 71200 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71201 size: "small", 71202 icon: keyboard_return, 71203 label: (0,external_wp_i18n_namespaceObject.__)('Submit'), 71204 type: "submit" 71205 }) 71206 }) 71207 })] 71208 }) 71209 })] 71210 }); 71211 } 71212 } 71213 71214 /** 71215 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-input/README.md 71216 */ 71217 /* harmony default export */ const url_input_button = (URLInputButton); 71218 71219 ;// ./node_modules/@wordpress/icons/build-module/library/image.js 71220 /** 71221 * WordPress dependencies 71222 */ 71223 71224 71225 const image_image = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 71226 viewBox: "0 0 24 24", 71227 xmlns: "http://www.w3.org/2000/svg", 71228 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 71229 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" 71230 }) 71231 }); 71232 /* harmony default export */ const library_image = (image_image); 71233 71234 ;// ./node_modules/@wordpress/block-editor/build-module/components/url-popover/image-url-input-ui.js 71235 /** 71236 * WordPress dependencies 71237 */ 71238 71239 71240 71241 71242 71243 71244 /** 71245 * Internal dependencies 71246 */ 71247 71248 71249 const LINK_DESTINATION_NONE = 'none'; 71250 const LINK_DESTINATION_CUSTOM = 'custom'; 71251 const LINK_DESTINATION_MEDIA = 'media'; 71252 const LINK_DESTINATION_ATTACHMENT = 'attachment'; 71253 const NEW_TAB_REL = ['noreferrer', 'noopener']; 71254 const ImageURLInputUI = ({ 71255 linkDestination, 71256 onChangeUrl, 71257 url, 71258 mediaType = 'image', 71259 mediaUrl, 71260 mediaLink, 71261 linkTarget, 71262 linkClass, 71263 rel, 71264 showLightboxSetting, 71265 lightboxEnabled, 71266 onSetLightbox, 71267 resetLightbox 71268 }) => { 71269 const [isOpen, setIsOpen] = (0,external_wp_element_namespaceObject.useState)(false); 71270 // Use internal state instead of a ref to make sure that the component 71271 // re-renders when the popover's anchor updates. 71272 const [popoverAnchor, setPopoverAnchor] = (0,external_wp_element_namespaceObject.useState)(null); 71273 const openLinkUI = () => { 71274 setIsOpen(true); 71275 }; 71276 const [isEditingLink, setIsEditingLink] = (0,external_wp_element_namespaceObject.useState)(false); 71277 const [urlInput, setUrlInput] = (0,external_wp_element_namespaceObject.useState)(null); 71278 const autocompleteRef = (0,external_wp_element_namespaceObject.useRef)(null); 71279 const wrapperRef = (0,external_wp_element_namespaceObject.useRef)(); 71280 (0,external_wp_element_namespaceObject.useEffect)(() => { 71281 if (!wrapperRef.current) { 71282 return; 71283 } 71284 const nextFocusTarget = external_wp_dom_namespaceObject.focus.focusable.find(wrapperRef.current)[0] || wrapperRef.current; 71285 nextFocusTarget.focus(); 71286 }, [isEditingLink, url, lightboxEnabled]); 71287 const startEditLink = () => { 71288 if (linkDestination === LINK_DESTINATION_MEDIA || linkDestination === LINK_DESTINATION_ATTACHMENT) { 71289 setUrlInput(''); 71290 } 71291 setIsEditingLink(true); 71292 }; 71293 const stopEditLink = () => { 71294 setIsEditingLink(false); 71295 }; 71296 const closeLinkUI = () => { 71297 setUrlInput(null); 71298 stopEditLink(); 71299 setIsOpen(false); 71300 }; 71301 const getUpdatedLinkTargetSettings = value => { 71302 const newLinkTarget = value ? '_blank' : undefined; 71303 let updatedRel; 71304 if (newLinkTarget) { 71305 const rels = (rel !== null && rel !== void 0 ? rel : '').split(' '); 71306 NEW_TAB_REL.forEach(relVal => { 71307 if (!rels.includes(relVal)) { 71308 rels.push(relVal); 71309 } 71310 }); 71311 updatedRel = rels.join(' '); 71312 } else { 71313 const rels = (rel !== null && rel !== void 0 ? rel : '').split(' ').filter(relVal => NEW_TAB_REL.includes(relVal) === false); 71314 updatedRel = rels.length ? rels.join(' ') : undefined; 71315 } 71316 return { 71317 linkTarget: newLinkTarget, 71318 rel: updatedRel 71319 }; 71320 }; 71321 const onFocusOutside = () => { 71322 return event => { 71323 // The autocomplete suggestions list renders in a separate popover (in a portal), 71324 // so onFocusOutside fails to detect that a click on a suggestion occurred in the 71325 // LinkContainer. Detect clicks on autocomplete suggestions using a ref here, and 71326 // return to avoid the popover being closed. 71327 const autocompleteElement = autocompleteRef.current; 71328 if (autocompleteElement && autocompleteElement.contains(event.target)) { 71329 return; 71330 } 71331 setIsOpen(false); 71332 setUrlInput(null); 71333 stopEditLink(); 71334 }; 71335 }; 71336 const onSubmitLinkChange = () => { 71337 return event => { 71338 if (urlInput) { 71339 // It is possible the entered URL actually matches a named link destination. 71340 // This check will ensure our link destination is correct. 71341 const selectedDestination = getLinkDestinations().find(destination => destination.url === urlInput)?.linkDestination || LINK_DESTINATION_CUSTOM; 71342 onChangeUrl({ 71343 href: urlInput, 71344 linkDestination: selectedDestination, 71345 lightbox: { 71346 enabled: false 71347 } 71348 }); 71349 } 71350 stopEditLink(); 71351 setUrlInput(null); 71352 event.preventDefault(); 71353 }; 71354 }; 71355 const onLinkRemove = () => { 71356 onChangeUrl({ 71357 linkDestination: LINK_DESTINATION_NONE, 71358 href: '' 71359 }); 71360 }; 71361 const getLinkDestinations = () => { 71362 const linkDestinations = [{ 71363 linkDestination: LINK_DESTINATION_MEDIA, 71364 title: (0,external_wp_i18n_namespaceObject.__)('Link to image file'), 71365 url: mediaType === 'image' ? mediaUrl : undefined, 71366 icon: library_image 71367 }]; 71368 if (mediaType === 'image' && mediaLink) { 71369 linkDestinations.push({ 71370 linkDestination: LINK_DESTINATION_ATTACHMENT, 71371 title: (0,external_wp_i18n_namespaceObject.__)('Link to attachment page'), 71372 url: mediaType === 'image' ? mediaLink : undefined, 71373 icon: library_page 71374 }); 71375 } 71376 return linkDestinations; 71377 }; 71378 const onSetHref = value => { 71379 const linkDestinations = getLinkDestinations(); 71380 let linkDestinationInput; 71381 if (!value) { 71382 linkDestinationInput = LINK_DESTINATION_NONE; 71383 } else { 71384 linkDestinationInput = (linkDestinations.find(destination => { 71385 return destination.url === value; 71386 }) || { 71387 linkDestination: LINK_DESTINATION_CUSTOM 71388 }).linkDestination; 71389 } 71390 onChangeUrl({ 71391 linkDestination: linkDestinationInput, 71392 href: value 71393 }); 71394 }; 71395 const onSetNewTab = value => { 71396 const updatedLinkTarget = getUpdatedLinkTargetSettings(value); 71397 onChangeUrl(updatedLinkTarget); 71398 }; 71399 const onSetLinkRel = value => { 71400 onChangeUrl({ 71401 rel: value 71402 }); 71403 }; 71404 const onSetLinkClass = value => { 71405 onChangeUrl({ 71406 linkClass: value 71407 }); 71408 }; 71409 const advancedOptions = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 71410 spacing: "3", 71411 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 71412 __nextHasNoMarginBottom: true, 71413 label: (0,external_wp_i18n_namespaceObject.__)('Open in new tab'), 71414 onChange: onSetNewTab, 71415 checked: linkTarget === '_blank' 71416 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 71417 __next40pxDefaultSize: true, 71418 __nextHasNoMarginBottom: true, 71419 label: (0,external_wp_i18n_namespaceObject.__)('Link rel'), 71420 value: rel !== null && rel !== void 0 ? rel : '', 71421 onChange: onSetLinkRel 71422 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextControl, { 71423 __next40pxDefaultSize: true, 71424 __nextHasNoMarginBottom: true, 71425 label: (0,external_wp_i18n_namespaceObject.__)('Link CSS class'), 71426 value: linkClass || '', 71427 onChange: onSetLinkClass 71428 })] 71429 }); 71430 const linkEditorValue = urlInput !== null ? urlInput : url; 71431 const hideLightboxPanel = !lightboxEnabled || lightboxEnabled && !showLightboxSetting; 71432 const showLinkEditor = !linkEditorValue && hideLightboxPanel; 71433 const urlLabel = (getLinkDestinations().find(destination => destination.linkDestination === linkDestination) || {}).title; 71434 const PopoverChildren = () => { 71435 if (lightboxEnabled && showLightboxSetting && !url && !isEditingLink) { 71436 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 71437 className: "block-editor-url-popover__expand-on-click", 71438 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(build_module_icon, { 71439 icon: library_fullscreen 71440 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 71441 className: "text", 71442 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 71443 children: (0,external_wp_i18n_namespaceObject.__)('Enlarge on click') 71444 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 71445 className: "description", 71446 children: (0,external_wp_i18n_namespaceObject.__)('Scales the image with a lightbox effect') 71447 })] 71448 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71449 icon: link_off, 71450 label: (0,external_wp_i18n_namespaceObject.__)('Disable enlarge on click'), 71451 onClick: () => { 71452 onSetLightbox?.(false); 71453 }, 71454 size: "compact" 71455 })] 71456 }); 71457 } else if (!url || isEditingLink) { 71458 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_popover.LinkEditor, { 71459 className: "block-editor-format-toolbar__link-container-content", 71460 value: linkEditorValue, 71461 onChangeInputValue: setUrlInput, 71462 onSubmit: onSubmitLinkChange(), 71463 autocompleteRef: autocompleteRef 71464 }); 71465 } else if (url && !isEditingLink) { 71466 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71467 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_popover.LinkViewer, { 71468 className: "block-editor-format-toolbar__link-container-content", 71469 url: url, 71470 onEditLinkClick: startEditLink, 71471 urlLabel: urlLabel 71472 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71473 icon: link_off, 71474 label: (0,external_wp_i18n_namespaceObject.__)('Remove link'), 71475 onClick: () => { 71476 onLinkRemove(); 71477 resetLightbox?.(); 71478 }, 71479 size: "compact" 71480 })] 71481 }); 71482 } 71483 }; 71484 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71485 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, { 71486 icon: library_link, 71487 className: "components-toolbar__control", 71488 label: (0,external_wp_i18n_namespaceObject.__)('Link'), 71489 "aria-expanded": isOpen, 71490 onClick: openLinkUI, 71491 ref: setPopoverAnchor, 71492 isActive: !!url || lightboxEnabled && showLightboxSetting 71493 }), isOpen && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(url_popover, { 71494 ref: wrapperRef, 71495 anchor: popoverAnchor, 71496 onFocusOutside: onFocusOutside(), 71497 onClose: closeLinkUI, 71498 renderSettings: hideLightboxPanel ? () => advancedOptions : null, 71499 additionalControls: showLinkEditor && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.NavigableMenu, { 71500 children: [getLinkDestinations().map(link => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 71501 icon: link.icon, 71502 iconPosition: "left", 71503 onClick: () => { 71504 setUrlInput(null); 71505 onSetHref(link.url); 71506 stopEditLink(); 71507 }, 71508 children: link.title 71509 }, link.linkDestination)), showLightboxSetting && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.MenuItem, { 71510 className: "block-editor-url-popover__expand-on-click", 71511 icon: library_fullscreen, 71512 info: (0,external_wp_i18n_namespaceObject.__)('Scale the image with a lightbox effect.'), 71513 iconPosition: "left", 71514 onClick: () => { 71515 setUrlInput(null); 71516 onChangeUrl({ 71517 linkDestination: LINK_DESTINATION_NONE, 71518 href: '' 71519 }); 71520 onSetLightbox?.(true); 71521 stopEditLink(); 71522 }, 71523 children: (0,external_wp_i18n_namespaceObject.__)('Enlarge on click') 71524 }, "expand-on-click")] 71525 }), 71526 offset: 13, 71527 children: PopoverChildren() 71528 })] 71529 }); 71530 }; 71531 71532 71533 ;// ./node_modules/@wordpress/block-editor/build-module/components/preview-options/index.js 71534 /** 71535 * WordPress dependencies 71536 */ 71537 71538 function PreviewOptions() { 71539 external_wp_deprecated_default()('wp.blockEditor.PreviewOptions', { 71540 version: '6.5' 71541 }); 71542 return null; 71543 } 71544 71545 ;// ./node_modules/@wordpress/block-editor/build-module/components/use-resize-canvas/index.js 71546 /** 71547 * WordPress dependencies 71548 */ 71549 71550 71551 /** 71552 * Function to resize the editor window. 71553 * 71554 * @param {string} deviceType Used for determining the size of the container (e.g. Desktop, Tablet, Mobile) 71555 * 71556 * @return {Object} Inline styles to be added to resizable container. 71557 */ 71558 function useResizeCanvas(deviceType) { 71559 const [actualWidth, updateActualWidth] = (0,external_wp_element_namespaceObject.useState)(window.innerWidth); 71560 (0,external_wp_element_namespaceObject.useEffect)(() => { 71561 if (deviceType === 'Desktop') { 71562 return; 71563 } 71564 const resizeListener = () => updateActualWidth(window.innerWidth); 71565 window.addEventListener('resize', resizeListener); 71566 return () => { 71567 window.removeEventListener('resize', resizeListener); 71568 }; 71569 }, [deviceType]); 71570 const getCanvasWidth = device => { 71571 let deviceWidth; 71572 switch (device) { 71573 case 'Tablet': 71574 deviceWidth = 780; 71575 break; 71576 case 'Mobile': 71577 deviceWidth = 360; 71578 break; 71579 default: 71580 return null; 71581 } 71582 return deviceWidth < actualWidth ? deviceWidth : actualWidth; 71583 }; 71584 const contentInlineStyles = device => { 71585 const height = device === 'Mobile' ? '768px' : '1024px'; 71586 const marginVertical = '40px'; 71587 const marginHorizontal = 'auto'; 71588 switch (device) { 71589 case 'Tablet': 71590 case 'Mobile': 71591 return { 71592 width: getCanvasWidth(device), 71593 // Keeping margin styles separate to avoid warnings 71594 // when those props get overridden in the iframe component 71595 marginTop: marginVertical, 71596 marginBottom: marginVertical, 71597 marginLeft: marginHorizontal, 71598 marginRight: marginHorizontal, 71599 height, 71600 maxWidth: '100%' 71601 }; 71602 default: 71603 return { 71604 marginLeft: marginHorizontal, 71605 marginRight: marginHorizontal 71606 }; 71607 } 71608 }; 71609 return contentInlineStyles(deviceType); 71610 } 71611 71612 ;// ./node_modules/@wordpress/block-editor/build-module/components/skip-to-selected-block/index.js 71613 /** 71614 * WordPress dependencies 71615 */ 71616 71617 71618 71619 71620 71621 /** 71622 * Internal dependencies 71623 */ 71624 71625 71626 71627 /** 71628 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/skip-to-selected-block/README.md 71629 */ 71630 71631 function SkipToSelectedBlock() { 71632 const selectedBlockClientId = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlockSelectionStart(), []); 71633 const ref = (0,external_wp_element_namespaceObject.useRef)(); 71634 useBlockElementRef(selectedBlockClientId, ref); 71635 const onClick = () => { 71636 ref.current?.focus(); 71637 }; 71638 return selectedBlockClientId ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 71639 __next40pxDefaultSize: true, 71640 variant: "secondary", 71641 className: "block-editor-skip-to-selected-block", 71642 onClick: onClick, 71643 children: (0,external_wp_i18n_namespaceObject.__)('Skip to the selected block') 71644 }) : null; 71645 } 71646 71647 ;// ./node_modules/@wordpress/block-editor/build-module/components/multi-selection-inspector/index.js 71648 /** 71649 * WordPress dependencies 71650 */ 71651 71652 71653 71654 71655 71656 /** 71657 * Internal dependencies 71658 */ 71659 71660 71661 71662 function MultiSelectionInspector() { 71663 const selectedBlockCount = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSelectedBlockCount(), []); 71664 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 71665 justify: "flex-start", 71666 spacing: 2, 71667 className: "block-editor-multi-selection-inspector__card", 71668 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 71669 icon: library_copy, 71670 showColors: true 71671 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 71672 className: "block-editor-multi-selection-inspector__card-title", 71673 children: (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of blocks */ 71674 (0,external_wp_i18n_namespaceObject._n)('%d Block', '%d Blocks', selectedBlockCount), selectedBlockCount) 71675 })] 71676 }); 71677 } 71678 71679 ;// ./node_modules/@wordpress/icons/build-module/library/cog.js 71680 /** 71681 * WordPress dependencies 71682 */ 71683 71684 71685 const cog = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 71686 xmlns: "http://www.w3.org/2000/svg", 71687 viewBox: "0 0 24 24", 71688 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 71689 fillRule: "evenodd", 71690 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", 71691 clipRule: "evenodd" 71692 }) 71693 }); 71694 /* harmony default export */ const library_cog = (cog); 71695 71696 ;// ./node_modules/@wordpress/icons/build-module/library/styles.js 71697 /** 71698 * WordPress dependencies 71699 */ 71700 71701 71702 const styles = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, { 71703 viewBox: "0 0 24 24", 71704 xmlns: "http://www.w3.org/2000/svg", 71705 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, { 71706 fillRule: "evenodd", 71707 clipRule: "evenodd", 71708 d: "M20 12a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-1.5 0a6.5 6.5 0 0 1-6.5 6.5v-13a6.5 6.5 0 0 1 6.5 6.5Z" 71709 }) 71710 }); 71711 /* harmony default export */ const library_styles = (styles); 71712 71713 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/utils.js 71714 /** 71715 * WordPress dependencies 71716 */ 71717 71718 71719 const TAB_SETTINGS = { 71720 name: 'settings', 71721 title: (0,external_wp_i18n_namespaceObject.__)('Settings'), 71722 value: 'settings', 71723 icon: library_cog 71724 }; 71725 const TAB_STYLES = { 71726 name: 'styles', 71727 title: (0,external_wp_i18n_namespaceObject.__)('Styles'), 71728 value: 'styles', 71729 icon: library_styles 71730 }; 71731 const TAB_LIST_VIEW = { 71732 name: 'list', 71733 title: (0,external_wp_i18n_namespaceObject.__)('List View'), 71734 value: 'list-view', 71735 icon: list_view 71736 }; 71737 71738 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/advanced-controls-panel.js 71739 /** 71740 * WordPress dependencies 71741 */ 71742 71743 71744 71745 /** 71746 * Internal dependencies 71747 */ 71748 71749 71750 const AdvancedControls = () => { 71751 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(InspectorAdvancedControls.slotName); 71752 const hasFills = Boolean(fills && fills.length); 71753 if (!hasFills) { 71754 return null; 71755 } 71756 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, { 71757 className: "block-editor-block-inspector__advanced", 71758 title: (0,external_wp_i18n_namespaceObject.__)('Advanced'), 71759 initialOpen: false, 71760 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71761 group: "advanced" 71762 }) 71763 }); 71764 }; 71765 /* harmony default export */ const advanced_controls_panel = (AdvancedControls); 71766 71767 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/position-controls-panel.js 71768 /** 71769 * WordPress dependencies 71770 */ 71771 71772 71773 71774 71775 /** 71776 * Internal dependencies 71777 */ 71778 71779 71780 71781 71782 71783 71784 const PositionControlsPanel = () => { 71785 const { 71786 selectedClientIds, 71787 selectedBlocks, 71788 hasPositionAttribute 71789 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 71790 const { 71791 getBlocksByClientId, 71792 getSelectedBlockClientIds 71793 } = select(store); 71794 const selectedBlockClientIds = getSelectedBlockClientIds(); 71795 const _selectedBlocks = getBlocksByClientId(selectedBlockClientIds); 71796 return { 71797 selectedClientIds: selectedBlockClientIds, 71798 selectedBlocks: _selectedBlocks, 71799 hasPositionAttribute: _selectedBlocks?.some(({ 71800 attributes 71801 }) => !!attributes?.style?.position?.type) 71802 }; 71803 }, []); 71804 const { 71805 updateBlockAttributes 71806 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 71807 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 71808 function resetPosition() { 71809 if (!selectedClientIds?.length || !selectedBlocks?.length) { 71810 return; 71811 } 71812 const attributesByClientId = Object.fromEntries(selectedBlocks?.map(({ 71813 clientId, 71814 attributes 71815 }) => [clientId, { 71816 style: utils_cleanEmptyObject({ 71817 ...attributes?.style, 71818 position: { 71819 ...attributes?.style?.position, 71820 type: undefined, 71821 top: undefined, 71822 right: undefined, 71823 bottom: undefined, 71824 left: undefined 71825 } 71826 }) 71827 }])); 71828 updateBlockAttributes(selectedClientIds, attributesByClientId, true); 71829 } 71830 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 71831 className: "block-editor-block-inspector__position", 71832 label: (0,external_wp_i18n_namespaceObject.__)('Position'), 71833 resetAll: resetPosition, 71834 dropdownMenuProps: dropdownMenuProps, 71835 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 71836 isShownByDefault: hasPositionAttribute, 71837 label: (0,external_wp_i18n_namespaceObject.__)('Position'), 71838 hasValue: () => hasPositionAttribute, 71839 onDeselect: resetPosition, 71840 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71841 group: "position" 71842 }) 71843 }) 71844 }); 71845 }; 71846 const PositionControls = () => { 71847 const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(inspector_controls_groups.position.name); 71848 const hasFills = Boolean(fills && fills.length); 71849 if (!hasFills) { 71850 return null; 71851 } 71852 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PositionControlsPanel, {}); 71853 }; 71854 /* harmony default export */ const position_controls_panel = (PositionControls); 71855 71856 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/settings-tab.js 71857 /** 71858 * Internal dependencies 71859 */ 71860 71861 71862 71863 71864 const SettingsTab = ({ 71865 showAdvancedControls = false 71866 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71867 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(position_controls_panel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71868 group: "bindings" 71869 }), showAdvancedControls && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 71870 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(advanced_controls_panel, {}) 71871 })] 71872 }); 71873 /* harmony default export */ const settings_tab = (SettingsTab); 71874 71875 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/styles-tab.js 71876 /** 71877 * WordPress dependencies 71878 */ 71879 71880 71881 71882 /** 71883 * Internal dependencies 71884 */ 71885 71886 71887 71888 71889 const StylesTab = ({ 71890 blockName, 71891 clientId, 71892 hasBlockStyles 71893 }) => { 71894 const borderPanelLabel = useBorderPanelLabel({ 71895 blockName 71896 }); 71897 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 71898 children: [hasBlockStyles && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 71899 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, { 71900 title: (0,external_wp_i18n_namespaceObject.__)('Styles'), 71901 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_styles, { 71902 clientId: clientId 71903 }) 71904 }) 71905 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71906 group: "color", 71907 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 71908 className: "color-block-support-panel__inner-wrapper" 71909 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71910 group: "background", 71911 label: (0,external_wp_i18n_namespaceObject.__)('Background image') 71912 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71913 group: "filter" 71914 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71915 group: "typography", 71916 label: (0,external_wp_i18n_namespaceObject.__)('Typography') 71917 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71918 group: "dimensions", 71919 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions') 71920 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71921 group: "border", 71922 label: borderPanelLabel 71923 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 71924 group: "styles" 71925 })] 71926 }); 71927 }; 71928 /* harmony default export */ const styles_tab = (StylesTab); 71929 71930 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/use-is-list-view-tab-disabled.js 71931 // List view tab restricts the blocks that may render to it via the 71932 // allowlist below. 71933 const allowlist = ['core/navigation']; 71934 const useIsListViewTabDisabled = blockName => { 71935 return !allowlist.includes(blockName); 71936 }; 71937 /* harmony default export */ const use_is_list_view_tab_disabled = (useIsListViewTabDisabled); 71938 71939 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/index.js 71940 /** 71941 * WordPress dependencies 71942 */ 71943 71944 71945 71946 71947 /** 71948 * Internal dependencies 71949 */ 71950 71951 71952 71953 71954 71955 71956 71957 const { 71958 Tabs: inspector_controls_tabs_Tabs 71959 } = unlock(external_wp_components_namespaceObject.privateApis); 71960 function InspectorControlsTabs({ 71961 blockName, 71962 clientId, 71963 hasBlockStyles, 71964 tabs 71965 }) { 71966 const showIconLabels = (0,external_wp_data_namespaceObject.useSelect)(select => { 71967 return select(external_wp_preferences_namespaceObject.store).get('core', 'showIconLabels'); 71968 }, []); 71969 71970 // The tabs panel will mount before fills are rendered to the list view 71971 // slot. This means the list view tab isn't initially included in the 71972 // available tabs so the panel defaults selection to the settings tab 71973 // which at the time is the first tab. This check allows blocks known to 71974 // include the list view tab to set it as the tab selected by default. 71975 const initialTabName = !use_is_list_view_tab_disabled(blockName) ? TAB_LIST_VIEW.name : undefined; 71976 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 71977 className: "block-editor-block-inspector__tabs", 71978 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(inspector_controls_tabs_Tabs, { 71979 defaultTabId: initialTabName, 71980 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls_tabs_Tabs.TabList, { 71981 children: tabs.map(tab => showIconLabels ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls_tabs_Tabs.Tab, { 71982 tabId: tab.name, 71983 children: tab.title 71984 }, tab.name) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Tooltip, { 71985 text: tab.title, 71986 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls_tabs_Tabs.Tab, { 71987 tabId: tab.name, 71988 "aria-label": tab.title, 71989 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Icon, { 71990 icon: tab.icon 71991 }) 71992 }) 71993 }, tab.name)) 71994 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls_tabs_Tabs.TabPanel, { 71995 tabId: TAB_SETTINGS.name, 71996 focusable: false, 71997 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(settings_tab, { 71998 showAdvancedControls: !!blockName 71999 }) 72000 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls_tabs_Tabs.TabPanel, { 72001 tabId: TAB_STYLES.name, 72002 focusable: false, 72003 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(styles_tab, { 72004 blockName: blockName, 72005 clientId: clientId, 72006 hasBlockStyles: hasBlockStyles 72007 }) 72008 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls_tabs_Tabs.TabPanel, { 72009 tabId: TAB_LIST_VIEW.name, 72010 focusable: false, 72011 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72012 group: "list" 72013 }) 72014 })] 72015 }, clientId) 72016 }); 72017 } 72018 72019 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js 72020 /** 72021 * WordPress dependencies 72022 */ 72023 72024 72025 72026 /** 72027 * Internal dependencies 72028 */ 72029 72030 72031 72032 72033 72034 const use_inspector_controls_tabs_EMPTY_ARRAY = []; 72035 function getShowTabs(blockName, tabSettings = {}) { 72036 // Block specific setting takes precedence over generic default. 72037 if (tabSettings[blockName] !== undefined) { 72038 return tabSettings[blockName]; 72039 } 72040 72041 // Use generic default if set over the Gutenberg experiment option. 72042 if (tabSettings.default !== undefined) { 72043 return tabSettings.default; 72044 } 72045 return true; 72046 } 72047 function useInspectorControlsTabs(blockName) { 72048 const tabs = []; 72049 const { 72050 bindings: bindingsGroup, 72051 border: borderGroup, 72052 color: colorGroup, 72053 default: defaultGroup, 72054 dimensions: dimensionsGroup, 72055 list: listGroup, 72056 position: positionGroup, 72057 styles: stylesGroup, 72058 typography: typographyGroup, 72059 effects: effectsGroup 72060 } = inspector_controls_groups; 72061 72062 // List View Tab: If there are any fills for the list group add that tab. 72063 const listViewDisabled = use_is_list_view_tab_disabled(blockName); 72064 const listFills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(listGroup.name); 72065 const hasListFills = !listViewDisabled && !!listFills && listFills.length; 72066 72067 // Styles Tab: Add this tab if there are any fills for block supports 72068 // e.g. border, color, spacing, typography, etc. 72069 const styleFills = [...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(borderGroup.name) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(colorGroup.name) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(dimensionsGroup.name) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(stylesGroup.name) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(typographyGroup.name) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(effectsGroup.name) || [])]; 72070 const hasStyleFills = styleFills.length; 72071 72072 // Settings Tab: If we don't have multiple tabs to display 72073 // (i.e. both list view and styles), check only the default and position 72074 // InspectorControls slots. If we have multiple tabs, we'll need to check 72075 // the advanced controls slot as well to ensure they are rendered. 72076 const advancedFills = [...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(InspectorAdvancedControls.slotName) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(bindingsGroup.name) || [])]; 72077 const settingsFills = [...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(defaultGroup.name) || []), ...((0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(positionGroup.name) || []), ...(hasListFills && hasStyleFills > 1 ? advancedFills : [])]; 72078 72079 // Add the tabs in the order that they will default to if available. 72080 // List View > Settings > Styles. 72081 if (hasListFills) { 72082 tabs.push(TAB_LIST_VIEW); 72083 } 72084 if (settingsFills.length) { 72085 tabs.push(TAB_SETTINGS); 72086 } 72087 if (hasStyleFills) { 72088 tabs.push(TAB_STYLES); 72089 } 72090 const tabSettings = (0,external_wp_data_namespaceObject.useSelect)(select => { 72091 return select(store).getSettings().blockInspectorTabs; 72092 }, []); 72093 const showTabs = getShowTabs(blockName, tabSettings); 72094 return showTabs ? tabs : use_inspector_controls_tabs_EMPTY_ARRAY; 72095 } 72096 72097 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-inspector/useBlockInspectorAnimationSettings.js 72098 /** 72099 * WordPress dependencies 72100 */ 72101 72102 72103 /** 72104 * Internal dependencies 72105 */ 72106 72107 function useBlockInspectorAnimationSettings(blockType) { 72108 return (0,external_wp_data_namespaceObject.useSelect)(select => { 72109 if (blockType) { 72110 const globalBlockInspectorAnimationSettings = select(store).getSettings().blockInspectorAnimation; 72111 72112 // Get the name of the block that will allow it's children to be animated. 72113 const animationParent = globalBlockInspectorAnimationSettings?.animationParent; 72114 72115 // Determine whether the animationParent block is a parent of the selected block. 72116 const { 72117 getSelectedBlockClientId, 72118 getBlockParentsByBlockName 72119 } = select(store); 72120 const _selectedBlockClientId = getSelectedBlockClientId(); 72121 const animationParentBlockClientId = getBlockParentsByBlockName(_selectedBlockClientId, animationParent, true)[0]; 72122 72123 // If the selected block is not a child of the animationParent block, 72124 // and not an animationParent block itself, don't animate. 72125 if (!animationParentBlockClientId && blockType.name !== animationParent) { 72126 return null; 72127 } 72128 return globalBlockInspectorAnimationSettings?.[blockType.name]; 72129 } 72130 return null; 72131 }, [blockType]); 72132 } 72133 72134 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-quick-navigation/index.js 72135 /** 72136 * WordPress dependencies 72137 */ 72138 72139 72140 72141 /** 72142 * Internal dependencies 72143 */ 72144 72145 72146 72147 72148 72149 function BlockQuickNavigation({ 72150 clientIds, 72151 onSelect 72152 }) { 72153 if (!clientIds.length) { 72154 return null; 72155 } 72156 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalVStack, { 72157 spacing: 1, 72158 children: clientIds.map(clientId => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockQuickNavigationItem, { 72159 onSelect: onSelect, 72160 clientId: clientId 72161 }, clientId)) 72162 }); 72163 } 72164 function BlockQuickNavigationItem({ 72165 clientId, 72166 onSelect 72167 }) { 72168 const blockInformation = useBlockDisplayInformation(clientId); 72169 const blockTitle = useBlockDisplayTitle({ 72170 clientId, 72171 context: 'list-view' 72172 }); 72173 const { 72174 isSelected 72175 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 72176 const { 72177 isBlockSelected, 72178 hasSelectedInnerBlock 72179 } = select(store); 72180 return { 72181 isSelected: isBlockSelected(clientId) || hasSelectedInnerBlock(clientId, /* deep: */true) 72182 }; 72183 }, [clientId]); 72184 const { 72185 selectBlock 72186 } = (0,external_wp_data_namespaceObject.useDispatch)(store); 72187 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 72188 __next40pxDefaultSize: true, 72189 isPressed: isSelected, 72190 onClick: async () => { 72191 await selectBlock(clientId); 72192 if (onSelect) { 72193 onSelect(clientId); 72194 } 72195 }, 72196 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Flex, { 72197 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexItem, { 72198 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 72199 icon: blockInformation?.icon 72200 }) 72201 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.FlexBlock, { 72202 style: { 72203 textAlign: 'left' 72204 }, 72205 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalTruncate, { 72206 children: blockTitle 72207 }) 72208 })] 72209 }) 72210 }); 72211 } 72212 72213 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-inspector/index.js 72214 /** 72215 * WordPress dependencies 72216 */ 72217 72218 72219 72220 72221 72222 /** 72223 * Internal dependencies 72224 */ 72225 72226 72227 72228 72229 72230 72231 72232 72233 72234 72235 72236 72237 72238 72239 72240 72241 72242 function BlockStylesPanel({ 72243 clientId 72244 }) { 72245 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, { 72246 title: (0,external_wp_i18n_namespaceObject.__)('Styles'), 72247 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_styles, { 72248 clientId: clientId 72249 }) 72250 }); 72251 } 72252 function BlockInspector() { 72253 const { 72254 count, 72255 selectedBlockName, 72256 selectedBlockClientId, 72257 blockType, 72258 isSectionBlock 72259 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 72260 const { 72261 getSelectedBlockClientId, 72262 getSelectedBlockCount, 72263 getBlockName, 72264 getParentSectionBlock, 72265 isSectionBlock: _isSectionBlock 72266 } = unlock(select(store)); 72267 const _selectedBlockClientId = getSelectedBlockClientId(); 72268 const renderedBlockClientId = getParentSectionBlock(_selectedBlockClientId) || getSelectedBlockClientId(); 72269 const _selectedBlockName = renderedBlockClientId && getBlockName(renderedBlockClientId); 72270 const _blockType = _selectedBlockName && (0,external_wp_blocks_namespaceObject.getBlockType)(_selectedBlockName); 72271 return { 72272 count: getSelectedBlockCount(), 72273 selectedBlockClientId: renderedBlockClientId, 72274 selectedBlockName: _selectedBlockName, 72275 blockType: _blockType, 72276 isSectionBlock: _isSectionBlock(renderedBlockClientId) 72277 }; 72278 }, []); 72279 const availableTabs = useInspectorControlsTabs(blockType?.name); 72280 const showTabs = availableTabs?.length > 1; 72281 72282 // The block inspector animation settings will be completely 72283 // removed in the future to create an API which allows the block 72284 // inspector to transition between what it 72285 // displays based on the relationship between the selected block 72286 // and its parent, and only enable it if the parent is controlling 72287 // its children blocks. 72288 const blockInspectorAnimationSettings = useBlockInspectorAnimationSettings(blockType); 72289 const borderPanelLabel = useBorderPanelLabel({ 72290 blockName: selectedBlockName 72291 }); 72292 if (count > 1 && !isSectionBlock) { 72293 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 72294 className: "block-editor-block-inspector", 72295 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(MultiSelectionInspector, {}), showTabs ? /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorControlsTabs, { 72296 tabs: availableTabs 72297 }) : /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 72298 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72299 group: "color", 72300 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 72301 className: "color-block-support-panel__inner-wrapper" 72302 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72303 group: "background", 72304 label: (0,external_wp_i18n_namespaceObject.__)('Background image') 72305 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72306 group: "typography", 72307 label: (0,external_wp_i18n_namespaceObject.__)('Typography') 72308 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72309 group: "dimensions", 72310 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions') 72311 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72312 group: "border", 72313 label: borderPanelLabel 72314 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72315 group: "styles" 72316 })] 72317 })] 72318 }); 72319 } 72320 const isSelectedBlockUnregistered = selectedBlockName === (0,external_wp_blocks_namespaceObject.getUnregisteredTypeHandlerName)(); 72321 72322 /* 72323 * If the selected block is of an unregistered type, avoid showing it as an actual selection 72324 * because we want the user to focus on the unregistered block warning, not block settings. 72325 */ 72326 if (!blockType || !selectedBlockClientId || isSelectedBlockUnregistered) { 72327 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 72328 className: "block-editor-block-inspector__no-blocks", 72329 children: (0,external_wp_i18n_namespaceObject.__)('No block selected.') 72330 }); 72331 } 72332 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockInspectorSingleBlockWrapper, { 72333 animate: blockInspectorAnimationSettings, 72334 wrapper: children => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AnimatedContainer, { 72335 blockInspectorAnimationSettings: blockInspectorAnimationSettings, 72336 selectedBlockClientId: selectedBlockClientId, 72337 children: children 72338 }), 72339 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockInspectorSingleBlock, { 72340 clientId: selectedBlockClientId, 72341 blockName: blockType.name, 72342 isSectionBlock: isSectionBlock 72343 }) 72344 }); 72345 } 72346 const BlockInspectorSingleBlockWrapper = ({ 72347 animate, 72348 wrapper, 72349 children 72350 }) => { 72351 return animate ? wrapper(children) : children; 72352 }; 72353 const AnimatedContainer = ({ 72354 blockInspectorAnimationSettings, 72355 selectedBlockClientId, 72356 children 72357 }) => { 72358 const animationOrigin = blockInspectorAnimationSettings && blockInspectorAnimationSettings.enterDirection === 'leftToRight' ? -50 : 50; 72359 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__unstableMotion.div, { 72360 animate: { 72361 x: 0, 72362 opacity: 1, 72363 transition: { 72364 ease: 'easeInOut', 72365 duration: 0.14 72366 } 72367 }, 72368 initial: { 72369 x: animationOrigin, 72370 opacity: 0 72371 }, 72372 children: children 72373 }, selectedBlockClientId); 72374 }; 72375 const BlockInspectorSingleBlock = ({ 72376 clientId, 72377 blockName, 72378 isSectionBlock 72379 }) => { 72380 const availableTabs = useInspectorControlsTabs(blockName); 72381 const showTabs = !isSectionBlock && availableTabs?.length > 1; 72382 const hasBlockStyles = (0,external_wp_data_namespaceObject.useSelect)(select => { 72383 const { 72384 getBlockStyles 72385 } = select(external_wp_blocks_namespaceObject.store); 72386 const blockStyles = getBlockStyles(blockName); 72387 return blockStyles && blockStyles.length > 0; 72388 }, [blockName]); 72389 const blockInformation = useBlockDisplayInformation(clientId); 72390 const borderPanelLabel = useBorderPanelLabel({ 72391 blockName 72392 }); 72393 const contentClientIds = (0,external_wp_data_namespaceObject.useSelect)(select => { 72394 // Avoid unnecessary subscription. 72395 if (!isSectionBlock) { 72396 return; 72397 } 72398 const { 72399 getClientIdsOfDescendants, 72400 getBlockName, 72401 getBlockEditingMode 72402 } = select(store); 72403 return getClientIdsOfDescendants(clientId).filter(current => getBlockName(current) !== 'core/list-item' && getBlockEditingMode(current) === 'contentOnly'); 72404 }, [isSectionBlock, clientId]); 72405 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 72406 className: "block-editor-block-inspector", 72407 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_card, { 72408 ...blockInformation, 72409 className: blockInformation.isSynced && 'is-synced' 72410 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_variation_transforms, { 72411 blockClientId: clientId 72412 }), showTabs && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorControlsTabs, { 72413 hasBlockStyles: hasBlockStyles, 72414 clientId: clientId, 72415 blockName: blockName, 72416 tabs: availableTabs 72417 }), !showTabs && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 72418 children: [hasBlockStyles && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockStylesPanel, { 72419 clientId: clientId 72420 }), contentClientIds && contentClientIds?.length > 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.PanelBody, { 72421 title: (0,external_wp_i18n_namespaceObject.__)('Content'), 72422 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(BlockQuickNavigation, { 72423 clientIds: contentClientIds 72424 }) 72425 }), !isSectionBlock && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 72426 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72427 group: "list" 72428 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72429 group: "color", 72430 label: (0,external_wp_i18n_namespaceObject.__)('Color'), 72431 className: "color-block-support-panel__inner-wrapper" 72432 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72433 group: "background", 72434 label: (0,external_wp_i18n_namespaceObject.__)('Background image') 72435 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72436 group: "typography", 72437 label: (0,external_wp_i18n_namespaceObject.__)('Typography') 72438 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72439 group: "dimensions", 72440 label: (0,external_wp_i18n_namespaceObject.__)('Dimensions') 72441 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72442 group: "border", 72443 label: borderPanelLabel 72444 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72445 group: "styles" 72446 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(position_controls_panel, {}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(inspector_controls.Slot, { 72447 group: "bindings" 72448 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 72449 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(advanced_controls_panel, {}) 72450 })] 72451 })] 72452 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SkipToSelectedBlock, {}, "back")] 72453 }); 72454 }; 72455 72456 /** 72457 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-inspector/README.md 72458 */ 72459 /* harmony default export */ const block_inspector = (BlockInspector); 72460 72461 ;// ./node_modules/@wordpress/block-editor/build-module/components/copy-handler/index.js 72462 /** 72463 * WordPress dependencies 72464 */ 72465 72466 72467 /** 72468 * Internal dependencies 72469 */ 72470 72471 72472 /** 72473 * @deprecated 72474 */ 72475 72476 const __unstableUseClipboardHandler = () => { 72477 external_wp_deprecated_default()('__unstableUseClipboardHandler', { 72478 alternative: 'BlockCanvas or WritingFlow', 72479 since: '6.4', 72480 version: '6.7' 72481 }); 72482 return useClipboardHandler(); 72483 }; 72484 72485 /** 72486 * @deprecated 72487 * @param {Object} props 72488 */ 72489 function CopyHandler(props) { 72490 external_wp_deprecated_default()('CopyHandler', { 72491 alternative: 'BlockCanvas or WritingFlow', 72492 since: '6.4', 72493 version: '6.7' 72494 }); 72495 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 72496 ...props, 72497 ref: useClipboardHandler() 72498 }); 72499 } 72500 72501 ;// ./node_modules/@wordpress/block-editor/build-module/components/inserter/library.js 72502 /** 72503 * WordPress dependencies 72504 */ 72505 72506 72507 72508 /** 72509 * Internal dependencies 72510 */ 72511 72512 72513 72514 const library_noop = () => {}; 72515 function InserterLibrary({ 72516 rootClientId, 72517 clientId, 72518 isAppender, 72519 showInserterHelpPanel, 72520 showMostUsedBlocks = false, 72521 __experimentalInsertionIndex, 72522 __experimentalInitialTab, 72523 __experimentalInitialCategory, 72524 __experimentalFilterValue, 72525 onPatternCategorySelection, 72526 onSelect = library_noop, 72527 shouldFocusBlock = false, 72528 onClose 72529 }, ref) { 72530 const { 72531 destinationRootClientId 72532 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 72533 const { 72534 getBlockRootClientId 72535 } = select(store); 72536 const _rootClientId = rootClientId || getBlockRootClientId(clientId) || undefined; 72537 return { 72538 destinationRootClientId: _rootClientId 72539 }; 72540 }, [clientId, rootClientId]); 72541 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateInserterMenu, { 72542 onSelect: onSelect, 72543 rootClientId: destinationRootClientId, 72544 clientId: clientId, 72545 isAppender: isAppender, 72546 showInserterHelpPanel: showInserterHelpPanel, 72547 showMostUsedBlocks: showMostUsedBlocks, 72548 __experimentalInsertionIndex: __experimentalInsertionIndex, 72549 __experimentalFilterValue: __experimentalFilterValue, 72550 onPatternCategorySelection: onPatternCategorySelection, 72551 __experimentalInitialTab: __experimentalInitialTab, 72552 __experimentalInitialCategory: __experimentalInitialCategory, 72553 shouldFocusBlock: shouldFocusBlock, 72554 ref: ref, 72555 onClose: onClose 72556 }); 72557 } 72558 const PrivateInserterLibrary = (0,external_wp_element_namespaceObject.forwardRef)(InserterLibrary); 72559 function PublicInserterLibrary(props, ref) { 72560 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivateInserterLibrary, { 72561 ...props, 72562 onPatternCategorySelection: undefined, 72563 ref: ref 72564 }); 72565 } 72566 /* harmony default export */ const library = ((0,external_wp_element_namespaceObject.forwardRef)(PublicInserterLibrary)); 72567 72568 ;// ./node_modules/@wordpress/block-editor/build-module/components/selection-scroll-into-view/index.js 72569 /** 72570 * WordPress dependencies 72571 */ 72572 72573 72574 /** 72575 * Scrolls the multi block selection end into view if not in view already. This 72576 * is important to do after selection by keyboard. 72577 * 72578 * @deprecated 72579 */ 72580 function MultiSelectScrollIntoView() { 72581 external_wp_deprecated_default()('wp.blockEditor.MultiSelectScrollIntoView', { 72582 hint: 'This behaviour is now built-in.', 72583 since: '5.8' 72584 }); 72585 return null; 72586 } 72587 72588 ;// ./node_modules/@wordpress/block-editor/build-module/components/typewriter/index.js 72589 /** 72590 * WordPress dependencies 72591 */ 72592 72593 72594 72595 72596 72597 /** 72598 * Internal dependencies 72599 */ 72600 72601 72602 const isIE = window.navigator.userAgent.indexOf('Trident') !== -1; 72603 const arrowKeyCodes = new Set([external_wp_keycodes_namespaceObject.UP, external_wp_keycodes_namespaceObject.DOWN, external_wp_keycodes_namespaceObject.LEFT, external_wp_keycodes_namespaceObject.RIGHT]); 72604 const initialTriggerPercentage = 0.75; 72605 function useTypewriter() { 72606 const hasSelectedBlock = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).hasSelectedBlock(), []); 72607 return (0,external_wp_compose_namespaceObject.useRefEffect)(node => { 72608 if (!hasSelectedBlock) { 72609 return; 72610 } 72611 const { 72612 ownerDocument 72613 } = node; 72614 const { 72615 defaultView 72616 } = ownerDocument; 72617 let scrollResizeRafId; 72618 let onKeyDownRafId; 72619 let caretRect; 72620 function onScrollResize() { 72621 if (scrollResizeRafId) { 72622 return; 72623 } 72624 scrollResizeRafId = defaultView.requestAnimationFrame(() => { 72625 computeCaretRectangle(); 72626 scrollResizeRafId = null; 72627 }); 72628 } 72629 function onKeyDown(event) { 72630 // Ensure the any remaining request is cancelled. 72631 if (onKeyDownRafId) { 72632 defaultView.cancelAnimationFrame(onKeyDownRafId); 72633 } 72634 72635 // Use an animation frame for a smooth result. 72636 onKeyDownRafId = defaultView.requestAnimationFrame(() => { 72637 maintainCaretPosition(event); 72638 onKeyDownRafId = null; 72639 }); 72640 } 72641 72642 /** 72643 * Maintains the scroll position after a selection change caused by a 72644 * keyboard event. 72645 * 72646 * @param {KeyboardEvent} event Keyboard event. 72647 */ 72648 function maintainCaretPosition({ 72649 keyCode 72650 }) { 72651 if (!isSelectionEligibleForScroll()) { 72652 return; 72653 } 72654 const currentCaretRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView); 72655 if (!currentCaretRect) { 72656 return; 72657 } 72658 72659 // If for some reason there is no position set to be scrolled to, let 72660 // this be the position to be scrolled to in the future. 72661 if (!caretRect) { 72662 caretRect = currentCaretRect; 72663 return; 72664 } 72665 72666 // Even though enabling the typewriter effect for arrow keys results in 72667 // a pleasant experience, it may not be the case for everyone, so, for 72668 // now, let's disable it. 72669 if (arrowKeyCodes.has(keyCode)) { 72670 // Reset the caret position to maintain. 72671 caretRect = currentCaretRect; 72672 return; 72673 } 72674 const diff = currentCaretRect.top - caretRect.top; 72675 if (diff === 0) { 72676 return; 72677 } 72678 const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(node); 72679 72680 // The page must be scrollable. 72681 if (!scrollContainer) { 72682 return; 72683 } 72684 const windowScroll = scrollContainer === ownerDocument.body || scrollContainer === ownerDocument.documentElement; 72685 const scrollY = windowScroll ? defaultView.scrollY : scrollContainer.scrollTop; 72686 const scrollContainerY = windowScroll ? 0 : scrollContainer.getBoundingClientRect().top; 72687 const relativeScrollPosition = windowScroll ? caretRect.top / defaultView.innerHeight : (caretRect.top - scrollContainerY) / (defaultView.innerHeight - scrollContainerY); 72688 72689 // If the scroll position is at the start, the active editable element 72690 // is the last one, and the caret is positioned within the initial 72691 // trigger percentage of the page, do not scroll the page. 72692 // The typewriter effect should not kick in until an empty page has been 72693 // filled with the initial trigger percentage or the user scrolls 72694 // intentionally down. 72695 if (scrollY === 0 && relativeScrollPosition < initialTriggerPercentage && isLastEditableNode()) { 72696 // Reset the caret position to maintain. 72697 caretRect = currentCaretRect; 72698 return; 72699 } 72700 const scrollContainerHeight = windowScroll ? defaultView.innerHeight : scrollContainer.clientHeight; 72701 72702 // Abort if the target scroll position would scroll the caret out of 72703 // view. 72704 if ( 72705 // The caret is under the lower fold. 72706 caretRect.top + caretRect.height > scrollContainerY + scrollContainerHeight || 72707 // The caret is above the upper fold. 72708 caretRect.top < scrollContainerY) { 72709 // Reset the caret position to maintain. 72710 caretRect = currentCaretRect; 72711 return; 72712 } 72713 if (windowScroll) { 72714 defaultView.scrollBy(0, diff); 72715 } else { 72716 scrollContainer.scrollTop += diff; 72717 } 72718 } 72719 72720 /** 72721 * Adds a `selectionchange` listener to reset the scroll position to be 72722 * maintained. 72723 */ 72724 function addSelectionChangeListener() { 72725 ownerDocument.addEventListener('selectionchange', computeCaretRectOnSelectionChange); 72726 } 72727 72728 /** 72729 * Resets the scroll position to be maintained during a `selectionchange` 72730 * event. Also removes the listener, so it acts as a one-time listener. 72731 */ 72732 function computeCaretRectOnSelectionChange() { 72733 ownerDocument.removeEventListener('selectionchange', computeCaretRectOnSelectionChange); 72734 computeCaretRectangle(); 72735 } 72736 72737 /** 72738 * Resets the scroll position to be maintained. 72739 */ 72740 function computeCaretRectangle() { 72741 if (isSelectionEligibleForScroll()) { 72742 caretRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView); 72743 } 72744 } 72745 72746 /** 72747 * Checks if the current situation is eligible for scroll: 72748 * - There should be one and only one block selected. 72749 * - The component must contain the selection. 72750 * - The active element must be contenteditable. 72751 */ 72752 function isSelectionEligibleForScroll() { 72753 return node.contains(ownerDocument.activeElement) && ownerDocument.activeElement.isContentEditable; 72754 } 72755 function isLastEditableNode() { 72756 const editableNodes = node.querySelectorAll('[contenteditable="true"]'); 72757 const lastEditableNode = editableNodes[editableNodes.length - 1]; 72758 return lastEditableNode === ownerDocument.activeElement; 72759 } 72760 72761 // When the user scrolls or resizes, the scroll position should be 72762 // reset. 72763 defaultView.addEventListener('scroll', onScrollResize, true); 72764 defaultView.addEventListener('resize', onScrollResize, true); 72765 node.addEventListener('keydown', onKeyDown); 72766 node.addEventListener('keyup', maintainCaretPosition); 72767 node.addEventListener('mousedown', addSelectionChangeListener); 72768 node.addEventListener('touchstart', addSelectionChangeListener); 72769 return () => { 72770 defaultView.removeEventListener('scroll', onScrollResize, true); 72771 defaultView.removeEventListener('resize', onScrollResize, true); 72772 node.removeEventListener('keydown', onKeyDown); 72773 node.removeEventListener('keyup', maintainCaretPosition); 72774 node.removeEventListener('mousedown', addSelectionChangeListener); 72775 node.removeEventListener('touchstart', addSelectionChangeListener); 72776 ownerDocument.removeEventListener('selectionchange', computeCaretRectOnSelectionChange); 72777 defaultView.cancelAnimationFrame(scrollResizeRafId); 72778 defaultView.cancelAnimationFrame(onKeyDownRafId); 72779 }; 72780 }, [hasSelectedBlock]); 72781 } 72782 function Typewriter({ 72783 children 72784 }) { 72785 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("div", { 72786 ref: useTypewriter(), 72787 className: "block-editor__typewriter", 72788 children: children 72789 }); 72790 } 72791 72792 /** 72793 * The exported component. The implementation of Typewriter faced technical 72794 * challenges in Internet Explorer, and is simply skipped, rendering the given 72795 * props children instead. 72796 * 72797 * @type {Component} 72798 */ 72799 const TypewriterOrIEBypass = isIE ? props => props.children : Typewriter; 72800 72801 /** 72802 * Ensures that the text selection keeps the same vertical distance from the 72803 * viewport during keyboard events within this component. The vertical distance 72804 * can vary. It is the last clicked or scrolled to position. 72805 */ 72806 /* harmony default export */ const typewriter = (TypewriterOrIEBypass); 72807 72808 ;// ./node_modules/@wordpress/block-editor/build-module/components/recursion-provider/index.js 72809 /** 72810 * WordPress dependencies 72811 */ 72812 72813 72814 72815 /** 72816 * Internal dependencies 72817 */ 72818 72819 72820 const RenderedRefsContext = (0,external_wp_element_namespaceObject.createContext)({}); 72821 72822 /** 72823 * Immutably adds an unique identifier to a set scoped for a given block type. 72824 * 72825 * @param {Object} renderedBlocks Rendered blocks grouped by block name 72826 * @param {string} blockName Name of the block. 72827 * @param {*} uniqueId Any value that acts as a unique identifier for a block instance. 72828 * 72829 * @return {Object} The list of rendered blocks grouped by block name. 72830 */ 72831 function addToBlockType(renderedBlocks, blockName, uniqueId) { 72832 const result = { 72833 ...renderedBlocks, 72834 [blockName]: renderedBlocks[blockName] ? new Set(renderedBlocks[blockName]) : new Set() 72835 }; 72836 result[blockName].add(uniqueId); 72837 return result; 72838 } 72839 72840 /** 72841 * A React context provider for use with the `useHasRecursion` hook to prevent recursive 72842 * renders. 72843 * 72844 * Wrap block content with this provider and provide the same `uniqueId` prop as used 72845 * with `useHasRecursion`. 72846 * 72847 * @param {Object} props 72848 * @param {*} props.uniqueId Any value that acts as a unique identifier for a block instance. 72849 * @param {string} props.blockName Optional block name. 72850 * @param {JSX.Element} props.children React children. 72851 * 72852 * @return {JSX.Element} A React element. 72853 */ 72854 function RecursionProvider({ 72855 children, 72856 uniqueId, 72857 blockName = '' 72858 }) { 72859 const previouslyRenderedBlocks = (0,external_wp_element_namespaceObject.useContext)(RenderedRefsContext); 72860 const { 72861 name 72862 } = useBlockEditContext(); 72863 blockName = blockName || name; 72864 const newRenderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => addToBlockType(previouslyRenderedBlocks, blockName, uniqueId), [previouslyRenderedBlocks, blockName, uniqueId]); 72865 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RenderedRefsContext.Provider, { 72866 value: newRenderedBlocks, 72867 children: children 72868 }); 72869 } 72870 72871 /** 72872 * A React hook for keeping track of blocks previously rendered up in the block 72873 * tree. Blocks susceptible to recursion can use this hook in their `Edit` 72874 * function to prevent said recursion. 72875 * 72876 * Use this with the `RecursionProvider` component, using the same `uniqueId` value 72877 * for both the hook and the provider. 72878 * 72879 * @param {*} uniqueId Any value that acts as a unique identifier for a block instance. 72880 * @param {string} blockName Optional block name. 72881 * 72882 * @return {boolean} A boolean describing whether the provided id has already been rendered. 72883 */ 72884 function useHasRecursion(uniqueId, blockName = '') { 72885 const previouslyRenderedBlocks = (0,external_wp_element_namespaceObject.useContext)(RenderedRefsContext); 72886 const { 72887 name 72888 } = useBlockEditContext(); 72889 blockName = blockName || name; 72890 return Boolean(previouslyRenderedBlocks[blockName]?.has(uniqueId)); 72891 } 72892 const DeprecatedExperimentalRecursionProvider = props => { 72893 external_wp_deprecated_default()('wp.blockEditor.__experimentalRecursionProvider', { 72894 since: '6.5', 72895 alternative: 'wp.blockEditor.RecursionProvider' 72896 }); 72897 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(RecursionProvider, { 72898 ...props 72899 }); 72900 }; 72901 const DeprecatedExperimentalUseHasRecursion = (...args) => { 72902 external_wp_deprecated_default()('wp.blockEditor.__experimentalUseHasRecursion', { 72903 since: '6.5', 72904 alternative: 'wp.blockEditor.useHasRecursion' 72905 }); 72906 return useHasRecursion(...args); 72907 }; 72908 72909 ;// ./node_modules/@wordpress/block-editor/build-module/components/inspector-popover-header/index.js 72910 /** 72911 * WordPress dependencies 72912 */ 72913 72914 72915 72916 72917 function InspectorPopoverHeader({ 72918 title, 72919 help, 72920 actions = [], 72921 onClose 72922 }) { 72923 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 72924 className: "block-editor-inspector-popover-header", 72925 spacing: 4, 72926 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 72927 alignment: "center", 72928 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalHeading, { 72929 className: "block-editor-inspector-popover-header__heading", 72930 level: 2, 72931 size: 13, 72932 children: title 72933 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalSpacer, {}), actions.map(({ 72934 label, 72935 icon, 72936 onClick 72937 }) => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 72938 size: "small", 72939 className: "block-editor-inspector-popover-header__action", 72940 label: label, 72941 icon: icon, 72942 variant: !icon && 'tertiary', 72943 onClick: onClick, 72944 children: !icon && label 72945 }, label)), onClose && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 72946 size: "small", 72947 className: "block-editor-inspector-popover-header__action", 72948 label: (0,external_wp_i18n_namespaceObject.__)('Close'), 72949 icon: close_small, 72950 onClick: onClose 72951 })] 72952 }), help && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalText, { 72953 children: help 72954 })] 72955 }); 72956 } 72957 72958 ;// ./node_modules/@wordpress/block-editor/build-module/components/publish-date-time-picker/index.js 72959 /** 72960 * WordPress dependencies 72961 */ 72962 72963 72964 72965 72966 72967 /** 72968 * Internal dependencies 72969 */ 72970 72971 72972 function PublishDateTimePicker({ 72973 onClose, 72974 onChange, 72975 showPopoverHeaderActions, 72976 isCompact, 72977 currentDate, 72978 ...additionalProps 72979 }, ref) { 72980 const datePickerProps = { 72981 startOfWeek: (0,external_wp_date_namespaceObject.getSettings)().l10n.startOfWeek, 72982 onChange, 72983 currentDate: isCompact ? undefined : currentDate, 72984 currentTime: isCompact ? currentDate : undefined, 72985 ...additionalProps 72986 }; 72987 const DatePickerComponent = isCompact ? external_wp_components_namespaceObject.TimePicker : external_wp_components_namespaceObject.DateTimePicker; 72988 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 72989 ref: ref, 72990 className: "block-editor-publish-date-time-picker", 72991 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(InspectorPopoverHeader, { 72992 title: (0,external_wp_i18n_namespaceObject.__)('Publish'), 72993 actions: showPopoverHeaderActions ? [{ 72994 label: (0,external_wp_i18n_namespaceObject.__)('Now'), 72995 onClick: () => onChange?.(null) 72996 }] : undefined, 72997 onClose: onClose 72998 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DatePickerComponent, { 72999 ...datePickerProps 73000 })] 73001 }); 73002 } 73003 const PrivatePublishDateTimePicker = (0,external_wp_element_namespaceObject.forwardRef)(PublishDateTimePicker); 73004 function PublicPublishDateTimePicker(props, ref) { 73005 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(PrivatePublishDateTimePicker, { 73006 ...props, 73007 showPopoverHeaderActions: true, 73008 isCompact: false, 73009 ref: ref 73010 }); 73011 } 73012 /* harmony default export */ const publish_date_time_picker = ((0,external_wp_element_namespaceObject.forwardRef)(PublicPublishDateTimePicker)); 73013 73014 ;// ./node_modules/@wordpress/block-editor/build-module/components/index.js 73015 /* 73016 * Block Creation Components 73017 */ 73018 73019 73020 73021 73022 73023 73024 73025 73026 73027 73028 73029 73030 73031 73032 73033 73034 73035 73036 73037 73038 73039 73040 73041 73042 73043 73044 73045 73046 73047 73048 73049 73050 73051 73052 73053 73054 73055 73056 73057 73058 73059 73060 73061 73062 73063 73064 73065 73066 73067 73068 73069 73070 73071 73072 73073 73074 73075 73076 73077 73078 73079 73080 73081 73082 73083 73084 73085 73086 73087 73088 /* 73089 * Content Related Components 73090 */ 73091 73092 73093 73094 73095 73096 73097 73098 73099 73100 73101 73102 73103 73104 73105 73106 73107 73108 73109 73110 73111 73112 73113 73114 73115 73116 73117 73118 73119 73120 73121 73122 73123 73124 73125 73126 73127 73128 73129 73130 73131 /* 73132 * State Related Components 73133 */ 73134 73135 73136 73137 73138 73139 ;// ./node_modules/@wordpress/block-editor/build-module/elements/index.js 73140 const elements_ELEMENT_CLASS_NAMES = { 73141 button: 'wp-element-button', 73142 caption: 'wp-element-caption' 73143 }; 73144 const __experimentalGetElementClassName = element => { 73145 return elements_ELEMENT_CLASS_NAMES[element] ? elements_ELEMENT_CLASS_NAMES[element] : ''; 73146 }; 73147 73148 ;// ./node_modules/@wordpress/block-editor/build-module/utils/get-px-from-css-unit.js 73149 /** 73150 * This function was accidentally exposed for mobile/native usage. 73151 * 73152 * @deprecated 73153 * 73154 * @return {string} Empty string. 73155 */ 73156 /* harmony default export */ const get_px_from_css_unit = (() => ''); 73157 73158 ;// ./node_modules/@wordpress/block-editor/build-module/utils/index.js 73159 73160 73161 73162 73163 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/image-settings-panel.js 73164 /** 73165 * WordPress dependencies 73166 */ 73167 73168 73169 73170 /** 73171 * Internal dependencies 73172 */ 73173 73174 73175 function useHasImageSettingsPanel(name, value, inheritedValue) { 73176 // Note: If lightbox `value` exists, that means it was 73177 // defined via the the Global Styles UI and will NOT 73178 // be a boolean value or contain the `allowEditing` property, 73179 // so we should show the settings panel in those cases. 73180 return name === 'core/image' && inheritedValue?.lightbox?.allowEditing || !!value?.lightbox; 73181 } 73182 function ImageSettingsPanel({ 73183 onChange, 73184 value, 73185 inheritedValue, 73186 panelId 73187 }) { 73188 const dropdownMenuProps = useToolsPanelDropdownMenuProps(); 73189 const resetLightbox = () => { 73190 onChange(undefined); 73191 }; 73192 const onChangeLightbox = newSetting => { 73193 onChange({ 73194 enabled: newSetting 73195 }); 73196 }; 73197 let lightboxChecked = false; 73198 if (inheritedValue?.lightbox?.enabled) { 73199 lightboxChecked = inheritedValue.lightbox.enabled; 73200 } 73201 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_ReactJSXRuntime_namespaceObject.Fragment, { 73202 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanel, { 73203 label: (0,external_wp_i18n_namespaceObject._x)('Settings', 'Image settings'), 73204 resetAll: resetLightbox, 73205 panelId: panelId, 73206 dropdownMenuProps: dropdownMenuProps, 73207 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem 73208 // We use the `userSettings` prop instead of `settings`, because `settings` 73209 // contains the core/theme values for the lightbox and we want to show the 73210 // "RESET" button ONLY when the user has explicitly set a value in the 73211 // Global Styles. 73212 , { 73213 hasValue: () => !!value?.lightbox, 73214 label: (0,external_wp_i18n_namespaceObject.__)('Enlarge on click'), 73215 onDeselect: resetLightbox, 73216 isShownByDefault: true, 73217 panelId: panelId, 73218 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToggleControl, { 73219 __nextHasNoMarginBottom: true, 73220 label: (0,external_wp_i18n_namespaceObject.__)('Enlarge on click'), 73221 checked: lightboxChecked, 73222 onChange: onChangeLightbox 73223 }) 73224 }) 73225 }) 73226 }); 73227 } 73228 73229 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/advanced-panel.js 73230 /** 73231 * WordPress dependencies 73232 */ 73233 73234 73235 73236 73237 /** 73238 * Internal dependencies 73239 */ 73240 73241 73242 function AdvancedPanel({ 73243 value, 73244 onChange, 73245 inheritedValue = value 73246 }) { 73247 // Custom CSS 73248 const [cssError, setCSSError] = (0,external_wp_element_namespaceObject.useState)(null); 73249 const customCSS = inheritedValue?.css; 73250 function handleOnChange(newValue) { 73251 onChange({ 73252 ...value, 73253 css: newValue 73254 }); 73255 if (cssError) { 73256 // Check if the new value is valid CSS, and pass a wrapping selector 73257 // to ensure that `transformStyles` validates the CSS. Note that the 73258 // wrapping selector here is not used in the actual output of any styles. 73259 const [transformed] = transform_styles([{ 73260 css: newValue 73261 }], '.for-validation-only'); 73262 if (transformed) { 73263 setCSSError(null); 73264 } 73265 } 73266 } 73267 function handleOnBlur(event) { 73268 if (!event?.target?.value) { 73269 setCSSError(null); 73270 return; 73271 } 73272 73273 // Check if the new value is valid CSS, and pass a wrapping selector 73274 // to ensure that `transformStyles` validates the CSS. Note that the 73275 // wrapping selector here is not used in the actual output of any styles. 73276 const [transformed] = transform_styles([{ 73277 css: event.target.value 73278 }], '.for-validation-only'); 73279 setCSSError(transformed === null ? (0,external_wp_i18n_namespaceObject.__)('There is an error with your CSS structure.') : null); 73280 } 73281 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalVStack, { 73282 spacing: 3, 73283 children: [cssError && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Notice, { 73284 status: "error", 73285 onRemove: () => setCSSError(null), 73286 children: cssError 73287 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.TextareaControl, { 73288 label: (0,external_wp_i18n_namespaceObject.__)('Additional CSS'), 73289 __nextHasNoMarginBottom: true, 73290 value: customCSS, 73291 onChange: newValue => handleOnChange(newValue), 73292 onBlur: handleOnBlur, 73293 className: "block-editor-global-styles-advanced-panel__custom-css-input", 73294 spellCheck: false 73295 })] 73296 }); 73297 } 73298 73299 ;// ./node_modules/memize/dist/index.js 73300 /** 73301 * Memize options object. 73302 * 73303 * @typedef MemizeOptions 73304 * 73305 * @property {number} [maxSize] Maximum size of the cache. 73306 */ 73307 73308 /** 73309 * Internal cache entry. 73310 * 73311 * @typedef MemizeCacheNode 73312 * 73313 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 73314 * @property {?MemizeCacheNode|undefined} [next] Next node. 73315 * @property {Array<*>} args Function arguments for cache 73316 * entry. 73317 * @property {*} val Function result. 73318 */ 73319 73320 /** 73321 * Properties of the enhanced function for controlling cache. 73322 * 73323 * @typedef MemizeMemoizedFunction 73324 * 73325 * @property {()=>void} clear Clear the cache. 73326 */ 73327 73328 /** 73329 * Accepts a function to be memoized, and returns a new memoized function, with 73330 * optional options. 73331 * 73332 * @template {(...args: any[]) => any} F 73333 * 73334 * @param {F} fn Function to memoize. 73335 * @param {MemizeOptions} [options] Options object. 73336 * 73337 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 73338 */ 73339 function memize(fn, options) { 73340 var size = 0; 73341 73342 /** @type {?MemizeCacheNode|undefined} */ 73343 var head; 73344 73345 /** @type {?MemizeCacheNode|undefined} */ 73346 var tail; 73347 73348 options = options || {}; 73349 73350 function memoized(/* ...args */) { 73351 var node = head, 73352 len = arguments.length, 73353 args, 73354 i; 73355 73356 searchCache: while (node) { 73357 // Perform a shallow equality test to confirm that whether the node 73358 // under test is a candidate for the arguments passed. Two arrays 73359 // are shallowly equal if their length matches and each entry is 73360 // strictly equal between the two sets. Avoid abstracting to a 73361 // function which could incur an arguments leaking deoptimization. 73362 73363 // Check whether node arguments match arguments length 73364 if (node.args.length !== arguments.length) { 73365 node = node.next; 73366 continue; 73367 } 73368 73369 // Check whether node arguments match arguments values 73370 for (i = 0; i < len; i++) { 73371 if (node.args[i] !== arguments[i]) { 73372 node = node.next; 73373 continue searchCache; 73374 } 73375 } 73376 73377 // At this point we can assume we've found a match 73378 73379 // Surface matched node to head if not already 73380 if (node !== head) { 73381 // As tail, shift to previous. Must only shift if not also 73382 // head, since if both head and tail, there is no previous. 73383 if (node === tail) { 73384 tail = node.prev; 73385 } 73386 73387 // Adjust siblings to point to each other. If node was tail, 73388 // this also handles new tail's empty `next` assignment. 73389 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 73390 if (node.next) { 73391 node.next.prev = node.prev; 73392 } 73393 73394 node.next = head; 73395 node.prev = null; 73396 /** @type {MemizeCacheNode} */ (head).prev = node; 73397 head = node; 73398 } 73399 73400 // Return immediately 73401 return node.val; 73402 } 73403 73404 // No cached value found. Continue to insertion phase: 73405 73406 // Create a copy of arguments (avoid leaking deoptimization) 73407 args = new Array(len); 73408 for (i = 0; i < len; i++) { 73409 args[i] = arguments[i]; 73410 } 73411 73412 node = { 73413 args: args, 73414 73415 // Generate the result from original function 73416 val: fn.apply(null, args), 73417 }; 73418 73419 // Don't need to check whether node is already head, since it would 73420 // have been returned above already if it was 73421 73422 // Shift existing head down list 73423 if (head) { 73424 head.prev = node; 73425 node.next = head; 73426 } else { 73427 // If no head, follows that there's no tail (at initial or reset) 73428 tail = node; 73429 } 73430 73431 // Trim tail if we're reached max size and are pending cache insertion 73432 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 73433 tail = /** @type {MemizeCacheNode} */ (tail).prev; 73434 /** @type {MemizeCacheNode} */ (tail).next = null; 73435 } else { 73436 size++; 73437 } 73438 73439 head = node; 73440 73441 return node.val; 73442 } 73443 73444 memoized.clear = function () { 73445 head = null; 73446 tail = null; 73447 size = 0; 73448 }; 73449 73450 // Ignore reason: There's not a clear solution to create an intersection of 73451 // the function with additional properties, where the goal is to retain the 73452 // function signature of the incoming argument and add control properties 73453 // on the return value. 73454 73455 // @ts-ignore 73456 return memoized; 73457 } 73458 73459 73460 73461 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/get-global-styles-changes.js 73462 /** 73463 * External dependencies 73464 */ 73465 73466 73467 /** 73468 * WordPress dependencies 73469 */ 73470 73471 73472 const globalStylesChangesCache = new Map(); 73473 const get_global_styles_changes_EMPTY_ARRAY = []; 73474 const translationMap = { 73475 caption: (0,external_wp_i18n_namespaceObject.__)('Caption'), 73476 link: (0,external_wp_i18n_namespaceObject.__)('Link'), 73477 button: (0,external_wp_i18n_namespaceObject.__)('Button'), 73478 heading: (0,external_wp_i18n_namespaceObject.__)('Heading'), 73479 h1: (0,external_wp_i18n_namespaceObject.__)('H1'), 73480 h2: (0,external_wp_i18n_namespaceObject.__)('H2'), 73481 h3: (0,external_wp_i18n_namespaceObject.__)('H3'), 73482 h4: (0,external_wp_i18n_namespaceObject.__)('H4'), 73483 h5: (0,external_wp_i18n_namespaceObject.__)('H5'), 73484 h6: (0,external_wp_i18n_namespaceObject.__)('H6'), 73485 'settings.color': (0,external_wp_i18n_namespaceObject.__)('Color'), 73486 'settings.typography': (0,external_wp_i18n_namespaceObject.__)('Typography'), 73487 'styles.color': (0,external_wp_i18n_namespaceObject.__)('Colors'), 73488 'styles.spacing': (0,external_wp_i18n_namespaceObject.__)('Spacing'), 73489 'styles.background': (0,external_wp_i18n_namespaceObject.__)('Background'), 73490 'styles.typography': (0,external_wp_i18n_namespaceObject.__)('Typography') 73491 }; 73492 const getBlockNames = memize(() => (0,external_wp_blocks_namespaceObject.getBlockTypes)().reduce((accumulator, { 73493 name, 73494 title 73495 }) => { 73496 accumulator[name] = title; 73497 return accumulator; 73498 }, {})); 73499 const isObject = obj => obj !== null && typeof obj === 'object'; 73500 73501 /** 73502 * Get the translation for a given global styles key. 73503 * @param {string} key A key representing a path to a global style property or setting. 73504 * @return {string|undefined} A translated key or undefined if no translation exists. 73505 */ 73506 function getTranslation(key) { 73507 if (translationMap[key]) { 73508 return translationMap[key]; 73509 } 73510 const keyArray = key.split('.'); 73511 if (keyArray?.[0] === 'blocks') { 73512 const blockName = getBlockNames()?.[keyArray[1]]; 73513 return blockName || keyArray[1]; 73514 } 73515 if (keyArray?.[0] === 'elements') { 73516 return translationMap[keyArray[1]] || keyArray[1]; 73517 } 73518 return undefined; 73519 } 73520 73521 /** 73522 * A deep comparison of two objects, optimized for comparing global styles. 73523 * @param {Object} changedObject The changed object to compare. 73524 * @param {Object} originalObject The original object to compare against. 73525 * @param {string} parentPath A key/value pair object of block names and their rendered titles. 73526 * @return {string[]} An array of paths whose values have changed. 73527 */ 73528 function deepCompare(changedObject, originalObject, parentPath = '') { 73529 // We have two non-object values to compare. 73530 if (!isObject(changedObject) && !isObject(originalObject)) { 73531 /* 73532 * Only return a path if the value has changed. 73533 * And then only the path name up to 2 levels deep. 73534 */ 73535 return changedObject !== originalObject ? parentPath.split('.').slice(0, 2).join('.') : undefined; 73536 } 73537 73538 // Enable comparison when an object doesn't have a corresponding property to compare. 73539 changedObject = isObject(changedObject) ? changedObject : {}; 73540 originalObject = isObject(originalObject) ? originalObject : {}; 73541 const allKeys = new Set([...Object.keys(changedObject), ...Object.keys(originalObject)]); 73542 let diffs = []; 73543 for (const key of allKeys) { 73544 const path = parentPath ? parentPath + '.' + key : key; 73545 const changedPath = deepCompare(changedObject[key], originalObject[key], path); 73546 if (changedPath) { 73547 diffs = diffs.concat(changedPath); 73548 } 73549 } 73550 return diffs; 73551 } 73552 73553 /** 73554 * Returns an array of translated summarized global styles changes. 73555 * Results are cached using a Map() key of `JSON.stringify( { next, previous } )`. 73556 * 73557 * @param {Object} next The changed object to compare. 73558 * @param {Object} previous The original object to compare against. 73559 * @return {Array[]} A 2-dimensional array of tuples: [ "group", "translated change" ]. 73560 */ 73561 function getGlobalStylesChangelist(next, previous) { 73562 const cacheKey = JSON.stringify({ 73563 next, 73564 previous 73565 }); 73566 if (globalStylesChangesCache.has(cacheKey)) { 73567 return globalStylesChangesCache.get(cacheKey); 73568 } 73569 73570 /* 73571 * Compare the two changesets with normalized keys. 73572 * The order of these keys determines the order in which 73573 * they'll appear in the results. 73574 */ 73575 const changedValueTree = deepCompare({ 73576 styles: { 73577 background: next?.styles?.background, 73578 color: next?.styles?.color, 73579 typography: next?.styles?.typography, 73580 spacing: next?.styles?.spacing 73581 }, 73582 blocks: next?.styles?.blocks, 73583 elements: next?.styles?.elements, 73584 settings: next?.settings 73585 }, { 73586 styles: { 73587 background: previous?.styles?.background, 73588 color: previous?.styles?.color, 73589 typography: previous?.styles?.typography, 73590 spacing: previous?.styles?.spacing 73591 }, 73592 blocks: previous?.styles?.blocks, 73593 elements: previous?.styles?.elements, 73594 settings: previous?.settings 73595 }); 73596 if (!changedValueTree.length) { 73597 globalStylesChangesCache.set(cacheKey, get_global_styles_changes_EMPTY_ARRAY); 73598 return get_global_styles_changes_EMPTY_ARRAY; 73599 } 73600 73601 // Remove duplicate results. 73602 const result = [...new Set(changedValueTree)] 73603 /* 73604 * Translate the keys. 73605 * Remove empty translations. 73606 */.reduce((acc, curr) => { 73607 const translation = getTranslation(curr); 73608 if (translation) { 73609 acc.push([curr.split('.')[0], translation]); 73610 } 73611 return acc; 73612 }, []); 73613 globalStylesChangesCache.set(cacheKey, result); 73614 return result; 73615 } 73616 73617 /** 73618 * From a getGlobalStylesChangelist() result, returns an array of translated global styles changes, grouped by type. 73619 * The types are 'blocks', 'elements', 'settings', and 'styles'. 73620 * 73621 * @param {Object} next The changed object to compare. 73622 * @param {Object} previous The original object to compare against. 73623 * @param {{maxResults:number}} options Options. maxResults: results to return before truncating. 73624 * @return {string[]} An array of translated changes. 73625 */ 73626 function getGlobalStylesChanges(next, previous, options = {}) { 73627 let changeList = getGlobalStylesChangelist(next, previous); 73628 const changesLength = changeList.length; 73629 const { 73630 maxResults 73631 } = options; 73632 if (changesLength) { 73633 // Truncate to `n` results if necessary. 73634 if (!!maxResults && changesLength > maxResults) { 73635 changeList = changeList.slice(0, maxResults); 73636 } 73637 return Object.entries(changeList.reduce((acc, curr) => { 73638 const group = acc[curr[0]] || []; 73639 if (!group.includes(curr[1])) { 73640 acc[curr[0]] = [...group, curr[1]]; 73641 } 73642 return acc; 73643 }, {})).map(([key, changeValues]) => { 73644 const changeValuesLength = changeValues.length; 73645 const joinedChangesValue = changeValues.join(/* translators: Used between list items, there is a space after the comma. */ 73646 (0,external_wp_i18n_namespaceObject.__)(', ') // eslint-disable-line @wordpress/i18n-no-flanking-whitespace 73647 ); 73648 switch (key) { 73649 case 'blocks': 73650 { 73651 return (0,external_wp_i18n_namespaceObject.sprintf)( 73652 // translators: %s: a list of block names separated by a comma. 73653 (0,external_wp_i18n_namespaceObject._n)('%s block.', '%s blocks.', changeValuesLength), joinedChangesValue); 73654 } 73655 case 'elements': 73656 { 73657 return (0,external_wp_i18n_namespaceObject.sprintf)( 73658 // translators: %s: a list of element names separated by a comma. 73659 (0,external_wp_i18n_namespaceObject._n)('%s element.', '%s elements.', changeValuesLength), joinedChangesValue); 73660 } 73661 case 'settings': 73662 { 73663 return (0,external_wp_i18n_namespaceObject.sprintf)( 73664 // translators: %s: a list of theme.json setting labels separated by a comma. 73665 (0,external_wp_i18n_namespaceObject.__)('%s settings.'), joinedChangesValue); 73666 } 73667 case 'styles': 73668 { 73669 return (0,external_wp_i18n_namespaceObject.sprintf)( 73670 // translators: %s: a list of theme.json top-level styles labels separated by a comma. 73671 (0,external_wp_i18n_namespaceObject.__)('%s styles.'), joinedChangesValue); 73672 } 73673 default: 73674 { 73675 return (0,external_wp_i18n_namespaceObject.sprintf)( 73676 // translators: %s: a list of global styles changes separated by a comma. 73677 (0,external_wp_i18n_namespaceObject.__)('%s.'), joinedChangesValue); 73678 } 73679 } 73680 }); 73681 } 73682 return get_global_styles_changes_EMPTY_ARRAY; 73683 } 73684 73685 ;// ./node_modules/@wordpress/block-editor/build-module/components/global-styles/index.js 73686 73687 73688 73689 73690 73691 73692 73693 73694 73695 73696 73697 73698 73699 73700 73701 ;// ./node_modules/@wordpress/block-editor/build-module/components/rich-text/get-rich-text-values.js 73702 /** 73703 * WordPress dependencies 73704 */ 73705 73706 73707 73708 73709 /** 73710 * Internal dependencies 73711 */ 73712 73713 73714 73715 /* 73716 * This function is similar to `@wordpress/element`'s `renderToString` function, 73717 * except that it does not render the elements to a string, but instead collects 73718 * the values of all rich text `Content` elements. 73719 */ 73720 73721 function addValuesForElement(element, values, innerBlocks) { 73722 if (null === element || undefined === element || false === element) { 73723 return; 73724 } 73725 if (Array.isArray(element)) { 73726 return addValuesForElements(element, values, innerBlocks); 73727 } 73728 switch (typeof element) { 73729 case 'string': 73730 case 'number': 73731 return; 73732 } 73733 const { 73734 type, 73735 props 73736 } = element; 73737 switch (type) { 73738 case external_wp_element_namespaceObject.StrictMode: 73739 case external_wp_element_namespaceObject.Fragment: 73740 return addValuesForElements(props.children, values, innerBlocks); 73741 case external_wp_element_namespaceObject.RawHTML: 73742 return; 73743 case inner_blocks.Content: 73744 return addValuesForBlocks(values, innerBlocks); 73745 case Content: 73746 values.push(props.value); 73747 return; 73748 } 73749 switch (typeof type) { 73750 case 'string': 73751 if (typeof props.children !== 'undefined') { 73752 return addValuesForElements(props.children, values, innerBlocks); 73753 } 73754 return; 73755 case 'function': 73756 const el = type.prototype && typeof type.prototype.render === 'function' ? new type(props).render() : type(props); 73757 return addValuesForElement(el, values, innerBlocks); 73758 } 73759 } 73760 function addValuesForElements(children, ...args) { 73761 children = Array.isArray(children) ? children : [children]; 73762 for (let i = 0; i < children.length; i++) { 73763 addValuesForElement(children[i], ...args); 73764 } 73765 } 73766 function addValuesForBlocks(values, blocks) { 73767 for (let i = 0; i < blocks.length; i++) { 73768 const { 73769 name, 73770 attributes, 73771 innerBlocks 73772 } = blocks[i]; 73773 const saveElement = (0,external_wp_blocks_namespaceObject.getSaveElement)(name, attributes, 73774 /*#__PURE__*/ 73775 // Instead of letting save elements use `useInnerBlocksProps.save`, 73776 // force them to use InnerBlocks.Content instead so we can intercept 73777 // a single component. 73778 (0,external_ReactJSXRuntime_namespaceObject.jsx)(inner_blocks.Content, {})); 73779 addValuesForElement(saveElement, values, innerBlocks); 73780 } 73781 } 73782 function getRichTextValues(blocks = []) { 73783 external_wp_blocks_namespaceObject.__unstableGetBlockProps.skipFilters = true; 73784 const values = []; 73785 addValuesForBlocks(values, blocks); 73786 external_wp_blocks_namespaceObject.__unstableGetBlockProps.skipFilters = false; 73787 return values.map(value => value instanceof external_wp_richText_namespaceObject.RichTextData ? value : external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value)); 73788 } 73789 73790 ;// ./node_modules/@wordpress/block-editor/build-module/components/resizable-box-popover/index.js 73791 /** 73792 * WordPress dependencies 73793 */ 73794 73795 73796 /** 73797 * Internal dependencies 73798 */ 73799 73800 73801 function ResizableBoxPopover({ 73802 clientId, 73803 resizableBoxProps, 73804 ...props 73805 }) { 73806 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(cover, { 73807 clientId: clientId, 73808 __unstablePopoverSlot: "block-toolbar", 73809 ...props, 73810 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ResizableBox, { 73811 ...resizableBoxProps 73812 }) 73813 }); 73814 } 73815 73816 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-manager/checklist.js 73817 /** 73818 * WordPress dependencies 73819 */ 73820 73821 73822 /** 73823 * Internal dependencies 73824 */ 73825 73826 73827 function BlockTypesChecklist({ 73828 blockTypes, 73829 value, 73830 onItemChange 73831 }) { 73832 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("ul", { 73833 className: "block-editor-block-manager__checklist", 73834 children: blockTypes.map(blockType => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("li", { 73835 className: "block-editor-block-manager__checklist-item", 73836 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 73837 __nextHasNoMarginBottom: true, 73838 label: blockType.title, 73839 checked: value.includes(blockType.name), 73840 onChange: (...args) => onItemChange(blockType, ...args) 73841 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_icon, { 73842 icon: blockType.icon 73843 })] 73844 }, blockType.name)) 73845 }); 73846 } 73847 /* harmony default export */ const checklist = (BlockTypesChecklist); 73848 73849 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-manager/category.js 73850 /** 73851 * WordPress dependencies 73852 */ 73853 73854 73855 73856 73857 /** 73858 * Internal dependencies 73859 */ 73860 73861 73862 function BlockManagerCategory({ 73863 title, 73864 blockTypes, 73865 selectedBlockTypes, 73866 onChange 73867 }) { 73868 const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockManagerCategory); 73869 const toggleVisible = (0,external_wp_element_namespaceObject.useCallback)((blockType, nextIsChecked) => { 73870 if (nextIsChecked) { 73871 onChange([...selectedBlockTypes, blockType]); 73872 } else { 73873 onChange(selectedBlockTypes.filter(({ 73874 name 73875 }) => name !== blockType.name)); 73876 } 73877 }, [selectedBlockTypes, onChange]); 73878 const toggleAllVisible = (0,external_wp_element_namespaceObject.useCallback)(nextIsChecked => { 73879 if (nextIsChecked) { 73880 onChange([...selectedBlockTypes, ...blockTypes.filter(blockType => !selectedBlockTypes.find(({ 73881 name 73882 }) => name === blockType.name))]); 73883 } else { 73884 onChange(selectedBlockTypes.filter(selectedBlockType => !blockTypes.find(({ 73885 name 73886 }) => name === selectedBlockType.name))); 73887 } 73888 }, [blockTypes, selectedBlockTypes, onChange]); 73889 if (!blockTypes.length) { 73890 return null; 73891 } 73892 const checkedBlockNames = blockTypes.map(({ 73893 name 73894 }) => name).filter(type => (selectedBlockTypes !== null && selectedBlockTypes !== void 0 ? selectedBlockTypes : []).some(selectedBlockType => selectedBlockType.name === type)); 73895 const titleId = 'block-editor-block-manager__category-title-' + instanceId; 73896 const isAllChecked = checkedBlockNames.length === blockTypes.length; 73897 const isIndeterminate = !isAllChecked && checkedBlockNames.length > 0; 73898 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 73899 role: "group", 73900 "aria-labelledby": titleId, 73901 className: "block-editor-block-manager__category", 73902 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.CheckboxControl, { 73903 __nextHasNoMarginBottom: true, 73904 checked: isAllChecked, 73905 onChange: toggleAllVisible, 73906 className: "block-editor-block-manager__category-title", 73907 indeterminate: isIndeterminate, 73908 label: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("span", { 73909 id: titleId, 73910 children: title 73911 }) 73912 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(checklist, { 73913 blockTypes: blockTypes, 73914 value: checkedBlockNames, 73915 onItemChange: toggleVisible 73916 })] 73917 }); 73918 } 73919 /* harmony default export */ const block_manager_category = (BlockManagerCategory); 73920 73921 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-manager/index.js 73922 /** 73923 * WordPress dependencies 73924 */ 73925 73926 73927 73928 73929 73930 73931 73932 73933 /** 73934 * Internal dependencies 73935 */ 73936 73937 73938 /** 73939 * Provides a list of blocks with checkboxes. 73940 * 73941 * @param {Object} props Props. 73942 * @param {Array} props.blockTypes An array of blocks. 73943 * @param {Array} props.selectedBlockTypes An array of selected blocks. 73944 * @param {Function} props.onChange Function to be called when the selected blocks change. 73945 */ 73946 73947 function BlockManager({ 73948 blockTypes, 73949 selectedBlockTypes, 73950 onChange 73951 }) { 73952 const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500); 73953 const [search, setSearch] = (0,external_wp_element_namespaceObject.useState)(''); 73954 const { 73955 categories, 73956 isMatchingSearchTerm 73957 } = (0,external_wp_data_namespaceObject.useSelect)(select => { 73958 return { 73959 categories: select(external_wp_blocks_namespaceObject.store).getCategories(), 73960 isMatchingSearchTerm: select(external_wp_blocks_namespaceObject.store).isMatchingSearchTerm 73961 }; 73962 }, []); 73963 function enableAllBlockTypes() { 73964 onChange(blockTypes); 73965 } 73966 const filteredBlockTypes = blockTypes.filter(blockType => { 73967 return !search || isMatchingSearchTerm(blockType, search); 73968 }); 73969 const numberOfHiddenBlocks = blockTypes.length - selectedBlockTypes.length; 73970 73971 // Announce search results on change 73972 (0,external_wp_element_namespaceObject.useEffect)(() => { 73973 if (!search) { 73974 return; 73975 } 73976 const count = filteredBlockTypes.length; 73977 const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of results. */ 73978 (0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count); 73979 debouncedSpeak(resultsFoundMessage); 73980 }, [filteredBlockTypes?.length, search, debouncedSpeak]); 73981 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 73982 className: "block-editor-block-manager__content", 73983 children: [!!numberOfHiddenBlocks && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 73984 className: "block-editor-block-manager__disabled-blocks-count", 73985 children: [(0,external_wp_i18n_namespaceObject.sprintf)(/* translators: %d: number of blocks. */ 73986 (0,external_wp_i18n_namespaceObject._n)('%d block is hidden.', '%d blocks are hidden.', numberOfHiddenBlocks), numberOfHiddenBlocks), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 73987 __next40pxDefaultSize: true, 73988 variant: "link", 73989 onClick: enableAllBlockTypes, 73990 children: (0,external_wp_i18n_namespaceObject.__)('Reset') 73991 })] 73992 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SearchControl, { 73993 __nextHasNoMarginBottom: true, 73994 label: (0,external_wp_i18n_namespaceObject.__)('Search for a block'), 73995 placeholder: (0,external_wp_i18n_namespaceObject.__)('Search for a block'), 73996 value: search, 73997 onChange: nextSearch => setSearch(nextSearch), 73998 className: "block-editor-block-manager__search" 73999 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)("div", { 74000 tabIndex: "0", 74001 role: "region", 74002 "aria-label": (0,external_wp_i18n_namespaceObject.__)('Available block types'), 74003 className: "block-editor-block-manager__results", 74004 children: [filteredBlockTypes.length === 0 && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 74005 className: "block-editor-block-manager__no-results", 74006 children: (0,external_wp_i18n_namespaceObject.__)('No blocks found.') 74007 }), categories.map(category => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_manager_category, { 74008 title: category.title, 74009 blockTypes: filteredBlockTypes.filter(blockType => blockType.category === category.slug), 74010 selectedBlockTypes: selectedBlockTypes, 74011 onChange: onChange 74012 }, category.slug)), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(block_manager_category, { 74013 title: (0,external_wp_i18n_namespaceObject.__)('Uncategorized'), 74014 blockTypes: filteredBlockTypes.filter(({ 74015 category 74016 }) => !category), 74017 selectedBlockTypes: selectedBlockTypes, 74018 onChange: onChange 74019 })] 74020 })] 74021 }); 74022 } 74023 74024 ;// ./node_modules/@wordpress/block-editor/build-module/components/block-removal-warning-modal/index.js 74025 /** 74026 * WordPress dependencies 74027 */ 74028 74029 74030 74031 74032 74033 /** 74034 * Internal dependencies 74035 */ 74036 74037 74038 74039 function BlockRemovalWarningModal({ 74040 rules 74041 }) { 74042 const { 74043 clientIds, 74044 selectPrevious, 74045 message 74046 } = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getRemovalPromptData()); 74047 const { 74048 clearBlockRemovalPrompt, 74049 setBlockRemovalRules, 74050 privateRemoveBlocks 74051 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store)); 74052 74053 // Load block removal rules, simultaneously signalling that the block 74054 // removal prompt is in place. 74055 (0,external_wp_element_namespaceObject.useEffect)(() => { 74056 setBlockRemovalRules(rules); 74057 return () => { 74058 setBlockRemovalRules(); 74059 }; 74060 }, [rules, setBlockRemovalRules]); 74061 if (!message) { 74062 return; 74063 } 74064 const onConfirmRemoval = () => { 74065 privateRemoveBlocks(clientIds, selectPrevious, /* force */true); 74066 clearBlockRemovalPrompt(); 74067 }; 74068 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.Modal, { 74069 title: (0,external_wp_i18n_namespaceObject.__)('Be careful!'), 74070 onRequestClose: clearBlockRemovalPrompt, 74071 size: "medium", 74072 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)("p", { 74073 children: message 74074 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_wp_components_namespaceObject.__experimentalHStack, { 74075 justify: "right", 74076 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 74077 variant: "tertiary", 74078 onClick: clearBlockRemovalPrompt, 74079 __next40pxDefaultSize: true, 74080 children: (0,external_wp_i18n_namespaceObject.__)('Cancel') 74081 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Button, { 74082 variant: "primary", 74083 onClick: onConfirmRemoval, 74084 __next40pxDefaultSize: true, 74085 children: (0,external_wp_i18n_namespaceObject.__)('Delete') 74086 })] 74087 })] 74088 }); 74089 } 74090 74091 ;// ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/scale-tool.js 74092 /** 74093 * WordPress dependencies 74094 */ 74095 74096 74097 74098 74099 /** 74100 * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps 74101 */ 74102 74103 /** 74104 * The descriptions are purposely made generic as object-fit could be used for 74105 * any replaced element. Provide your own set of options if you need different 74106 * help text or labels. 74107 * 74108 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element 74109 * 74110 * @type {SelectControlProps[]} 74111 */ 74112 74113 const DEFAULT_SCALE_OPTIONS = [{ 74114 value: 'fill', 74115 label: (0,external_wp_i18n_namespaceObject._x)('Fill', 'Scale option for dimensions control'), 74116 help: (0,external_wp_i18n_namespaceObject.__)('Fill the space by stretching the content.') 74117 }, { 74118 value: 'contain', 74119 label: (0,external_wp_i18n_namespaceObject._x)('Contain', 'Scale option for dimensions control'), 74120 help: (0,external_wp_i18n_namespaceObject.__)('Fit the content to the space without clipping.') 74121 }, { 74122 value: 'cover', 74123 label: (0,external_wp_i18n_namespaceObject._x)('Cover', 'Scale option for dimensions control'), 74124 help: (0,external_wp_i18n_namespaceObject.__)("Fill the space by clipping what doesn't fit.") 74125 }, { 74126 value: 'none', 74127 label: (0,external_wp_i18n_namespaceObject._x)('None', 'Scale option for dimensions control'), 74128 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.') 74129 }, { 74130 value: 'scale-down', 74131 label: (0,external_wp_i18n_namespaceObject._x)('Scale down', 'Scale option for dimensions control'), 74132 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.') 74133 }]; 74134 74135 /** 74136 * @callback ScaleToolPropsOnChange 74137 * @param {string} nextValue New scale value. 74138 * @return {void} 74139 */ 74140 74141 /** 74142 * @typedef {Object} ScaleToolProps 74143 * @property {string} [panelId] ID of the panel that contains the controls. 74144 * @property {string} [value] Current scale value. 74145 * @property {ScaleToolPropsOnChange} [onChange] Callback to update the scale value. 74146 * @property {SelectControlProps[]} [options] Scale options. 74147 * @property {string} [defaultValue] Default scale value. 74148 * @property {boolean} [showControl=true] Whether to show the control. 74149 * @property {boolean} [isShownByDefault=true] Whether the tool panel is shown by default. 74150 */ 74151 74152 /** 74153 * A tool to select the CSS object-fit property for the image. 74154 * 74155 * @param {ScaleToolProps} props 74156 * 74157 * @return {import('react').ReactElement} The scale tool. 74158 */ 74159 function ScaleTool({ 74160 panelId, 74161 value, 74162 onChange, 74163 options = DEFAULT_SCALE_OPTIONS, 74164 defaultValue = DEFAULT_SCALE_OPTIONS[0].value, 74165 isShownByDefault = true 74166 }) { 74167 // Match the CSS default so if the value is used directly in CSS it will look correct in the control. 74168 const displayValue = value !== null && value !== void 0 ? value : 'fill'; 74169 const scaleHelp = (0,external_wp_element_namespaceObject.useMemo)(() => { 74170 return options.reduce((acc, option) => { 74171 acc[option.value] = option.help; 74172 return acc; 74173 }, {}); 74174 }, [options]); 74175 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 74176 label: (0,external_wp_i18n_namespaceObject.__)('Scale'), 74177 isShownByDefault: isShownByDefault, 74178 hasValue: () => displayValue !== defaultValue, 74179 onDeselect: () => onChange(defaultValue), 74180 panelId: panelId, 74181 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, { 74182 __nextHasNoMarginBottom: true, 74183 label: (0,external_wp_i18n_namespaceObject.__)('Scale'), 74184 isBlock: true, 74185 help: scaleHelp[displayValue], 74186 value: displayValue, 74187 onChange: onChange, 74188 size: "__unstable-large", 74189 children: options.map(option => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOption, { 74190 ...option 74191 }, option.value)) 74192 }) 74193 }); 74194 } 74195 74196 ;// ./node_modules/@babel/runtime/helpers/esm/extends.js 74197 function extends_extends() { 74198 return extends_extends = Object.assign ? Object.assign.bind() : function (n) { 74199 for (var e = 1; e < arguments.length; e++) { 74200 var t = arguments[e]; 74201 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); 74202 } 74203 return n; 74204 }, extends_extends.apply(null, arguments); 74205 } 74206 74207 ;// ./node_modules/@emotion/memoize/dist/emotion-memoize.esm.js 74208 function memoize(fn) { 74209 var cache = Object.create(null); 74210 return function (arg) { 74211 if (cache[arg] === undefined) cache[arg] = fn(arg); 74212 return cache[arg]; 74213 }; 74214 } 74215 74216 74217 74218 ;// ./node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js 74219 74220 74221 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 74222 74223 var isPropValid = /* #__PURE__ */memoize(function (prop) { 74224 return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 74225 /* o */ 74226 && prop.charCodeAt(1) === 110 74227 /* n */ 74228 && prop.charCodeAt(2) < 91; 74229 } 74230 /* Z+1 */ 74231 ); 74232 74233 74234 74235 ;// ./node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js 74236 /* 74237 74238 Based off glamor's StyleSheet, thanks Sunil ❤️ 74239 74240 high performance StyleSheet for css-in-js systems 74241 74242 - uses multiple style tags behind the scenes for millions of rules 74243 - uses `insertRule` for appending in production for *much* faster performance 74244 74245 // usage 74246 74247 import { StyleSheet } from '@emotion/sheet' 74248 74249 let styleSheet = new StyleSheet({ key: '', container: document.head }) 74250 74251 styleSheet.insert('#box { border: 1px solid red; }') 74252 - appends a css rule into the stylesheet 74253 74254 styleSheet.flush() 74255 - empties the stylesheet of all its contents 74256 74257 */ 74258 // $FlowFixMe 74259 function sheetForTag(tag) { 74260 if (tag.sheet) { 74261 // $FlowFixMe 74262 return tag.sheet; 74263 } // this weirdness brought to you by firefox 74264 74265 /* istanbul ignore next */ 74266 74267 74268 for (var i = 0; i < document.styleSheets.length; i++) { 74269 if (document.styleSheets[i].ownerNode === tag) { 74270 // $FlowFixMe 74271 return document.styleSheets[i]; 74272 } 74273 } 74274 } 74275 74276 function createStyleElement(options) { 74277 var tag = document.createElement('style'); 74278 tag.setAttribute('data-emotion', options.key); 74279 74280 if (options.nonce !== undefined) { 74281 tag.setAttribute('nonce', options.nonce); 74282 } 74283 74284 tag.appendChild(document.createTextNode('')); 74285 tag.setAttribute('data-s', ''); 74286 return tag; 74287 } 74288 74289 var StyleSheet = /*#__PURE__*/function () { 74290 // Using Node instead of HTMLElement since container may be a ShadowRoot 74291 function StyleSheet(options) { 74292 var _this = this; 74293 74294 this._insertTag = function (tag) { 74295 var before; 74296 74297 if (_this.tags.length === 0) { 74298 if (_this.insertionPoint) { 74299 before = _this.insertionPoint.nextSibling; 74300 } else if (_this.prepend) { 74301 before = _this.container.firstChild; 74302 } else { 74303 before = _this.before; 74304 } 74305 } else { 74306 before = _this.tags[_this.tags.length - 1].nextSibling; 74307 } 74308 74309 _this.container.insertBefore(tag, before); 74310 74311 _this.tags.push(tag); 74312 }; 74313 74314 this.isSpeedy = options.speedy === undefined ? "production" === 'production' : options.speedy; 74315 this.tags = []; 74316 this.ctr = 0; 74317 this.nonce = options.nonce; // key is the value of the data-emotion attribute, it's used to identify different sheets 74318 74319 this.key = options.key; 74320 this.container = options.container; 74321 this.prepend = options.prepend; 74322 this.insertionPoint = options.insertionPoint; 74323 this.before = null; 74324 } 74325 74326 var _proto = StyleSheet.prototype; 74327 74328 _proto.hydrate = function hydrate(nodes) { 74329 nodes.forEach(this._insertTag); 74330 }; 74331 74332 _proto.insert = function insert(rule) { 74333 // the max length is how many rules we have per style tag, it's 65000 in speedy mode 74334 // it's 1 in dev because we insert source maps that map a single rule to a location 74335 // and you can only have one source map per style tag 74336 if (this.ctr % (this.isSpeedy ? 65000 : 1) === 0) { 74337 this._insertTag(createStyleElement(this)); 74338 } 74339 74340 var tag = this.tags[this.tags.length - 1]; 74341 74342 if (false) { var isImportRule; } 74343 74344 if (this.isSpeedy) { 74345 var sheet = sheetForTag(tag); 74346 74347 try { 74348 // this is the ultrafast version, works across browsers 74349 // the big drawback is that the css won't be editable in devtools 74350 sheet.insertRule(rule, sheet.cssRules.length); 74351 } catch (e) { 74352 if (false) {} 74353 } 74354 } else { 74355 tag.appendChild(document.createTextNode(rule)); 74356 } 74357 74358 this.ctr++; 74359 }; 74360 74361 _proto.flush = function flush() { 74362 // $FlowFixMe 74363 this.tags.forEach(function (tag) { 74364 return tag.parentNode && tag.parentNode.removeChild(tag); 74365 }); 74366 this.tags = []; 74367 this.ctr = 0; 74368 74369 if (false) {} 74370 }; 74371 74372 return StyleSheet; 74373 }(); 74374 74375 74376 74377 ;// ./node_modules/stylis/src/Utility.js 74378 /** 74379 * @param {number} 74380 * @return {number} 74381 */ 74382 var abs = Math.abs 74383 74384 /** 74385 * @param {number} 74386 * @return {string} 74387 */ 74388 var Utility_from = String.fromCharCode 74389 74390 /** 74391 * @param {object} 74392 * @return {object} 74393 */ 74394 var Utility_assign = Object.assign 74395 74396 /** 74397 * @param {string} value 74398 * @param {number} length 74399 * @return {number} 74400 */ 74401 function hash (value, length) { 74402 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 74403 } 74404 74405 /** 74406 * @param {string} value 74407 * @return {string} 74408 */ 74409 function trim (value) { 74410 return value.trim() 74411 } 74412 74413 /** 74414 * @param {string} value 74415 * @param {RegExp} pattern 74416 * @return {string?} 74417 */ 74418 function Utility_match (value, pattern) { 74419 return (value = pattern.exec(value)) ? value[0] : value 74420 } 74421 74422 /** 74423 * @param {string} value 74424 * @param {(string|RegExp)} pattern 74425 * @param {string} replacement 74426 * @return {string} 74427 */ 74428 function Utility_replace (value, pattern, replacement) { 74429 return value.replace(pattern, replacement) 74430 } 74431 74432 /** 74433 * @param {string} value 74434 * @param {string} search 74435 * @return {number} 74436 */ 74437 function indexof (value, search) { 74438 return value.indexOf(search) 74439 } 74440 74441 /** 74442 * @param {string} value 74443 * @param {number} index 74444 * @return {number} 74445 */ 74446 function Utility_charat (value, index) { 74447 return value.charCodeAt(index) | 0 74448 } 74449 74450 /** 74451 * @param {string} value 74452 * @param {number} begin 74453 * @param {number} end 74454 * @return {string} 74455 */ 74456 function Utility_substr (value, begin, end) { 74457 return value.slice(begin, end) 74458 } 74459 74460 /** 74461 * @param {string} value 74462 * @return {number} 74463 */ 74464 function Utility_strlen (value) { 74465 return value.length 74466 } 74467 74468 /** 74469 * @param {any[]} value 74470 * @return {number} 74471 */ 74472 function Utility_sizeof (value) { 74473 return value.length 74474 } 74475 74476 /** 74477 * @param {any} value 74478 * @param {any[]} array 74479 * @return {any} 74480 */ 74481 function Utility_append (value, array) { 74482 return array.push(value), value 74483 } 74484 74485 /** 74486 * @param {string[]} array 74487 * @param {function} callback 74488 * @return {string} 74489 */ 74490 function Utility_combine (array, callback) { 74491 return array.map(callback).join('') 74492 } 74493 74494 ;// ./node_modules/stylis/src/Tokenizer.js 74495 74496 74497 var line = 1 74498 var column = 1 74499 var Tokenizer_length = 0 74500 var Tokenizer_position = 0 74501 var Tokenizer_character = 0 74502 var characters = '' 74503 74504 /** 74505 * @param {string} value 74506 * @param {object | null} root 74507 * @param {object | null} parent 74508 * @param {string} type 74509 * @param {string[] | string} props 74510 * @param {object[] | string} children 74511 * @param {number} length 74512 */ 74513 function node (value, root, parent, type, props, children, length) { 74514 return {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: ''} 74515 } 74516 74517 /** 74518 * @param {object} root 74519 * @param {object} props 74520 * @return {object} 74521 */ 74522 function Tokenizer_copy (root, props) { 74523 return Utility_assign(node('', null, null, '', null, null, 0), root, {length: -root.length}, props) 74524 } 74525 74526 /** 74527 * @return {number} 74528 */ 74529 function Tokenizer_char () { 74530 return Tokenizer_character 74531 } 74532 74533 /** 74534 * @return {number} 74535 */ 74536 function prev () { 74537 Tokenizer_character = Tokenizer_position > 0 ? Utility_charat(characters, --Tokenizer_position) : 0 74538 74539 if (column--, Tokenizer_character === 10) 74540 column = 1, line-- 74541 74542 return Tokenizer_character 74543 } 74544 74545 /** 74546 * @return {number} 74547 */ 74548 function next () { 74549 Tokenizer_character = Tokenizer_position < Tokenizer_length ? Utility_charat(characters, Tokenizer_position++) : 0 74550 74551 if (column++, Tokenizer_character === 10) 74552 column = 1, line++ 74553 74554 return Tokenizer_character 74555 } 74556 74557 /** 74558 * @return {number} 74559 */ 74560 function peek () { 74561 return Utility_charat(characters, Tokenizer_position) 74562 } 74563 74564 /** 74565 * @return {number} 74566 */ 74567 function caret () { 74568 return Tokenizer_position 74569 } 74570 74571 /** 74572 * @param {number} begin 74573 * @param {number} end 74574 * @return {string} 74575 */ 74576 function slice (begin, end) { 74577 return Utility_substr(characters, begin, end) 74578 } 74579 74580 /** 74581 * @param {number} type 74582 * @return {number} 74583 */ 74584 function token (type) { 74585 switch (type) { 74586 // \0 \t \n \r \s whitespace token 74587 case 0: case 9: case 10: case 13: case 32: 74588 return 5 74589 // ! + , / > @ ~ isolate token 74590 case 33: case 43: case 44: case 47: case 62: case 64: case 126: 74591 // ; { } breakpoint token 74592 case 59: case 123: case 125: 74593 return 4 74594 // : accompanied token 74595 case 58: 74596 return 3 74597 // " ' ( [ opening delimit token 74598 case 34: case 39: case 40: case 91: 74599 return 2 74600 // ) ] closing delimit token 74601 case 41: case 93: 74602 return 1 74603 } 74604 74605 return 0 74606 } 74607 74608 /** 74609 * @param {string} value 74610 * @return {any[]} 74611 */ 74612 function alloc (value) { 74613 return line = column = 1, Tokenizer_length = Utility_strlen(characters = value), Tokenizer_position = 0, [] 74614 } 74615 74616 /** 74617 * @param {any} value 74618 * @return {any} 74619 */ 74620 function dealloc (value) { 74621 return characters = '', value 74622 } 74623 74624 /** 74625 * @param {number} type 74626 * @return {string} 74627 */ 74628 function delimit (type) { 74629 return trim(slice(Tokenizer_position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type))) 74630 } 74631 74632 /** 74633 * @param {string} value 74634 * @return {string[]} 74635 */ 74636 function Tokenizer_tokenize (value) { 74637 return dealloc(tokenizer(alloc(value))) 74638 } 74639 74640 /** 74641 * @param {number} type 74642 * @return {string} 74643 */ 74644 function whitespace (type) { 74645 while (Tokenizer_character = peek()) 74646 if (Tokenizer_character < 33) 74647 next() 74648 else 74649 break 74650 74651 return token(type) > 2 || token(Tokenizer_character) > 3 ? '' : ' ' 74652 } 74653 74654 /** 74655 * @param {string[]} children 74656 * @return {string[]} 74657 */ 74658 function tokenizer (children) { 74659 while (next()) 74660 switch (token(Tokenizer_character)) { 74661 case 0: append(identifier(Tokenizer_position - 1), children) 74662 break 74663 case 2: append(delimit(Tokenizer_character), children) 74664 break 74665 default: append(from(Tokenizer_character), children) 74666 } 74667 74668 return children 74669 } 74670 74671 /** 74672 * @param {number} index 74673 * @param {number} count 74674 * @return {string} 74675 */ 74676 function escaping (index, count) { 74677 while (--count && next()) 74678 // not 0-9 A-F a-f 74679 if (Tokenizer_character < 48 || Tokenizer_character > 102 || (Tokenizer_character > 57 && Tokenizer_character < 65) || (Tokenizer_character > 70 && Tokenizer_character < 97)) 74680 break 74681 74682 return slice(index, caret() + (count < 6 && peek() == 32 && next() == 32)) 74683 } 74684 74685 /** 74686 * @param {number} type 74687 * @return {number} 74688 */ 74689 function delimiter (type) { 74690 while (next()) 74691 switch (Tokenizer_character) { 74692 // ] ) " ' 74693 case type: 74694 return Tokenizer_position 74695 // " ' 74696 case 34: case 39: 74697 if (type !== 34 && type !== 39) 74698 delimiter(Tokenizer_character) 74699 break 74700 // ( 74701 case 40: 74702 if (type === 41) 74703 delimiter(type) 74704 break 74705 // \ 74706 case 92: 74707 next() 74708 break 74709 } 74710 74711 return Tokenizer_position 74712 } 74713 74714 /** 74715 * @param {number} type 74716 * @param {number} index 74717 * @return {number} 74718 */ 74719 function commenter (type, index) { 74720 while (next()) 74721 // // 74722 if (type + Tokenizer_character === 47 + 10) 74723 break 74724 // /* 74725 else if (type + Tokenizer_character === 42 + 42 && peek() === 47) 74726 break 74727 74728 return '/*' + slice(index, Tokenizer_position - 1) + '*' + Utility_from(type === 47 ? type : next()) 74729 } 74730 74731 /** 74732 * @param {number} index 74733 * @return {string} 74734 */ 74735 function identifier (index) { 74736 while (!token(peek())) 74737 next() 74738 74739 return slice(index, Tokenizer_position) 74740 } 74741 74742 ;// ./node_modules/stylis/src/Enum.js 74743 var Enum_MS = '-ms-' 74744 var Enum_MOZ = '-moz-' 74745 var Enum_WEBKIT = '-webkit-' 74746 74747 var COMMENT = 'comm' 74748 var Enum_RULESET = 'rule' 74749 var Enum_DECLARATION = 'decl' 74750 74751 var PAGE = '@page' 74752 var MEDIA = '@media' 74753 var IMPORT = '@import' 74754 var CHARSET = '@charset' 74755 var VIEWPORT = '@viewport' 74756 var SUPPORTS = '@supports' 74757 var DOCUMENT = '@document' 74758 var NAMESPACE = '@namespace' 74759 var Enum_KEYFRAMES = '@keyframes' 74760 var FONT_FACE = '@font-face' 74761 var COUNTER_STYLE = '@counter-style' 74762 var FONT_FEATURE_VALUES = '@font-feature-values' 74763 74764 ;// ./node_modules/stylis/src/Serializer.js 74765 74766 74767 74768 /** 74769 * @param {object[]} children 74770 * @param {function} callback 74771 * @return {string} 74772 */ 74773 function Serializer_serialize (children, callback) { 74774 var output = '' 74775 var length = Utility_sizeof(children) 74776 74777 for (var i = 0; i < length; i++) 74778 output += callback(children[i], i, children, callback) || '' 74779 74780 return output 74781 } 74782 74783 /** 74784 * @param {object} element 74785 * @param {number} index 74786 * @param {object[]} children 74787 * @param {function} callback 74788 * @return {string} 74789 */ 74790 function Serializer_stringify (element, index, children, callback) { 74791 switch (element.type) { 74792 case IMPORT: case Enum_DECLARATION: return element.return = element.return || element.value 74793 case COMMENT: return '' 74794 case Enum_KEYFRAMES: return element.return = element.value + '{' + Serializer_serialize(element.children, callback) + '}' 74795 case Enum_RULESET: element.value = element.props.join(',') 74796 } 74797 74798 return Utility_strlen(children = Serializer_serialize(element.children, callback)) ? element.return = element.value + '{' + children + '}' : '' 74799 } 74800 74801 ;// ./node_modules/stylis/src/Middleware.js 74802 74803 74804 74805 74806 74807 74808 /** 74809 * @param {function[]} collection 74810 * @return {function} 74811 */ 74812 function middleware (collection) { 74813 var length = Utility_sizeof(collection) 74814 74815 return function (element, index, children, callback) { 74816 var output = '' 74817 74818 for (var i = 0; i < length; i++) 74819 output += collection[i](element, index, children, callback) || '' 74820 74821 return output 74822 } 74823 } 74824 74825 /** 74826 * @param {function} callback 74827 * @return {function} 74828 */ 74829 function rulesheet (callback) { 74830 return function (element) { 74831 if (!element.root) 74832 if (element = element.return) 74833 callback(element) 74834 } 74835 } 74836 74837 /** 74838 * @param {object} element 74839 * @param {number} index 74840 * @param {object[]} children 74841 * @param {function} callback 74842 */ 74843 function prefixer (element, index, children, callback) { 74844 if (element.length > -1) 74845 if (!element.return) 74846 switch (element.type) { 74847 case DECLARATION: element.return = prefix(element.value, element.length, children) 74848 return 74849 case KEYFRAMES: 74850 return serialize([copy(element, {value: replace(element.value, '@', '@' + WEBKIT)})], callback) 74851 case RULESET: 74852 if (element.length) 74853 return combine(element.props, function (value) { 74854 switch (match(value, /(::plac\w+|:read-\w+)/)) { 74855 // :read-(only|write) 74856 case ':read-only': case ':read-write': 74857 return serialize([copy(element, {props: [replace(value, /:(read-\w+)/, ':' + MOZ + '$1')]})], callback) 74858 // :placeholder 74859 case '::placeholder': 74860 return serialize([ 74861 copy(element, {props: [replace(value, /:(plac\w+)/, ':' + WEBKIT + 'input-$1')]}), 74862 copy(element, {props: [replace(value, /:(plac\w+)/, ':' + MOZ + '$1')]}), 74863 copy(element, {props: [replace(value, /:(plac\w+)/, MS + 'input-$1')]}) 74864 ], callback) 74865 } 74866 74867 return '' 74868 }) 74869 } 74870 } 74871 74872 /** 74873 * @param {object} element 74874 * @param {number} index 74875 * @param {object[]} children 74876 */ 74877 function namespace (element) { 74878 switch (element.type) { 74879 case RULESET: 74880 element.props = element.props.map(function (value) { 74881 return combine(tokenize(value), function (value, index, children) { 74882 switch (charat(value, 0)) { 74883 // \f 74884 case 12: 74885 return substr(value, 1, strlen(value)) 74886 // \0 ( + > ~ 74887 case 0: case 40: case 43: case 62: case 126: 74888 return value 74889 // : 74890 case 58: 74891 if (children[++index] === 'global') 74892 children[index] = '', children[++index] = '\f' + substr(children[index], index = 1, -1) 74893 // \s 74894 case 32: 74895 return index === 1 ? '' : value 74896 default: 74897 switch (index) { 74898 case 0: element = value 74899 return sizeof(children) > 1 ? '' : value 74900 case index = sizeof(children) - 1: case 2: 74901 return index === 2 ? value + element + element : value + element 74902 default: 74903 return value 74904 } 74905 } 74906 }) 74907 }) 74908 } 74909 } 74910 74911 ;// ./node_modules/stylis/src/Parser.js 74912 74913 74914 74915 74916 /** 74917 * @param {string} value 74918 * @return {object[]} 74919 */ 74920 function compile (value) { 74921 return dealloc(Parser_parse('', null, null, null, [''], value = alloc(value), 0, [0], value)) 74922 } 74923 74924 /** 74925 * @param {string} value 74926 * @param {object} root 74927 * @param {object?} parent 74928 * @param {string[]} rule 74929 * @param {string[]} rules 74930 * @param {string[]} rulesets 74931 * @param {number[]} pseudo 74932 * @param {number[]} points 74933 * @param {string[]} declarations 74934 * @return {object} 74935 */ 74936 function Parser_parse (value, root, parent, rule, rules, rulesets, pseudo, points, declarations) { 74937 var index = 0 74938 var offset = 0 74939 var length = pseudo 74940 var atrule = 0 74941 var property = 0 74942 var previous = 0 74943 var variable = 1 74944 var scanning = 1 74945 var ampersand = 1 74946 var character = 0 74947 var type = '' 74948 var props = rules 74949 var children = rulesets 74950 var reference = rule 74951 var characters = type 74952 74953 while (scanning) 74954 switch (previous = character, character = next()) { 74955 // ( 74956 case 40: 74957 if (previous != 108 && Utility_charat(characters, length - 1) == 58) { 74958 if (indexof(characters += Utility_replace(delimit(character), '&', '&\f'), '&\f') != -1) 74959 ampersand = -1 74960 break 74961 } 74962 // " ' [ 74963 case 34: case 39: case 91: 74964 characters += delimit(character) 74965 break 74966 // \t \n \r \s 74967 case 9: case 10: case 13: case 32: 74968 characters += whitespace(previous) 74969 break 74970 // \ 74971 case 92: 74972 characters += escaping(caret() - 1, 7) 74973 continue 74974 // / 74975 case 47: 74976 switch (peek()) { 74977 case 42: case 47: 74978 Utility_append(comment(commenter(next(), caret()), root, parent), declarations) 74979 break 74980 default: 74981 characters += '/' 74982 } 74983 break 74984 // { 74985 case 123 * variable: 74986 points[index++] = Utility_strlen(characters) * ampersand 74987 // } ; \0 74988 case 125 * variable: case 59: case 0: 74989 switch (character) { 74990 // \0 } 74991 case 0: case 125: scanning = 0 74992 // ; 74993 case 59 + offset: 74994 if (property > 0 && (Utility_strlen(characters) - length)) 74995 Utility_append(property > 32 ? declaration(characters + ';', rule, parent, length - 1) : declaration(Utility_replace(characters, ' ', '') + ';', rule, parent, length - 2), declarations) 74996 break 74997 // @ ; 74998 case 59: characters += ';' 74999 // { rule/at-rule 75000 default: 75001 Utility_append(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length), rulesets) 75002 75003 if (character === 123) 75004 if (offset === 0) 75005 Parser_parse(characters, root, reference, reference, props, rulesets, length, points, children) 75006 else 75007 switch (atrule === 99 && Utility_charat(characters, 3) === 110 ? 100 : atrule) { 75008 // d m s 75009 case 100: case 109: case 115: 75010 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) 75011 break 75012 default: 75013 Parser_parse(characters, reference, reference, reference, [''], children, 0, points, children) 75014 } 75015 } 75016 75017 index = offset = property = 0, variable = ampersand = 1, type = characters = '', length = pseudo 75018 break 75019 // : 75020 case 58: 75021 length = 1 + Utility_strlen(characters), property = previous 75022 default: 75023 if (variable < 1) 75024 if (character == 123) 75025 --variable 75026 else if (character == 125 && variable++ == 0 && prev() == 125) 75027 continue 75028 75029 switch (characters += Utility_from(character), character * variable) { 75030 // & 75031 case 38: 75032 ampersand = offset > 0 ? 1 : (characters += '\f', -1) 75033 break 75034 // , 75035 case 44: 75036 points[index++] = (Utility_strlen(characters) - 1) * ampersand, ampersand = 1 75037 break 75038 // @ 75039 case 64: 75040 // - 75041 if (peek() === 45) 75042 characters += delimit(next()) 75043 75044 atrule = peek(), offset = length = Utility_strlen(type = characters += identifier(caret())), character++ 75045 break 75046 // - 75047 case 45: 75048 if (previous === 45 && Utility_strlen(characters) == 2) 75049 variable = 0 75050 } 75051 } 75052 75053 return rulesets 75054 } 75055 75056 /** 75057 * @param {string} value 75058 * @param {object} root 75059 * @param {object?} parent 75060 * @param {number} index 75061 * @param {number} offset 75062 * @param {string[]} rules 75063 * @param {number[]} points 75064 * @param {string} type 75065 * @param {string[]} props 75066 * @param {string[]} children 75067 * @param {number} length 75068 * @return {object} 75069 */ 75070 function ruleset (value, root, parent, index, offset, rules, points, type, props, children, length) { 75071 var post = offset - 1 75072 var rule = offset === 0 ? rules : [''] 75073 var size = Utility_sizeof(rule) 75074 75075 for (var i = 0, j = 0, k = 0; i < index; ++i) 75076 for (var x = 0, y = Utility_substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x) 75077 if (z = trim(j > 0 ? rule[x] + ' ' + y : Utility_replace(y, /&\f/g, rule[x]))) 75078 props[k++] = z 75079 75080 return node(value, root, parent, offset === 0 ? Enum_RULESET : type, props, children, length) 75081 } 75082 75083 /** 75084 * @param {number} value 75085 * @param {object} root 75086 * @param {object?} parent 75087 * @return {object} 75088 */ 75089 function comment (value, root, parent) { 75090 return node(value, root, parent, COMMENT, Utility_from(Tokenizer_char()), Utility_substr(value, 2, -2), 0) 75091 } 75092 75093 /** 75094 * @param {string} value 75095 * @param {object} root 75096 * @param {object?} parent 75097 * @param {number} length 75098 * @return {object} 75099 */ 75100 function declaration (value, root, parent, length) { 75101 return node(value, root, parent, Enum_DECLARATION, Utility_substr(value, 0, length), Utility_substr(value, length + 1, -1), length) 75102 } 75103 75104 ;// ./node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js 75105 75106 75107 75108 75109 75110 var identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) { 75111 var previous = 0; 75112 var character = 0; 75113 75114 while (true) { 75115 previous = character; 75116 character = peek(); // &\f 75117 75118 if (previous === 38 && character === 12) { 75119 points[index] = 1; 75120 } 75121 75122 if (token(character)) { 75123 break; 75124 } 75125 75126 next(); 75127 } 75128 75129 return slice(begin, Tokenizer_position); 75130 }; 75131 75132 var toRules = function toRules(parsed, points) { 75133 // pretend we've started with a comma 75134 var index = -1; 75135 var character = 44; 75136 75137 do { 75138 switch (token(character)) { 75139 case 0: 75140 // &\f 75141 if (character === 38 && peek() === 12) { 75142 // this is not 100% correct, we don't account for literal sequences here - like for example quoted strings 75143 // stylis inserts \f after & to know when & where it should replace this sequence with the context selector 75144 // and when it should just concatenate the outer and inner selectors 75145 // it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here 75146 points[index] = 1; 75147 } 75148 75149 parsed[index] += identifierWithPointTracking(Tokenizer_position - 1, points, index); 75150 break; 75151 75152 case 2: 75153 parsed[index] += delimit(character); 75154 break; 75155 75156 case 4: 75157 // comma 75158 if (character === 44) { 75159 // colon 75160 parsed[++index] = peek() === 58 ? '&\f' : ''; 75161 points[index] = parsed[index].length; 75162 break; 75163 } 75164 75165 // fallthrough 75166 75167 default: 75168 parsed[index] += Utility_from(character); 75169 } 75170 } while (character = next()); 75171 75172 return parsed; 75173 }; 75174 75175 var getRules = function getRules(value, points) { 75176 return dealloc(toRules(alloc(value), points)); 75177 }; // WeakSet would be more appropriate, but only WeakMap is supported in IE11 75178 75179 75180 var fixedElements = /* #__PURE__ */new WeakMap(); 75181 var compat = function compat(element) { 75182 if (element.type !== 'rule' || !element.parent || // positive .length indicates that this rule contains pseudo 75183 // negative .length indicates that this rule has been already prefixed 75184 element.length < 1) { 75185 return; 75186 } 75187 75188 var value = element.value, 75189 parent = element.parent; 75190 var isImplicitRule = element.column === parent.column && element.line === parent.line; 75191 75192 while (parent.type !== 'rule') { 75193 parent = parent.parent; 75194 if (!parent) return; 75195 } // short-circuit for the simplest case 75196 75197 75198 if (element.props.length === 1 && value.charCodeAt(0) !== 58 75199 /* colon */ 75200 && !fixedElements.get(parent)) { 75201 return; 75202 } // if this is an implicitly inserted rule (the one eagerly inserted at the each new nested level) 75203 // then the props has already been manipulated beforehand as they that array is shared between it and its "rule parent" 75204 75205 75206 if (isImplicitRule) { 75207 return; 75208 } 75209 75210 fixedElements.set(element, true); 75211 var points = []; 75212 var rules = getRules(value, points); 75213 var parentRules = parent.props; 75214 75215 for (var i = 0, k = 0; i < rules.length; i++) { 75216 for (var j = 0; j < parentRules.length; j++, k++) { 75217 element.props[k] = points[i] ? rules[i].replace(/&\f/g, parentRules[j]) : parentRules[j] + " " + rules[i]; 75218 } 75219 } 75220 }; 75221 var removeLabel = function removeLabel(element) { 75222 if (element.type === 'decl') { 75223 var value = element.value; 75224 75225 if ( // charcode for l 75226 value.charCodeAt(0) === 108 && // charcode for b 75227 value.charCodeAt(2) === 98) { 75228 // this ignores label 75229 element["return"] = ''; 75230 element.value = ''; 75231 } 75232 } 75233 }; 75234 var ignoreFlag = 'emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason'; 75235 75236 var isIgnoringComment = function isIgnoringComment(element) { 75237 return element.type === 'comm' && element.children.indexOf(ignoreFlag) > -1; 75238 }; 75239 75240 var createUnsafeSelectorsAlarm = function createUnsafeSelectorsAlarm(cache) { 75241 return function (element, index, children) { 75242 if (element.type !== 'rule' || cache.compat) return; 75243 var unsafePseudoClasses = element.value.match(/(:first|:nth|:nth-last)-child/g); 75244 75245 if (unsafePseudoClasses) { 75246 var isNested = element.parent === children[0]; // in nested rules comments become children of the "auto-inserted" rule 75247 // 75248 // considering this input: 75249 // .a { 75250 // .b /* comm */ {} 75251 // color: hotpink; 75252 // } 75253 // we get output corresponding to this: 75254 // .a { 75255 // & { 75256 // /* comm */ 75257 // color: hotpink; 75258 // } 75259 // .b {} 75260 // } 75261 75262 var commentContainer = isNested ? children[0].children : // global rule at the root level 75263 children; 75264 75265 for (var i = commentContainer.length - 1; i >= 0; i--) { 75266 var node = commentContainer[i]; 75267 75268 if (node.line < element.line) { 75269 break; 75270 } // it is quite weird but comments are *usually* put at `column: element.column - 1` 75271 // so we seek *from the end* for the node that is earlier than the rule's `element` and check that 75272 // this will also match inputs like this: 75273 // .a { 75274 // /* comm */ 75275 // .b {} 75276 // } 75277 // 75278 // but that is fine 75279 // 75280 // it would be the easiest to change the placement of the comment to be the first child of the rule: 75281 // .a { 75282 // .b { /* comm */ } 75283 // } 75284 // with such inputs we wouldn't have to search for the comment at all 75285 // TODO: consider changing this comment placement in the next major version 75286 75287 75288 if (node.column < element.column) { 75289 if (isIgnoringComment(node)) { 75290 return; 75291 } 75292 75293 break; 75294 } 75295 } 75296 75297 unsafePseudoClasses.forEach(function (unsafePseudoClass) { 75298 console.error("The pseudo class \"" + unsafePseudoClass + "\" is potentially unsafe when doing server-side rendering. Try changing it to \"" + unsafePseudoClass.split('-child')[0] + "-of-type\"."); 75299 }); 75300 } 75301 }; 75302 }; 75303 75304 var isImportRule = function isImportRule(element) { 75305 return element.type.charCodeAt(1) === 105 && element.type.charCodeAt(0) === 64; 75306 }; 75307 75308 var isPrependedWithRegularRules = function isPrependedWithRegularRules(index, children) { 75309 for (var i = index - 1; i >= 0; i--) { 75310 if (!isImportRule(children[i])) { 75311 return true; 75312 } 75313 } 75314 75315 return false; 75316 }; // use this to remove incorrect elements from further processing 75317 // so they don't get handed to the `sheet` (or anything else) 75318 // as that could potentially lead to additional logs which in turn could be overhelming to the user 75319 75320 75321 var nullifyElement = function nullifyElement(element) { 75322 element.type = ''; 75323 element.value = ''; 75324 element["return"] = ''; 75325 element.children = ''; 75326 element.props = ''; 75327 }; 75328 75329 var incorrectImportAlarm = function incorrectImportAlarm(element, index, children) { 75330 if (!isImportRule(element)) { 75331 return; 75332 } 75333 75334 if (element.parent) { 75335 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."); 75336 nullifyElement(element); 75337 } else if (isPrependedWithRegularRules(index, children)) { 75338 console.error("`@import` rules can't be after other rules. Please put your `@import` rules before your other rules."); 75339 nullifyElement(element); 75340 } 75341 }; 75342 75343 /* eslint-disable no-fallthrough */ 75344 75345 function emotion_cache_browser_esm_prefix(value, length) { 75346 switch (hash(value, length)) { 75347 // color-adjust 75348 case 5103: 75349 return Enum_WEBKIT + 'print-' + value + value; 75350 // animation, animation-(delay|direction|duration|fill-mode|iteration-count|name|play-state|timing-function) 75351 75352 case 5737: 75353 case 4201: 75354 case 3177: 75355 case 3433: 75356 case 1641: 75357 case 4457: 75358 case 2921: // text-decoration, filter, clip-path, backface-visibility, column, box-decoration-break 75359 75360 case 5572: 75361 case 6356: 75362 case 5844: 75363 case 3191: 75364 case 6645: 75365 case 3005: // mask, mask-image, mask-(mode|clip|size), mask-(repeat|origin), mask-position, mask-composite, 75366 75367 case 6391: 75368 case 5879: 75369 case 5623: 75370 case 6135: 75371 case 4599: 75372 case 4855: // background-clip, columns, column-(count|fill|gap|rule|rule-color|rule-style|rule-width|span|width) 75373 75374 case 4215: 75375 case 6389: 75376 case 5109: 75377 case 5365: 75378 case 5621: 75379 case 3829: 75380 return Enum_WEBKIT + value + value; 75381 // appearance, user-select, transform, hyphens, text-size-adjust 75382 75383 case 5349: 75384 case 4246: 75385 case 4810: 75386 case 6968: 75387 case 2756: 75388 return Enum_WEBKIT + value + Enum_MOZ + value + Enum_MS + value + value; 75389 // flex, flex-direction 75390 75391 case 6828: 75392 case 4268: 75393 return Enum_WEBKIT + value + Enum_MS + value + value; 75394 // order 75395 75396 case 6165: 75397 return Enum_WEBKIT + value + Enum_MS + 'flex-' + value + value; 75398 // align-items 75399 75400 case 5187: 75401 return Enum_WEBKIT + value + Utility_replace(value, /(\w+).+(:[^]+)/, Enum_WEBKIT + 'box-$1$2' + Enum_MS + 'flex-$1$2') + value; 75402 // align-self 75403 75404 case 5443: 75405 return Enum_WEBKIT + value + Enum_MS + 'flex-item-' + Utility_replace(value, /flex-|-self/, '') + value; 75406 // align-content 75407 75408 case 4675: 75409 return Enum_WEBKIT + value + Enum_MS + 'flex-line-pack' + Utility_replace(value, /align-content|flex-|-self/, '') + value; 75410 // flex-shrink 75411 75412 case 5548: 75413 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, 'shrink', 'negative') + value; 75414 // flex-basis 75415 75416 case 5292: 75417 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, 'basis', 'preferred-size') + value; 75418 // flex-grow 75419 75420 case 6060: 75421 return Enum_WEBKIT + 'box-' + Utility_replace(value, '-grow', '') + Enum_WEBKIT + value + Enum_MS + Utility_replace(value, 'grow', 'positive') + value; 75422 // transition 75423 75424 case 4554: 75425 return Enum_WEBKIT + Utility_replace(value, /([^-])(transform)/g, '$1' + Enum_WEBKIT + '$2') + value; 75426 // cursor 75427 75428 case 6187: 75429 return Utility_replace(Utility_replace(Utility_replace(value, /(zoom-|grab)/, Enum_WEBKIT + '$1'), /(image-set)/, Enum_WEBKIT + '$1'), value, '') + value; 75430 // background, background-image 75431 75432 case 5495: 75433 case 3959: 75434 return Utility_replace(value, /(image-set\([^]*)/, Enum_WEBKIT + '$1' + '$`$1'); 75435 // justify-content 75436 75437 case 4968: 75438 return Utility_replace(Utility_replace(value, /(.+:)(flex-)?(.*)/, Enum_WEBKIT + 'box-pack:$3' + Enum_MS + 'flex-pack:$3'), /s.+-b[^;]+/, 'justify') + Enum_WEBKIT + value + value; 75439 // (margin|padding)-inline-(start|end) 75440 75441 case 4095: 75442 case 3583: 75443 case 4068: 75444 case 2532: 75445 return Utility_replace(value, /(.+)-inline(.+)/, Enum_WEBKIT + '$1$2') + value; 75446 // (min|max)?(width|height|inline-size|block-size) 75447 75448 case 8116: 75449 case 7059: 75450 case 5753: 75451 case 5535: 75452 case 5445: 75453 case 5701: 75454 case 4933: 75455 case 4677: 75456 case 5533: 75457 case 5789: 75458 case 5021: 75459 case 4765: 75460 // stretch, max-content, min-content, fill-available 75461 if (Utility_strlen(value) - 1 - length > 6) switch (Utility_charat(value, length + 1)) { 75462 // (m)ax-content, (m)in-content 75463 case 109: 75464 // - 75465 if (Utility_charat(value, length + 4) !== 45) break; 75466 // (f)ill-available, (f)it-content 75467 75468 case 102: 75469 return Utility_replace(value, /(.+:)(.+)-([^]+)/, '$1' + Enum_WEBKIT + '$2-$3' + '$1' + Enum_MOZ + (Utility_charat(value, length + 3) == 108 ? '$3' : '$2-$3')) + value; 75470 // (s)tretch 75471 75472 case 115: 75473 return ~indexof(value, 'stretch') ? emotion_cache_browser_esm_prefix(Utility_replace(value, 'stretch', 'fill-available'), length) + value : value; 75474 } 75475 break; 75476 // position: sticky 75477 75478 case 4949: 75479 // (s)ticky? 75480 if (Utility_charat(value, length + 1) !== 115) break; 75481 // display: (flex|inline-flex) 75482 75483 case 6444: 75484 switch (Utility_charat(value, Utility_strlen(value) - 3 - (~indexof(value, '!important') && 10))) { 75485 // stic(k)y 75486 case 107: 75487 return Utility_replace(value, ':', ':' + Enum_WEBKIT) + value; 75488 // (inline-)?fl(e)x 75489 75490 case 101: 75491 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; 75492 } 75493 75494 break; 75495 // writing-mode 75496 75497 case 5936: 75498 switch (Utility_charat(value, length + 11)) { 75499 // vertical-l(r) 75500 case 114: 75501 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, /[svh]\w+-[tblr]{2}/, 'tb') + value; 75502 // vertical-r(l) 75503 75504 case 108: 75505 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, /[svh]\w+-[tblr]{2}/, 'tb-rl') + value; 75506 // horizontal(-)tb 75507 75508 case 45: 75509 return Enum_WEBKIT + value + Enum_MS + Utility_replace(value, /[svh]\w+-[tblr]{2}/, 'lr') + value; 75510 } 75511 75512 return Enum_WEBKIT + value + Enum_MS + value + value; 75513 } 75514 75515 return value; 75516 } 75517 75518 var emotion_cache_browser_esm_prefixer = function prefixer(element, index, children, callback) { 75519 if (element.length > -1) if (!element["return"]) switch (element.type) { 75520 case Enum_DECLARATION: 75521 element["return"] = emotion_cache_browser_esm_prefix(element.value, element.length); 75522 break; 75523 75524 case Enum_KEYFRAMES: 75525 return Serializer_serialize([Tokenizer_copy(element, { 75526 value: Utility_replace(element.value, '@', '@' + Enum_WEBKIT) 75527 })], callback); 75528 75529 case Enum_RULESET: 75530 if (element.length) return Utility_combine(element.props, function (value) { 75531 switch (Utility_match(value, /(::plac\w+|:read-\w+)/)) { 75532 // :read-(only|write) 75533 case ':read-only': 75534 case ':read-write': 75535 return Serializer_serialize([Tokenizer_copy(element, { 75536 props: [Utility_replace(value, /:(read-\w+)/, ':' + Enum_MOZ + '$1')] 75537 })], callback); 75538 // :placeholder 75539 75540 case '::placeholder': 75541 return Serializer_serialize([Tokenizer_copy(element, { 75542 props: [Utility_replace(value, /:(plac\w+)/, ':' + Enum_WEBKIT + 'input-$1')] 75543 }), Tokenizer_copy(element, { 75544 props: [Utility_replace(value, /:(plac\w+)/, ':' + Enum_MOZ + '$1')] 75545 }), Tokenizer_copy(element, { 75546 props: [Utility_replace(value, /:(plac\w+)/, Enum_MS + 'input-$1')] 75547 })], callback); 75548 } 75549 75550 return ''; 75551 }); 75552 } 75553 }; 75554 75555 var defaultStylisPlugins = [emotion_cache_browser_esm_prefixer]; 75556 75557 var createCache = function createCache(options) { 75558 var key = options.key; 75559 75560 if (false) {} 75561 75562 if ( key === 'css') { 75563 var ssrStyles = document.querySelectorAll("style[data-emotion]:not([data-s])"); // get SSRed styles out of the way of React's hydration 75564 // document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be) 75565 // note this very very intentionally targets all style elements regardless of the key to ensure 75566 // that creating a cache works inside of render of a React component 75567 75568 Array.prototype.forEach.call(ssrStyles, function (node) { 75569 // we want to only move elements which have a space in the data-emotion attribute value 75570 // because that indicates that it is an Emotion 11 server-side rendered style elements 75571 // while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector 75572 // Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes) 75573 // so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles 75574 // will not result in the Emotion 10 styles being destroyed 75575 var dataEmotionAttribute = node.getAttribute('data-emotion'); 75576 75577 if (dataEmotionAttribute.indexOf(' ') === -1) { 75578 return; 75579 } 75580 document.head.appendChild(node); 75581 node.setAttribute('data-s', ''); 75582 }); 75583 } 75584 75585 var stylisPlugins = options.stylisPlugins || defaultStylisPlugins; 75586 75587 if (false) {} 75588 75589 var inserted = {}; 75590 var container; 75591 var nodesToHydrate = []; 75592 75593 { 75594 container = options.container || document.head; 75595 Array.prototype.forEach.call( // this means we will ignore elements which don't have a space in them which 75596 // means that the style elements we're looking at are only Emotion 11 server-rendered style elements 75597 document.querySelectorAll("style[data-emotion^=\"" + key + " \"]"), function (node) { 75598 var attrib = node.getAttribute("data-emotion").split(' '); // $FlowFixMe 75599 75600 for (var i = 1; i < attrib.length; i++) { 75601 inserted[attrib[i]] = true; 75602 } 75603 75604 nodesToHydrate.push(node); 75605 }); 75606 } 75607 75608 var _insert; 75609 75610 var omnipresentPlugins = [compat, removeLabel]; 75611 75612 if (false) {} 75613 75614 { 75615 var currentSheet; 75616 var finalizingPlugins = [Serializer_stringify, false ? 0 : rulesheet(function (rule) { 75617 currentSheet.insert(rule); 75618 })]; 75619 var serializer = middleware(omnipresentPlugins.concat(stylisPlugins, finalizingPlugins)); 75620 75621 var stylis = function stylis(styles) { 75622 return Serializer_serialize(compile(styles), serializer); 75623 }; 75624 75625 _insert = function insert(selector, serialized, sheet, shouldCache) { 75626 currentSheet = sheet; 75627 75628 if (false) {} 75629 75630 stylis(selector ? selector + "{" + serialized.styles + "}" : serialized.styles); 75631 75632 if (shouldCache) { 75633 cache.inserted[serialized.name] = true; 75634 } 75635 }; 75636 } 75637 75638 var cache = { 75639 key: key, 75640 sheet: new StyleSheet({ 75641 key: key, 75642 container: container, 75643 nonce: options.nonce, 75644 speedy: options.speedy, 75645 prepend: options.prepend, 75646 insertionPoint: options.insertionPoint 75647 }), 75648 nonce: options.nonce, 75649 inserted: inserted, 75650 registered: {}, 75651 insert: _insert 75652 }; 75653 cache.sheet.hydrate(nodesToHydrate); 75654 return cache; 75655 }; 75656 75657 /* harmony default export */ const emotion_cache_browser_esm = (createCache); 75658 75659 ;// ./node_modules/@emotion/hash/dist/emotion-hash.esm.js 75660 /* eslint-disable */ 75661 // Inspired by https://github.com/garycourt/murmurhash-js 75662 // Ported from https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp#L37-L86 75663 function murmur2(str) { 75664 // 'm' and 'r' are mixing constants generated offline. 75665 // They're not really 'magic', they just happen to work well. 75666 // const m = 0x5bd1e995; 75667 // const r = 24; 75668 // Initialize the hash 75669 var h = 0; // Mix 4 bytes at a time into the hash 75670 75671 var k, 75672 i = 0, 75673 len = str.length; 75674 75675 for (; len >= 4; ++i, len -= 4) { 75676 k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24; 75677 k = 75678 /* Math.imul(k, m): */ 75679 (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16); 75680 k ^= 75681 /* k >>> r: */ 75682 k >>> 24; 75683 h = 75684 /* Math.imul(k, m): */ 75685 (k & 0xffff) * 0x5bd1e995 + ((k >>> 16) * 0xe995 << 16) ^ 75686 /* Math.imul(h, m): */ 75687 (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16); 75688 } // Handle the last few bytes of the input array 75689 75690 75691 switch (len) { 75692 case 3: 75693 h ^= (str.charCodeAt(i + 2) & 0xff) << 16; 75694 75695 case 2: 75696 h ^= (str.charCodeAt(i + 1) & 0xff) << 8; 75697 75698 case 1: 75699 h ^= str.charCodeAt(i) & 0xff; 75700 h = 75701 /* Math.imul(h, m): */ 75702 (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16); 75703 } // Do a few final mixes of the hash to ensure the last few 75704 // bytes are well-incorporated. 75705 75706 75707 h ^= h >>> 13; 75708 h = 75709 /* Math.imul(h, m): */ 75710 (h & 0xffff) * 0x5bd1e995 + ((h >>> 16) * 0xe995 << 16); 75711 return ((h ^ h >>> 15) >>> 0).toString(36); 75712 } 75713 75714 /* harmony default export */ const emotion_hash_esm = (murmur2); 75715 75716 ;// ./node_modules/@emotion/unitless/dist/emotion-unitless.esm.js 75717 var unitlessKeys = { 75718 animationIterationCount: 1, 75719 borderImageOutset: 1, 75720 borderImageSlice: 1, 75721 borderImageWidth: 1, 75722 boxFlex: 1, 75723 boxFlexGroup: 1, 75724 boxOrdinalGroup: 1, 75725 columnCount: 1, 75726 columns: 1, 75727 flex: 1, 75728 flexGrow: 1, 75729 flexPositive: 1, 75730 flexShrink: 1, 75731 flexNegative: 1, 75732 flexOrder: 1, 75733 gridRow: 1, 75734 gridRowEnd: 1, 75735 gridRowSpan: 1, 75736 gridRowStart: 1, 75737 gridColumn: 1, 75738 gridColumnEnd: 1, 75739 gridColumnSpan: 1, 75740 gridColumnStart: 1, 75741 msGridRow: 1, 75742 msGridRowSpan: 1, 75743 msGridColumn: 1, 75744 msGridColumnSpan: 1, 75745 fontWeight: 1, 75746 lineHeight: 1, 75747 opacity: 1, 75748 order: 1, 75749 orphans: 1, 75750 tabSize: 1, 75751 widows: 1, 75752 zIndex: 1, 75753 zoom: 1, 75754 WebkitLineClamp: 1, 75755 // SVG-related properties 75756 fillOpacity: 1, 75757 floodOpacity: 1, 75758 stopOpacity: 1, 75759 strokeDasharray: 1, 75760 strokeDashoffset: 1, 75761 strokeMiterlimit: 1, 75762 strokeOpacity: 1, 75763 strokeWidth: 1 75764 }; 75765 75766 /* harmony default export */ const emotion_unitless_esm = (unitlessKeys); 75767 75768 ;// ./node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js 75769 75770 75771 75772 75773 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"; 75774 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)."; 75775 var hyphenateRegex = /[A-Z]|^ms/g; 75776 var animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g; 75777 75778 var isCustomProperty = function isCustomProperty(property) { 75779 return property.charCodeAt(1) === 45; 75780 }; 75781 75782 var isProcessableValue = function isProcessableValue(value) { 75783 return value != null && typeof value !== 'boolean'; 75784 }; 75785 75786 var processStyleName = /* #__PURE__ */memoize(function (styleName) { 75787 return isCustomProperty(styleName) ? styleName : styleName.replace(hyphenateRegex, '-$&').toLowerCase(); 75788 }); 75789 75790 var processStyleValue = function processStyleValue(key, value) { 75791 switch (key) { 75792 case 'animation': 75793 case 'animationName': 75794 { 75795 if (typeof value === 'string') { 75796 return value.replace(animationRegex, function (match, p1, p2) { 75797 cursor = { 75798 name: p1, 75799 styles: p2, 75800 next: cursor 75801 }; 75802 return p1; 75803 }); 75804 } 75805 } 75806 } 75807 75808 if (emotion_unitless_esm[key] !== 1 && !isCustomProperty(key) && typeof value === 'number' && value !== 0) { 75809 return value + 'px'; 75810 } 75811 75812 return value; 75813 }; 75814 75815 if (false) { var hyphenatedCache, hyphenPattern, msPattern, oldProcessStyleValue, contentValues, contentValuePattern; } 75816 75817 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.')); 75818 75819 function handleInterpolation(mergedProps, registered, interpolation) { 75820 if (interpolation == null) { 75821 return ''; 75822 } 75823 75824 if (interpolation.__emotion_styles !== undefined) { 75825 if (false) {} 75826 75827 return interpolation; 75828 } 75829 75830 switch (typeof interpolation) { 75831 case 'boolean': 75832 { 75833 return ''; 75834 } 75835 75836 case 'object': 75837 { 75838 if (interpolation.anim === 1) { 75839 cursor = { 75840 name: interpolation.name, 75841 styles: interpolation.styles, 75842 next: cursor 75843 }; 75844 return interpolation.name; 75845 } 75846 75847 if (interpolation.styles !== undefined) { 75848 var next = interpolation.next; 75849 75850 if (next !== undefined) { 75851 // not the most efficient thing ever but this is a pretty rare case 75852 // and there will be very few iterations of this generally 75853 while (next !== undefined) { 75854 cursor = { 75855 name: next.name, 75856 styles: next.styles, 75857 next: cursor 75858 }; 75859 next = next.next; 75860 } 75861 } 75862 75863 var styles = interpolation.styles + ";"; 75864 75865 if (false) {} 75866 75867 return styles; 75868 } 75869 75870 return createStringFromObject(mergedProps, registered, interpolation); 75871 } 75872 75873 case 'function': 75874 { 75875 if (mergedProps !== undefined) { 75876 var previousCursor = cursor; 75877 var result = interpolation(mergedProps); 75878 cursor = previousCursor; 75879 return handleInterpolation(mergedProps, registered, result); 75880 } else if (false) {} 75881 75882 break; 75883 } 75884 75885 case 'string': 75886 if (false) { var replaced, matched; } 75887 75888 break; 75889 } // finalize string values (regular strings and functions interpolated into css calls) 75890 75891 75892 if (registered == null) { 75893 return interpolation; 75894 } 75895 75896 var cached = registered[interpolation]; 75897 return cached !== undefined ? cached : interpolation; 75898 } 75899 75900 function createStringFromObject(mergedProps, registered, obj) { 75901 var string = ''; 75902 75903 if (Array.isArray(obj)) { 75904 for (var i = 0; i < obj.length; i++) { 75905 string += handleInterpolation(mergedProps, registered, obj[i]) + ";"; 75906 } 75907 } else { 75908 for (var _key in obj) { 75909 var value = obj[_key]; 75910 75911 if (typeof value !== 'object') { 75912 if (registered != null && registered[value] !== undefined) { 75913 string += _key + "{" + registered[value] + "}"; 75914 } else if (isProcessableValue(value)) { 75915 string += processStyleName(_key) + ":" + processStyleValue(_key, value) + ";"; 75916 } 75917 } else { 75918 if (_key === 'NO_COMPONENT_SELECTOR' && "production" !== 'production') {} 75919 75920 if (Array.isArray(value) && typeof value[0] === 'string' && (registered == null || registered[value[0]] === undefined)) { 75921 for (var _i = 0; _i < value.length; _i++) { 75922 if (isProcessableValue(value[_i])) { 75923 string += processStyleName(_key) + ":" + processStyleValue(_key, value[_i]) + ";"; 75924 } 75925 } 75926 } else { 75927 var interpolated = handleInterpolation(mergedProps, registered, value); 75928 75929 switch (_key) { 75930 case 'animation': 75931 case 'animationName': 75932 { 75933 string += processStyleName(_key) + ":" + interpolated + ";"; 75934 break; 75935 } 75936 75937 default: 75938 { 75939 if (false) {} 75940 75941 string += _key + "{" + interpolated + "}"; 75942 } 75943 } 75944 } 75945 } 75946 } 75947 } 75948 75949 return string; 75950 } 75951 75952 var labelPattern = /label:\s*([^\s;\n{]+)\s*(;|$)/g; 75953 var sourceMapPattern; 75954 75955 if (false) {} // this is the cursor for keyframes 75956 // keyframes are stored on the SerializedStyles object as a linked list 75957 75958 75959 var cursor; 75960 var emotion_serialize_browser_esm_serializeStyles = function serializeStyles(args, registered, mergedProps) { 75961 if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && args[0].styles !== undefined) { 75962 return args[0]; 75963 } 75964 75965 var stringMode = true; 75966 var styles = ''; 75967 cursor = undefined; 75968 var strings = args[0]; 75969 75970 if (strings == null || strings.raw === undefined) { 75971 stringMode = false; 75972 styles += handleInterpolation(mergedProps, registered, strings); 75973 } else { 75974 if (false) {} 75975 75976 styles += strings[0]; 75977 } // we start at 1 since we've already handled the first arg 75978 75979 75980 for (var i = 1; i < args.length; i++) { 75981 styles += handleInterpolation(mergedProps, registered, args[i]); 75982 75983 if (stringMode) { 75984 if (false) {} 75985 75986 styles += strings[i]; 75987 } 75988 } 75989 75990 var sourceMap; 75991 75992 if (false) {} // using a global regex with .exec is stateful so lastIndex has to be reset each time 75993 75994 75995 labelPattern.lastIndex = 0; 75996 var identifierName = ''; 75997 var match; // https://esbench.com/bench/5b809c2cf2949800a0f61fb5 75998 75999 while ((match = labelPattern.exec(styles)) !== null) { 76000 identifierName += '-' + // $FlowFixMe we know it's not null 76001 match[1]; 76002 } 76003 76004 var name = emotion_hash_esm(styles) + identifierName; 76005 76006 if (false) {} 76007 76008 return { 76009 name: name, 76010 styles: styles, 76011 next: cursor 76012 }; 76013 }; 76014 76015 76016 76017 ;// ./node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js 76018 76019 76020 76021 var syncFallback = function syncFallback(create) { 76022 return create(); 76023 }; 76024 76025 var useInsertionEffect = external_React_['useInsertion' + 'Effect'] ? external_React_['useInsertion' + 'Effect'] : false; 76026 var emotion_use_insertion_effect_with_fallbacks_browser_esm_useInsertionEffectAlwaysWithSyncFallback = useInsertionEffect || syncFallback; 76027 var useInsertionEffectWithLayoutFallback = (/* unused pure expression or super */ null && (useInsertionEffect || useLayoutEffect)); 76028 76029 76030 76031 ;// ./node_modules/@emotion/react/dist/emotion-element-6a883da9.browser.esm.js 76032 76033 76034 76035 76036 76037 76038 76039 76040 76041 var emotion_element_6a883da9_browser_esm_hasOwnProperty = {}.hasOwnProperty; 76042 76043 var EmotionCacheContext = /* #__PURE__ */(0,external_React_.createContext)( // we're doing this to avoid preconstruct's dead code elimination in this one case 76044 // because this module is primarily intended for the browser and node 76045 // but it's also required in react native and similar environments sometimes 76046 // and we could have a special build just for that 76047 // but this is much easier and the native packages 76048 // might use a different theme context in the future anyway 76049 typeof HTMLElement !== 'undefined' ? /* #__PURE__ */emotion_cache_browser_esm({ 76050 key: 'css' 76051 }) : null); 76052 76053 if (false) {} 76054 76055 var CacheProvider = EmotionCacheContext.Provider; 76056 var __unsafe_useEmotionCache = function useEmotionCache() { 76057 return useContext(EmotionCacheContext); 76058 }; 76059 76060 var withEmotionCache = function withEmotionCache(func) { 76061 // $FlowFixMe 76062 return /*#__PURE__*/(0,external_React_.forwardRef)(function (props, ref) { 76063 // the cache will never be null in the browser 76064 var cache = (0,external_React_.useContext)(EmotionCacheContext); 76065 return func(props, cache, ref); 76066 }); 76067 }; 76068 76069 var ThemeContext = /* #__PURE__ */(0,external_React_.createContext)({}); 76070 76071 if (false) {} 76072 76073 var useTheme = function useTheme() { 76074 return useContext(ThemeContext); 76075 }; 76076 76077 var getTheme = function getTheme(outerTheme, theme) { 76078 if (typeof theme === 'function') { 76079 var mergedTheme = theme(outerTheme); 76080 76081 if (false) {} 76082 76083 return mergedTheme; 76084 } 76085 76086 if (false) {} 76087 76088 return _extends({}, outerTheme, theme); 76089 }; 76090 76091 var createCacheWithTheme = /* #__PURE__ */(/* unused pure expression or super */ null && (weakMemoize(function (outerTheme) { 76092 return weakMemoize(function (theme) { 76093 return getTheme(outerTheme, theme); 76094 }); 76095 }))); 76096 var ThemeProvider = function ThemeProvider(props) { 76097 var theme = useContext(ThemeContext); 76098 76099 if (props.theme !== theme) { 76100 theme = createCacheWithTheme(theme)(props.theme); 76101 } 76102 76103 return /*#__PURE__*/createElement(ThemeContext.Provider, { 76104 value: theme 76105 }, props.children); 76106 }; 76107 function withTheme(Component) { 76108 var componentName = Component.displayName || Component.name || 'Component'; 76109 76110 var render = function render(props, ref) { 76111 var theme = useContext(ThemeContext); 76112 return /*#__PURE__*/createElement(Component, _extends({ 76113 theme: theme, 76114 ref: ref 76115 }, props)); 76116 }; // $FlowFixMe 76117 76118 76119 var WithTheme = /*#__PURE__*/forwardRef(render); 76120 WithTheme.displayName = "WithTheme(" + componentName + ")"; 76121 return hoistNonReactStatics(WithTheme, Component); 76122 } 76123 76124 var getLastPart = function getLastPart(functionName) { 76125 // The match may be something like 'Object.createEmotionProps' or 76126 // 'Loader.prototype.render' 76127 var parts = functionName.split('.'); 76128 return parts[parts.length - 1]; 76129 }; 76130 76131 var getFunctionNameFromStackTraceLine = function getFunctionNameFromStackTraceLine(line) { 76132 // V8 76133 var match = /^\s+at\s+([A-Za-z0-9$.]+)\s/.exec(line); 76134 if (match) return getLastPart(match[1]); // Safari / Firefox 76135 76136 match = /^([A-Za-z0-9$.]+)@/.exec(line); 76137 if (match) return getLastPart(match[1]); 76138 return undefined; 76139 }; 76140 76141 var internalReactFunctionNames = /* #__PURE__ */new Set(['renderWithHooks', 'processChild', 'finishClassComponent', 'renderToString']); // These identifiers come from error stacks, so they have to be valid JS 76142 // identifiers, thus we only need to replace what is a valid character for JS, 76143 // but not for CSS. 76144 76145 var sanitizeIdentifier = function sanitizeIdentifier(identifier) { 76146 return identifier.replace(/\$/g, '-'); 76147 }; 76148 76149 var getLabelFromStackTrace = function getLabelFromStackTrace(stackTrace) { 76150 if (!stackTrace) return undefined; 76151 var lines = stackTrace.split('\n'); 76152 76153 for (var i = 0; i < lines.length; i++) { 76154 var functionName = getFunctionNameFromStackTraceLine(lines[i]); // The first line of V8 stack traces is just "Error" 76155 76156 if (!functionName) continue; // If we reach one of these, we have gone too far and should quit 76157 76158 if (internalReactFunctionNames.has(functionName)) break; // The component name is the first function in the stack that starts with an 76159 // uppercase letter 76160 76161 if (/^[A-Z]/.test(functionName)) return sanitizeIdentifier(functionName); 76162 } 76163 76164 return undefined; 76165 }; 76166 76167 var typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__'; 76168 var labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__'; 76169 var createEmotionProps = function createEmotionProps(type, props) { 76170 if (false) {} 76171 76172 var newProps = {}; 76173 76174 for (var key in props) { 76175 if (emotion_element_6a883da9_browser_esm_hasOwnProperty.call(props, key)) { 76176 newProps[key] = props[key]; 76177 } 76178 } 76179 76180 newProps[typePropName] = type; // For performance, only call getLabelFromStackTrace in development and when 76181 // the label hasn't already been computed 76182 76183 if (false) { var label; } 76184 76185 return newProps; 76186 }; 76187 76188 var Insertion = function Insertion(_ref) { 76189 var cache = _ref.cache, 76190 serialized = _ref.serialized, 76191 isStringTag = _ref.isStringTag; 76192 registerStyles(cache, serialized, isStringTag); 76193 var rules = useInsertionEffectAlwaysWithSyncFallback(function () { 76194 return insertStyles(cache, serialized, isStringTag); 76195 }); 76196 76197 return null; 76198 }; 76199 76200 var Emotion = /* #__PURE__ */(/* unused pure expression or super */ null && (withEmotionCache(function (props, cache, ref) { 76201 var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works 76202 // not passing the registered cache to serializeStyles because it would 76203 // make certain babel optimisations not possible 76204 76205 if (typeof cssProp === 'string' && cache.registered[cssProp] !== undefined) { 76206 cssProp = cache.registered[cssProp]; 76207 } 76208 76209 var WrappedComponent = props[typePropName]; 76210 var registeredStyles = [cssProp]; 76211 var className = ''; 76212 76213 if (typeof props.className === 'string') { 76214 className = getRegisteredStyles(cache.registered, registeredStyles, props.className); 76215 } else if (props.className != null) { 76216 className = props.className + " "; 76217 } 76218 76219 var serialized = serializeStyles(registeredStyles, undefined, useContext(ThemeContext)); 76220 76221 if (false) { var labelFromStack; } 76222 76223 className += cache.key + "-" + serialized.name; 76224 var newProps = {}; 76225 76226 for (var key in props) { 76227 if (emotion_element_6a883da9_browser_esm_hasOwnProperty.call(props, key) && key !== 'css' && key !== typePropName && ( true || 0)) { 76228 newProps[key] = props[key]; 76229 } 76230 } 76231 76232 newProps.ref = ref; 76233 newProps.className = className; 76234 return /*#__PURE__*/createElement(Fragment, null, /*#__PURE__*/createElement(Insertion, { 76235 cache: cache, 76236 serialized: serialized, 76237 isStringTag: typeof WrappedComponent === 'string' 76238 }), /*#__PURE__*/createElement(WrappedComponent, newProps)); 76239 }))); 76240 76241 if (false) {} 76242 76243 76244 76245 ;// ./node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js 76246 var isBrowser = "object" !== 'undefined'; 76247 function emotion_utils_browser_esm_getRegisteredStyles(registered, registeredStyles, classNames) { 76248 var rawClassName = ''; 76249 classNames.split(' ').forEach(function (className) { 76250 if (registered[className] !== undefined) { 76251 registeredStyles.push(registered[className] + ";"); 76252 } else { 76253 rawClassName += className + " "; 76254 } 76255 }); 76256 return rawClassName; 76257 } 76258 var emotion_utils_browser_esm_registerStyles = function registerStyles(cache, serialized, isStringTag) { 76259 var className = cache.key + "-" + serialized.name; 76260 76261 if ( // we only need to add the styles to the registered cache if the 76262 // class name could be used further down 76263 // the tree but if it's a string tag, we know it won't 76264 // so we don't have to add it to registered cache. 76265 // this improves memory usage since we can avoid storing the whole style string 76266 (isStringTag === false || // we need to always store it if we're in compat mode and 76267 // in node since emotion-server relies on whether a style is in 76268 // the registered cache to know whether a style is global or not 76269 // also, note that this check will be dead code eliminated in the browser 76270 isBrowser === false ) && cache.registered[className] === undefined) { 76271 cache.registered[className] = serialized.styles; 76272 } 76273 }; 76274 var emotion_utils_browser_esm_insertStyles = function insertStyles(cache, serialized, isStringTag) { 76275 emotion_utils_browser_esm_registerStyles(cache, serialized, isStringTag); 76276 var className = cache.key + "-" + serialized.name; 76277 76278 if (cache.inserted[serialized.name] === undefined) { 76279 var current = serialized; 76280 76281 do { 76282 var maybeStyles = cache.insert(serialized === current ? "." + className : '', current, cache.sheet, true); 76283 76284 current = current.next; 76285 } while (current !== undefined); 76286 } 76287 }; 76288 76289 76290 76291 ;// ./node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js 76292 76293 76294 76295 76296 76297 76298 76299 76300 var testOmitPropsOnStringTag = isPropValid; 76301 76302 var testOmitPropsOnComponent = function testOmitPropsOnComponent(key) { 76303 return key !== 'theme'; 76304 }; 76305 76306 var getDefaultShouldForwardProp = function getDefaultShouldForwardProp(tag) { 76307 return typeof tag === 'string' && // 96 is one less than the char code 76308 // for "a" so this is checking that 76309 // it's a lowercase character 76310 tag.charCodeAt(0) > 96 ? testOmitPropsOnStringTag : testOmitPropsOnComponent; 76311 }; 76312 var composeShouldForwardProps = function composeShouldForwardProps(tag, options, isReal) { 76313 var shouldForwardProp; 76314 76315 if (options) { 76316 var optionsShouldForwardProp = options.shouldForwardProp; 76317 shouldForwardProp = tag.__emotion_forwardProp && optionsShouldForwardProp ? function (propName) { 76318 return tag.__emotion_forwardProp(propName) && optionsShouldForwardProp(propName); 76319 } : optionsShouldForwardProp; 76320 } 76321 76322 if (typeof shouldForwardProp !== 'function' && isReal) { 76323 shouldForwardProp = tag.__emotion_forwardProp; 76324 } 76325 76326 return shouldForwardProp; 76327 }; 76328 76329 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"; 76330 76331 var emotion_styled_base_browser_esm_Insertion = function Insertion(_ref) { 76332 var cache = _ref.cache, 76333 serialized = _ref.serialized, 76334 isStringTag = _ref.isStringTag; 76335 emotion_utils_browser_esm_registerStyles(cache, serialized, isStringTag); 76336 var rules = emotion_use_insertion_effect_with_fallbacks_browser_esm_useInsertionEffectAlwaysWithSyncFallback(function () { 76337 return emotion_utils_browser_esm_insertStyles(cache, serialized, isStringTag); 76338 }); 76339 76340 return null; 76341 }; 76342 76343 var createStyled = function createStyled(tag, options) { 76344 if (false) {} 76345 76346 var isReal = tag.__emotion_real === tag; 76347 var baseTag = isReal && tag.__emotion_base || tag; 76348 var identifierName; 76349 var targetClassName; 76350 76351 if (options !== undefined) { 76352 identifierName = options.label; 76353 targetClassName = options.target; 76354 } 76355 76356 var shouldForwardProp = composeShouldForwardProps(tag, options, isReal); 76357 var defaultShouldForwardProp = shouldForwardProp || getDefaultShouldForwardProp(baseTag); 76358 var shouldUseAs = !defaultShouldForwardProp('as'); 76359 return function () { 76360 var args = arguments; 76361 var styles = isReal && tag.__emotion_styles !== undefined ? tag.__emotion_styles.slice(0) : []; 76362 76363 if (identifierName !== undefined) { 76364 styles.push("label:" + identifierName + ";"); 76365 } 76366 76367 if (args[0] == null || args[0].raw === undefined) { 76368 styles.push.apply(styles, args); 76369 } else { 76370 if (false) {} 76371 76372 styles.push(args[0][0]); 76373 var len = args.length; 76374 var i = 1; 76375 76376 for (; i < len; i++) { 76377 if (false) {} 76378 76379 styles.push(args[i], args[0][i]); 76380 } 76381 } // $FlowFixMe: we need to cast StatelessFunctionalComponent to our PrivateStyledComponent class 76382 76383 76384 var Styled = withEmotionCache(function (props, cache, ref) { 76385 var FinalTag = shouldUseAs && props.as || baseTag; 76386 var className = ''; 76387 var classInterpolations = []; 76388 var mergedProps = props; 76389 76390 if (props.theme == null) { 76391 mergedProps = {}; 76392 76393 for (var key in props) { 76394 mergedProps[key] = props[key]; 76395 } 76396 76397 mergedProps.theme = (0,external_React_.useContext)(ThemeContext); 76398 } 76399 76400 if (typeof props.className === 'string') { 76401 className = emotion_utils_browser_esm_getRegisteredStyles(cache.registered, classInterpolations, props.className); 76402 } else if (props.className != null) { 76403 className = props.className + " "; 76404 } 76405 76406 var serialized = emotion_serialize_browser_esm_serializeStyles(styles.concat(classInterpolations), cache.registered, mergedProps); 76407 className += cache.key + "-" + serialized.name; 76408 76409 if (targetClassName !== undefined) { 76410 className += " " + targetClassName; 76411 } 76412 76413 var finalShouldForwardProp = shouldUseAs && shouldForwardProp === undefined ? getDefaultShouldForwardProp(FinalTag) : defaultShouldForwardProp; 76414 var newProps = {}; 76415 76416 for (var _key in props) { 76417 if (shouldUseAs && _key === 'as') continue; 76418 76419 if ( // $FlowFixMe 76420 finalShouldForwardProp(_key)) { 76421 newProps[_key] = props[_key]; 76422 } 76423 } 76424 76425 newProps.className = className; 76426 newProps.ref = ref; 76427 return /*#__PURE__*/(0,external_React_.createElement)(external_React_.Fragment, null, /*#__PURE__*/(0,external_React_.createElement)(emotion_styled_base_browser_esm_Insertion, { 76428 cache: cache, 76429 serialized: serialized, 76430 isStringTag: typeof FinalTag === 'string' 76431 }), /*#__PURE__*/(0,external_React_.createElement)(FinalTag, newProps)); 76432 }); 76433 Styled.displayName = identifierName !== undefined ? identifierName : "Styled(" + (typeof baseTag === 'string' ? baseTag : baseTag.displayName || baseTag.name || 'Component') + ")"; 76434 Styled.defaultProps = tag.defaultProps; 76435 Styled.__emotion_real = Styled; 76436 Styled.__emotion_base = baseTag; 76437 Styled.__emotion_styles = styles; 76438 Styled.__emotion_forwardProp = shouldForwardProp; 76439 Object.defineProperty(Styled, 'toString', { 76440 value: function value() { 76441 if (targetClassName === undefined && "production" !== 'production') {} // $FlowFixMe: coerce undefined to string 76442 76443 76444 return "." + targetClassName; 76445 } 76446 }); 76447 76448 Styled.withComponent = function (nextTag, nextOptions) { 76449 return createStyled(nextTag, extends_extends({}, options, nextOptions, { 76450 shouldForwardProp: composeShouldForwardProps(Styled, nextOptions, true) 76451 })).apply(void 0, styles); 76452 }; 76453 76454 return Styled; 76455 }; 76456 }; 76457 76458 /* harmony default export */ const emotion_styled_base_browser_esm = (createStyled); 76459 76460 ;// ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/width-height-tool.js 76461 76462 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)."; } 76463 /** 76464 * External dependencies 76465 */ 76466 76467 /** 76468 * WordPress dependencies 76469 */ 76470 76471 76472 76473 const SingleColumnToolsPanelItem = /*#__PURE__*/emotion_styled_base_browser_esm(external_wp_components_namespaceObject.__experimentalToolsPanelItem, true ? { 76474 target: "ef8pe3d0" 76475 } : 0)( true ? { 76476 name: "957xgf", 76477 styles: "grid-column:span 1" 76478 } : 0); 76479 76480 /** 76481 * @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit 76482 */ 76483 76484 /** 76485 * @typedef {Object} WidthHeightToolValue 76486 * @property {string} [width] Width CSS value. 76487 * @property {string} [height] Height CSS value. 76488 */ 76489 76490 /** 76491 * @callback WidthHeightToolOnChange 76492 * @param {WidthHeightToolValue} nextValue Next dimensions value. 76493 * @return {void} 76494 */ 76495 76496 /** 76497 * @typedef {Object} WidthHeightToolProps 76498 * @property {string} [panelId] ID of the panel that contains the controls. 76499 * @property {WidthHeightToolValue} [value] Current dimensions values. 76500 * @property {WidthHeightToolOnChange} [onChange] Callback to update the dimensions values. 76501 * @property {WPUnitControlUnit[]} [units] Units options. 76502 * @property {boolean} [isShownByDefault] Whether the panel is shown by default. 76503 */ 76504 76505 /** 76506 * Component that renders controls to edit the dimensions of an image or container. 76507 * 76508 * @param {WidthHeightToolProps} props The component props. 76509 * 76510 * @return {import('react').ReactElement} The width and height tool. 76511 */ 76512 function WidthHeightTool({ 76513 panelId, 76514 value = {}, 76515 onChange = () => {}, 76516 units, 76517 isShownByDefault = true 76518 }) { 76519 var _value$width, _value$height; 76520 // null, undefined, and 'auto' all represent the default value. 76521 const width = value.width === 'auto' ? '' : (_value$width = value.width) !== null && _value$width !== void 0 ? _value$width : ''; 76522 const height = value.height === 'auto' ? '' : (_value$height = value.height) !== null && _value$height !== void 0 ? _value$height : ''; 76523 const onDimensionChange = dimension => nextDimension => { 76524 const nextValue = { 76525 ...value 76526 }; 76527 // Empty strings or undefined may be passed and both represent removing the value. 76528 if (!nextDimension) { 76529 delete nextValue[dimension]; 76530 } else { 76531 nextValue[dimension] = nextDimension; 76532 } 76533 onChange(nextValue); 76534 }; 76535 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 76536 children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SingleColumnToolsPanelItem, { 76537 label: (0,external_wp_i18n_namespaceObject.__)('Width'), 76538 isShownByDefault: isShownByDefault, 76539 hasValue: () => width !== '', 76540 onDeselect: onDimensionChange('width'), 76541 panelId: panelId, 76542 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 76543 label: (0,external_wp_i18n_namespaceObject.__)('Width'), 76544 placeholder: (0,external_wp_i18n_namespaceObject.__)('Auto'), 76545 labelPosition: "top", 76546 units: units, 76547 min: 0, 76548 value: width, 76549 onChange: onDimensionChange('width'), 76550 size: "__unstable-large" 76551 }) 76552 }), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(SingleColumnToolsPanelItem, { 76553 label: (0,external_wp_i18n_namespaceObject.__)('Height'), 76554 isShownByDefault: isShownByDefault, 76555 hasValue: () => height !== '', 76556 onDeselect: onDimensionChange('height'), 76557 panelId: panelId, 76558 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalUnitControl, { 76559 label: (0,external_wp_i18n_namespaceObject.__)('Height'), 76560 placeholder: (0,external_wp_i18n_namespaceObject.__)('Auto'), 76561 labelPosition: "top", 76562 units: units, 76563 min: 0, 76564 value: height, 76565 onChange: onDimensionChange('height'), 76566 size: "__unstable-large" 76567 }) 76568 })] 76569 }); 76570 } 76571 76572 ;// ./node_modules/@wordpress/block-editor/build-module/components/dimensions-tool/index.js 76573 /** 76574 * WordPress dependencies 76575 */ 76576 76577 76578 /** 76579 * Internal dependencies 76580 */ 76581 76582 76583 76584 76585 /** 76586 * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps 76587 */ 76588 76589 /** 76590 * @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit 76591 */ 76592 76593 /** 76594 * @typedef {Object} Dimensions 76595 * @property {string} [width] CSS width property. 76596 * @property {string} [height] CSS height property. 76597 * @property {string} [scale] CSS object-fit property. 76598 * @property {string} [aspectRatio] CSS aspect-ratio property. 76599 */ 76600 76601 /** 76602 * @callback DimensionsControlsOnChange 76603 * @param {Dimensions} nextValue 76604 * @return {void} 76605 */ 76606 76607 /** 76608 * @typedef {Object} DimensionsControlsProps 76609 * @property {string} [panelId] ID of the panel that contains the controls. 76610 * @property {Dimensions} [value] Current dimensions values. 76611 * @property {DimensionsControlsOnChange} [onChange] Callback to update the dimensions values. 76612 * @property {SelectControlProps[]} [aspectRatioOptions] Aspect ratio options. 76613 * @property {SelectControlProps[]} [scaleOptions] Scale options. 76614 * @property {WPUnitControlUnit[]} [unitsOptions] Units options. 76615 */ 76616 76617 /** 76618 * Component that renders controls to edit the dimensions of an image or container. 76619 * 76620 * @param {DimensionsControlsProps} props The component props. 76621 * 76622 * @return {Element} The dimensions controls. 76623 */ 76624 76625 function DimensionsTool({ 76626 panelId, 76627 value = {}, 76628 onChange = () => {}, 76629 aspectRatioOptions, 76630 // Default options handled by AspectRatioTool. 76631 defaultAspectRatio = 'auto', 76632 // Match CSS default value for aspect-ratio. 76633 scaleOptions, 76634 // Default options handled by ScaleTool. 76635 defaultScale = 'fill', 76636 // Match CSS default value for object-fit. 76637 unitsOptions, 76638 // Default options handled by UnitControl. 76639 tools = ['aspectRatio', 'widthHeight', 'scale'] 76640 }) { 76641 // Coerce undefined and CSS default values to be null. 76642 const width = value.width === undefined || value.width === 'auto' ? null : value.width; 76643 const height = value.height === undefined || value.height === 'auto' ? null : value.height; 76644 const aspectRatio = value.aspectRatio === undefined || value.aspectRatio === 'auto' ? null : value.aspectRatio; 76645 const scale = value.scale === undefined || value.scale === 'fill' ? null : value.scale; 76646 76647 // Keep track of state internally, so when the value is cleared by means 76648 // other than directly editing that field, it's easier to restore the 76649 // previous value. 76650 const [lastScale, setLastScale] = (0,external_wp_element_namespaceObject.useState)(scale); 76651 const [lastAspectRatio, setLastAspectRatio] = (0,external_wp_element_namespaceObject.useState)(aspectRatio); 76652 76653 // 'custom' is not a valid value for CSS aspect-ratio, but it is used in the 76654 // dropdown to indicate that setting both the width and height is the same 76655 // as a custom aspect ratio. 76656 const aspectRatioValue = width && height ? 'custom' : lastAspectRatio; 76657 const showScaleControl = aspectRatio || width && height; 76658 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, { 76659 children: [tools.includes('aspectRatio') && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(AspectRatioTool, { 76660 panelId: panelId, 76661 options: aspectRatioOptions, 76662 defaultValue: defaultAspectRatio, 76663 value: aspectRatioValue, 76664 onChange: nextAspectRatio => { 76665 const nextValue = { 76666 ...value 76667 }; 76668 76669 // 'auto' is CSS default, so it gets treated as null. 76670 nextAspectRatio = nextAspectRatio === 'auto' ? null : nextAspectRatio; 76671 setLastAspectRatio(nextAspectRatio); 76672 76673 // Update aspectRatio. 76674 if (!nextAspectRatio) { 76675 delete nextValue.aspectRatio; 76676 } else { 76677 nextValue.aspectRatio = nextAspectRatio; 76678 } 76679 76680 // Auto-update scale. 76681 if (!nextAspectRatio) { 76682 delete nextValue.scale; 76683 } else if (lastScale) { 76684 nextValue.scale = lastScale; 76685 } else { 76686 nextValue.scale = defaultScale; 76687 setLastScale(defaultScale); 76688 } 76689 76690 // Auto-update width and height. 76691 if ('custom' !== nextAspectRatio && width && height) { 76692 delete nextValue.height; 76693 } 76694 onChange(nextValue); 76695 } 76696 }), tools.includes('widthHeight') && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(WidthHeightTool, { 76697 panelId: panelId, 76698 units: unitsOptions, 76699 value: { 76700 width, 76701 height 76702 }, 76703 onChange: ({ 76704 width: nextWidth, 76705 height: nextHeight 76706 }) => { 76707 const nextValue = { 76708 ...value 76709 }; 76710 76711 // 'auto' is CSS default, so it gets treated as null. 76712 nextWidth = nextWidth === 'auto' ? null : nextWidth; 76713 nextHeight = nextHeight === 'auto' ? null : nextHeight; 76714 76715 // Update width. 76716 if (!nextWidth) { 76717 delete nextValue.width; 76718 } else { 76719 nextValue.width = nextWidth; 76720 } 76721 76722 // Update height. 76723 if (!nextHeight) { 76724 delete nextValue.height; 76725 } else { 76726 nextValue.height = nextHeight; 76727 } 76728 76729 // Auto-update aspectRatio. 76730 if (nextWidth && nextHeight) { 76731 delete nextValue.aspectRatio; 76732 } else if (lastAspectRatio) { 76733 nextValue.aspectRatio = lastAspectRatio; 76734 } else { 76735 // No setting defaultAspectRatio here, because 76736 // aspectRatio is optional in this scenario, 76737 // unlike scale. 76738 } 76739 76740 // Auto-update scale. 76741 if (!lastAspectRatio && !!nextWidth !== !!nextHeight) { 76742 delete nextValue.scale; 76743 } else if (lastScale) { 76744 nextValue.scale = lastScale; 76745 } else { 76746 nextValue.scale = defaultScale; 76747 setLastScale(defaultScale); 76748 } 76749 onChange(nextValue); 76750 } 76751 }), tools.includes('scale') && showScaleControl && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ScaleTool, { 76752 panelId: panelId, 76753 options: scaleOptions, 76754 defaultValue: defaultScale, 76755 value: lastScale, 76756 onChange: nextScale => { 76757 const nextValue = { 76758 ...value 76759 }; 76760 76761 // 'fill' is CSS default, so it gets treated as null. 76762 nextScale = nextScale === 'fill' ? null : nextScale; 76763 setLastScale(nextScale); 76764 76765 // Update scale. 76766 if (!nextScale) { 76767 delete nextValue.scale; 76768 } else { 76769 nextValue.scale = nextScale; 76770 } 76771 onChange(nextValue); 76772 } 76773 })] 76774 }); 76775 } 76776 /* harmony default export */ const dimensions_tool = (DimensionsTool); 76777 76778 ;// ./node_modules/@wordpress/block-editor/build-module/components/resolution-tool/index.js 76779 /** 76780 * WordPress dependencies 76781 */ 76782 76783 76784 76785 const DEFAULT_SIZE_OPTIONS = [{ 76786 label: (0,external_wp_i18n_namespaceObject._x)('Thumbnail', 'Image size option for resolution control'), 76787 value: 'thumbnail' 76788 }, { 76789 label: (0,external_wp_i18n_namespaceObject._x)('Medium', 'Image size option for resolution control'), 76790 value: 'medium' 76791 }, { 76792 label: (0,external_wp_i18n_namespaceObject._x)('Large', 'Image size option for resolution control'), 76793 value: 'large' 76794 }, { 76795 label: (0,external_wp_i18n_namespaceObject._x)('Full Size', 'Image size option for resolution control'), 76796 value: 'full' 76797 }]; 76798 function ResolutionTool({ 76799 panelId, 76800 value, 76801 onChange, 76802 options = DEFAULT_SIZE_OPTIONS, 76803 defaultValue = DEFAULT_SIZE_OPTIONS[0].value, 76804 isShownByDefault = true, 76805 resetAllFilter 76806 }) { 76807 const displayValue = value !== null && value !== void 0 ? value : defaultValue; 76808 return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.__experimentalToolsPanelItem, { 76809 hasValue: () => displayValue !== defaultValue, 76810 label: (0,external_wp_i18n_namespaceObject.__)('Resolution'), 76811 onDeselect: () => onChange(defaultValue), 76812 isShownByDefault: isShownByDefault, 76813 panelId: panelId, 76814 resetAllFilter: resetAllFilter, 76815 children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.SelectControl, { 76816 __nextHasNoMarginBottom: true, 76817 label: (0,external_wp_i18n_namespaceObject.__)('Resolution'), 76818 value: displayValue, 76819 options: options, 76820 onChange: onChange, 76821 help: (0,external_wp_i18n_namespaceObject.__)('Select the size of the source image.'), 76822 size: "__unstable-large" 76823 }) 76824 }); 76825 } 76826 76827 ;// ./node_modules/@wordpress/block-editor/build-module/private-apis.js 76828 /** 76829 * Internal dependencies 76830 */ 76831 76832 76833 76834 76835 76836 76837 76838 76839 76840 76841 76842 76843 76844 76845 76846 76847 76848 76849 76850 76851 76852 76853 76854 76855 76856 76857 76858 76859 76860 76861 76862 76863 76864 /** 76865 * Private @wordpress/block-editor APIs. 76866 */ 76867 const privateApis = {}; 76868 lock(privateApis, { 76869 ...global_styles_namespaceObject, 76870 ExperimentalBlockCanvas: ExperimentalBlockCanvas, 76871 ExperimentalBlockEditorProvider: ExperimentalBlockEditorProvider, 76872 getDuotoneFilter: getDuotoneFilter, 76873 getRichTextValues: getRichTextValues, 76874 PrivateQuickInserter: QuickInserter, 76875 extractWords: extractWords, 76876 getNormalizedSearchTerms: getNormalizedSearchTerms, 76877 normalizeString: normalizeString, 76878 PrivateListView: PrivateListView, 76879 ResizableBoxPopover: ResizableBoxPopover, 76880 useHasBlockToolbar: useHasBlockToolbar, 76881 cleanEmptyObject: utils_cleanEmptyObject, 76882 BlockQuickNavigation: BlockQuickNavigation, 76883 LayoutStyle: LayoutStyle, 76884 BlockManager: BlockManager, 76885 BlockRemovalWarningModal: BlockRemovalWarningModal, 76886 useLayoutClasses: useLayoutClasses, 76887 useLayoutStyles: useLayoutStyles, 76888 DimensionsTool: dimensions_tool, 76889 ResolutionTool: ResolutionTool, 76890 TabbedSidebar: tabbed_sidebar, 76891 TextAlignmentControl: TextAlignmentControl, 76892 usesContextKey: usesContextKey, 76893 useFlashEditableBlocks: useFlashEditableBlocks, 76894 useZoomOut: useZoomOut, 76895 globalStylesDataKey: globalStylesDataKey, 76896 globalStylesLinksDataKey: globalStylesLinksDataKey, 76897 selectBlockPatternsKey: selectBlockPatternsKey, 76898 requiresWrapperOnCopy: requiresWrapperOnCopy, 76899 PrivateRichText: PrivateRichText, 76900 PrivateInserterLibrary: PrivateInserterLibrary, 76901 reusableBlocksSelectKey: reusableBlocksSelectKey, 76902 PrivateBlockPopover: PrivateBlockPopover, 76903 PrivatePublishDateTimePicker: PrivatePublishDateTimePicker, 76904 useSpacingSizes: useSpacingSizes, 76905 useBlockDisplayTitle: useBlockDisplayTitle, 76906 __unstableBlockStyleVariationOverridesWithConfig: __unstableBlockStyleVariationOverridesWithConfig, 76907 setBackgroundStyleDefaults: setBackgroundStyleDefaults, 76908 sectionRootClientIdKey: sectionRootClientIdKey, 76909 CommentIconSlotFill: block_comment_icon_slot, 76910 CommentIconToolbarSlotFill: block_comment_icon_toolbar_slot 76911 }); 76912 76913 ;// ./node_modules/@wordpress/block-editor/build-module/index.js 76914 /** 76915 * Internal dependencies 76916 */ 76917 76918 76919 76920 76921 76922 76923 76924 76925 76926 })(); 76927 76928 (window.wp = window.wp || {}).blockEditor = __webpack_exports__; 76929 /******/ })() 76930 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Apr 24 08:20:01 2025 | Cross-referenced by PHPXref |