| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 "use strict"; 2 var wp; 3 (wp ||= {}).richText = (() => { 4 var __create = Object.create; 5 var __defProp = Object.defineProperty; 6 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 7 var __getOwnPropNames = Object.getOwnPropertyNames; 8 var __getProtoOf = Object.getPrototypeOf; 9 var __hasOwnProp = Object.prototype.hasOwnProperty; 10 var __commonJS = (cb, mod) => function __require() { 11 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 12 }; 13 var __export = (target, all) => { 14 for (var name in all) 15 __defProp(target, name, { get: all[name], enumerable: true }); 16 }; 17 var __copyProps = (to, from, except, desc) => { 18 if (from && typeof from === "object" || typeof from === "function") { 19 for (let key of __getOwnPropNames(from)) 20 if (!__hasOwnProp.call(to, key) && key !== except) 21 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 22 } 23 return to; 24 }; 25 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 26 // If the importer is in node compatibility mode or this is not an ESM 27 // file that has been converted to a CommonJS file using a Babel- 28 // compatible transform (i.e. "__esModule" has not been set), then set 29 // "default" to the CommonJS "module.exports" for node compatibility. 30 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 31 mod 32 )); 33 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 34 35 // package-external:@wordpress/data 36 var require_data = __commonJS({ 37 "package-external:@wordpress/data"(exports, module) { 38 module.exports = window.wp.data; 39 } 40 }); 41 42 // package-external:@wordpress/escape-html 43 var require_escape_html = __commonJS({ 44 "package-external:@wordpress/escape-html"(exports, module) { 45 module.exports = window.wp.escapeHtml; 46 } 47 }); 48 49 // package-external:@wordpress/a11y 50 var require_a11y = __commonJS({ 51 "package-external:@wordpress/a11y"(exports, module) { 52 module.exports = window.wp.a11y; 53 } 54 }); 55 56 // package-external:@wordpress/i18n 57 var require_i18n = __commonJS({ 58 "package-external:@wordpress/i18n"(exports, module) { 59 module.exports = window.wp.i18n; 60 } 61 }); 62 63 // package-external:@wordpress/element 64 var require_element = __commonJS({ 65 "package-external:@wordpress/element"(exports, module) { 66 module.exports = window.wp.element; 67 } 68 }); 69 70 // package-external:@wordpress/deprecated 71 var require_deprecated = __commonJS({ 72 "package-external:@wordpress/deprecated"(exports, module) { 73 module.exports = window.wp.deprecated; 74 } 75 }); 76 77 // package-external:@wordpress/compose 78 var require_compose = __commonJS({ 79 "package-external:@wordpress/compose"(exports, module) { 80 module.exports = window.wp.compose; 81 } 82 }); 83 84 // package-external:@wordpress/dom 85 var require_dom = __commonJS({ 86 "package-external:@wordpress/dom"(exports, module) { 87 module.exports = window.wp.dom; 88 } 89 }); 90 91 // package-external:@wordpress/keycodes 92 var require_keycodes = __commonJS({ 93 "package-external:@wordpress/keycodes"(exports, module) { 94 module.exports = window.wp.keycodes; 95 } 96 }); 97 98 // packages/rich-text/build-module/index.js 99 var index_exports = {}; 100 __export(index_exports, { 101 RichTextData: () => RichTextData, 102 __experimentalRichText: () => __experimentalRichText, 103 __unstableCreateElement: () => createElement, 104 __unstableToDom: () => toDom, 105 __unstableUseRichText: () => useRichText, 106 applyFormat: () => applyFormat, 107 concat: () => concat, 108 create: () => create, 109 getActiveFormat: () => getActiveFormat, 110 getActiveFormats: () => getActiveFormats, 111 getActiveObject: () => getActiveObject, 112 getTextContent: () => getTextContent, 113 insert: () => insert, 114 insertObject: () => insertObject, 115 isCollapsed: () => isCollapsed, 116 isEmpty: () => isEmpty, 117 join: () => join, 118 registerFormatType: () => registerFormatType, 119 remove: () => remove2, 120 removeFormat: () => removeFormat, 121 replace: () => replace2, 122 slice: () => slice, 123 split: () => split, 124 store: () => store, 125 toHTMLString: () => toHTMLString, 126 toggleFormat: () => toggleFormat, 127 unregisterFormatType: () => unregisterFormatType, 128 useAnchor: () => useAnchor, 129 useAnchorRef: () => useAnchorRef 130 }); 131 132 // packages/rich-text/build-module/store/index.js 133 var import_data3 = __toESM(require_data()); 134 135 // packages/rich-text/build-module/store/reducer.js 136 var import_data = __toESM(require_data()); 137 function formatTypes(state = {}, action) { 138 switch (action.type) { 139 case "ADD_FORMAT_TYPES": 140 return { 141 ...state, 142 // Key format types by their name. 143 ...action.formatTypes.reduce( 144 (newFormatTypes, type) => ({ 145 ...newFormatTypes, 146 [type.name]: type 147 }), 148 {} 149 ) 150 }; 151 case "REMOVE_FORMAT_TYPES": 152 return Object.fromEntries( 153 Object.entries(state).filter( 154 ([key]) => !action.names.includes(key) 155 ) 156 ); 157 } 158 return state; 159 } 160 var reducer_default = (0, import_data.combineReducers)({ formatTypes }); 161 162 // packages/rich-text/build-module/store/selectors.js 163 var selectors_exports = {}; 164 __export(selectors_exports, { 165 getFormatType: () => getFormatType, 166 getFormatTypeForBareElement: () => getFormatTypeForBareElement, 167 getFormatTypeForClassName: () => getFormatTypeForClassName, 168 getFormatTypes: () => getFormatTypes 169 }); 170 var import_data2 = __toESM(require_data()); 171 var getFormatTypes = (0, import_data2.createSelector)( 172 (state) => Object.values(state.formatTypes), 173 (state) => [state.formatTypes] 174 ); 175 function getFormatType(state, name) { 176 return state.formatTypes[name]; 177 } 178 function getFormatTypeForBareElement(state, bareElementTagName) { 179 const formatTypes2 = getFormatTypes(state); 180 return formatTypes2.find(({ className, tagName }) => { 181 return className === null && bareElementTagName === tagName; 182 }) || formatTypes2.find(({ className, tagName }) => { 183 return className === null && "*" === tagName; 184 }); 185 } 186 function getFormatTypeForClassName(state, elementClassName) { 187 return getFormatTypes(state).find(({ className }) => { 188 if (className === null) { 189 return false; 190 } 191 return ` $elementClassName} `.indexOf(` $className} `) >= 0; 192 }); 193 } 194 195 // packages/rich-text/build-module/store/actions.js 196 var actions_exports = {}; 197 __export(actions_exports, { 198 addFormatTypes: () => addFormatTypes, 199 removeFormatTypes: () => removeFormatTypes 200 }); 201 function addFormatTypes(formatTypes2) { 202 return { 203 type: "ADD_FORMAT_TYPES", 204 formatTypes: Array.isArray(formatTypes2) ? formatTypes2 : [formatTypes2] 205 }; 206 } 207 function removeFormatTypes(names) { 208 return { 209 type: "REMOVE_FORMAT_TYPES", 210 names: Array.isArray(names) ? names : [names] 211 }; 212 } 213 214 // packages/rich-text/build-module/store/index.js 215 var STORE_NAME = "core/rich-text"; 216 var store = (0, import_data3.createReduxStore)(STORE_NAME, { 217 reducer: reducer_default, 218 selectors: selectors_exports, 219 actions: actions_exports 220 }); 221 (0, import_data3.register)(store); 222 223 // packages/rich-text/build-module/is-format-equal.js 224 function isFormatEqual(format1, format2) { 225 if (format1 === format2) { 226 return true; 227 } 228 if (!format1 || !format2) { 229 return false; 230 } 231 if (format1.type !== format2.type) { 232 return false; 233 } 234 const attributes1 = format1.attributes; 235 const attributes2 = format2.attributes; 236 if (attributes1 === attributes2) { 237 return true; 238 } 239 if (!attributes1 || !attributes2) { 240 return false; 241 } 242 const keys1 = Object.keys(attributes1); 243 const keys2 = Object.keys(attributes2); 244 if (keys1.length !== keys2.length) { 245 return false; 246 } 247 const length = keys1.length; 248 for (let i2 = 0; i2 < length; i2++) { 249 const name = keys1[i2]; 250 if (attributes1[name] !== attributes2[name]) { 251 return false; 252 } 253 } 254 return true; 255 } 256 257 // packages/rich-text/build-module/normalise-formats.js 258 function normaliseFormats(value) { 259 const newFormats = value.formats.slice(); 260 newFormats.forEach((formatsAtIndex, index) => { 261 const formatsAtPreviousIndex = newFormats[index - 1]; 262 if (formatsAtPreviousIndex) { 263 const newFormatsAtIndex = formatsAtIndex.slice(); 264 newFormatsAtIndex.forEach((format, formatIndex) => { 265 const previousFormat = formatsAtPreviousIndex[formatIndex]; 266 if (isFormatEqual(format, previousFormat)) { 267 newFormatsAtIndex[formatIndex] = previousFormat; 268 } 269 }); 270 newFormats[index] = newFormatsAtIndex; 271 } 272 }); 273 return { 274 ...value, 275 formats: newFormats 276 }; 277 } 278 279 // packages/rich-text/build-module/apply-format.js 280 function replace(array, index, value) { 281 array = array.slice(); 282 array[index] = value; 283 return array; 284 } 285 function applyFormat(value, format, startIndex = value.start, endIndex = value.end) { 286 const { formats, activeFormats } = value; 287 const newFormats = formats.slice(); 288 if (startIndex === endIndex) { 289 const startFormat = newFormats[startIndex]?.find( 290 ({ type }) => type === format.type 291 ); 292 if (startFormat) { 293 const index = newFormats[startIndex].indexOf(startFormat); 294 while (newFormats[startIndex] && newFormats[startIndex][index] === startFormat) { 295 newFormats[startIndex] = replace( 296 newFormats[startIndex], 297 index, 298 format 299 ); 300 startIndex--; 301 } 302 endIndex++; 303 while (newFormats[endIndex] && newFormats[endIndex][index] === startFormat) { 304 newFormats[endIndex] = replace( 305 newFormats[endIndex], 306 index, 307 format 308 ); 309 endIndex++; 310 } 311 } 312 } else { 313 let position = Infinity; 314 for (let index = startIndex; index < endIndex; index++) { 315 if (newFormats[index]) { 316 newFormats[index] = newFormats[index].filter( 317 ({ type }) => type !== format.type 318 ); 319 const length = newFormats[index].length; 320 if (length < position) { 321 position = length; 322 } 323 } else { 324 newFormats[index] = []; 325 position = 0; 326 } 327 } 328 for (let index = startIndex; index < endIndex; index++) { 329 newFormats[index].splice(position, 0, format); 330 } 331 } 332 return normaliseFormats({ 333 ...value, 334 formats: newFormats, 335 // Always revise active formats. This serves as a placeholder for new 336 // inputs with the format so new input appears with the format applied, 337 // and ensures a format of the same type uses the latest values. 338 activeFormats: [ 339 ...activeFormats?.filter( 340 ({ type }) => type !== format.type 341 ) || [], 342 format 343 ] 344 }); 345 } 346 347 // packages/rich-text/build-module/create.js 348 var import_data5 = __toESM(require_data()); 349 350 // packages/rich-text/build-module/create-element.js 351 function createElement({ implementation }, html) { 352 if (!createElement.body) { 353 createElement.body = implementation.createHTMLDocument("").body; 354 } 355 createElement.body.innerHTML = html; 356 return createElement.body; 357 } 358 359 // packages/rich-text/build-module/special-characters.js 360 var OBJECT_REPLACEMENT_CHARACTER = "\uFFFC"; 361 var ZWNBSP = "\uFEFF"; 362 363 // packages/rich-text/build-module/to-html-string.js 364 var import_escape_html = __toESM(require_escape_html()); 365 366 // packages/rich-text/build-module/get-active-formats.js 367 function getActiveFormats(value, EMPTY_ACTIVE_FORMATS3 = []) { 368 const { formats, start, end, activeFormats } = value; 369 if (start === void 0) { 370 return EMPTY_ACTIVE_FORMATS3; 371 } 372 if (start === end) { 373 if (activeFormats) { 374 return activeFormats; 375 } 376 const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS3; 377 const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS3; 378 if (formatsBefore.length < formatsAfter.length) { 379 return formatsBefore; 380 } 381 return formatsAfter; 382 } 383 if (!formats[start]) { 384 return EMPTY_ACTIVE_FORMATS3; 385 } 386 const selectedFormats = formats.slice(start, end); 387 const _activeFormats = [...selectedFormats[0]]; 388 let i2 = selectedFormats.length; 389 while (i2--) { 390 const formatsAtIndex = selectedFormats[i2]; 391 if (!formatsAtIndex) { 392 return EMPTY_ACTIVE_FORMATS3; 393 } 394 let ii = _activeFormats.length; 395 while (ii--) { 396 const format = _activeFormats[ii]; 397 if (!formatsAtIndex.find( 398 (_format) => isFormatEqual(format, _format) 399 )) { 400 _activeFormats.splice(ii, 1); 401 } 402 } 403 if (_activeFormats.length === 0) { 404 return EMPTY_ACTIVE_FORMATS3; 405 } 406 } 407 return _activeFormats || EMPTY_ACTIVE_FORMATS3; 408 } 409 410 // packages/rich-text/build-module/get-format-type.js 411 var import_data4 = __toESM(require_data()); 412 function getFormatType2(name) { 413 return (0, import_data4.select)(store).getFormatType(name); 414 } 415 416 // packages/rich-text/build-module/to-tree.js 417 function restoreOnAttributes(attributes, isEditableTree) { 418 if (isEditableTree) { 419 return attributes; 420 } 421 const newAttributes = {}; 422 for (const key in attributes) { 423 let newKey = key; 424 if (key.startsWith("data-disable-rich-text-")) { 425 newKey = key.slice("data-disable-rich-text-".length); 426 } 427 newAttributes[newKey] = attributes[key]; 428 } 429 return newAttributes; 430 } 431 function fromFormat({ 432 type, 433 tagName, 434 attributes, 435 unregisteredAttributes, 436 object, 437 boundaryClass, 438 isEditableTree 439 }) { 440 const formatType = getFormatType2(type); 441 let elementAttributes = {}; 442 if (boundaryClass && isEditableTree) { 443 elementAttributes["data-rich-text-format-boundary"] = "true"; 444 } 445 if (!formatType) { 446 if (attributes) { 447 elementAttributes = { ...attributes, ...elementAttributes }; 448 } 449 return { 450 type, 451 attributes: restoreOnAttributes( 452 elementAttributes, 453 isEditableTree 454 ), 455 object 456 }; 457 } 458 elementAttributes = { ...unregisteredAttributes, ...elementAttributes }; 459 for (const name in attributes) { 460 const key = formatType.attributes ? formatType.attributes[name] : false; 461 if (key) { 462 elementAttributes[key] = attributes[name]; 463 } else { 464 elementAttributes[name] = attributes[name]; 465 } 466 } 467 if (formatType.className) { 468 if (elementAttributes.class) { 469 elementAttributes.class = `$formatType.className} $elementAttributes.class}`; 470 } else { 471 elementAttributes.class = formatType.className; 472 } 473 } 474 return { 475 type: tagName || formatType.tagName, 476 object: formatType.object, 477 attributes: restoreOnAttributes(elementAttributes, isEditableTree) 478 }; 479 } 480 function isEqualUntil(a2, b2, index) { 481 do { 482 if (a2[index] !== b2[index]) { 483 return false; 484 } 485 } while (index--); 486 return true; 487 } 488 function toTree({ 489 value, 490 preserveWhiteSpace, 491 createEmpty: createEmpty2, 492 append: append3, 493 getLastChild: getLastChild3, 494 getParent: getParent3, 495 isText: isText3, 496 getText: getText3, 497 remove: remove4, 498 appendText: appendText3, 499 onStartIndex, 500 onEndIndex, 501 isEditableTree, 502 placeholder 503 }) { 504 const { formats, replacements, text, start, end } = value; 505 const formatsLength = formats.length + 1; 506 const tree = createEmpty2(); 507 const activeFormats = getActiveFormats(value); 508 const deepestActiveFormat = activeFormats[activeFormats.length - 1]; 509 let lastCharacterFormats; 510 let lastCharacter; 511 append3(tree, ""); 512 for (let i2 = 0; i2 < formatsLength; i2++) { 513 const character = text.charAt(i2); 514 const shouldInsertPadding = isEditableTree && // Pad the line if the line is empty. 515 (!lastCharacter || // Pad the line if the previous character is a line break, otherwise 516 // the line break won't be visible. 517 lastCharacter === "\n"); 518 const characterFormats = formats[i2]; 519 let pointer = getLastChild3(tree); 520 if (characterFormats) { 521 characterFormats.forEach((format, formatIndex) => { 522 if (pointer && lastCharacterFormats && // Reuse the last element if all formats remain the same. 523 isEqualUntil( 524 characterFormats, 525 lastCharacterFormats, 526 formatIndex 527 )) { 528 pointer = getLastChild3(pointer); 529 return; 530 } 531 const { type, tagName, attributes, unregisteredAttributes } = format; 532 const boundaryClass = isEditableTree && format === deepestActiveFormat; 533 const parent = getParent3(pointer); 534 const newNode = append3( 535 parent, 536 fromFormat({ 537 type, 538 tagName, 539 attributes, 540 unregisteredAttributes, 541 boundaryClass, 542 isEditableTree 543 }) 544 ); 545 if (isText3(pointer) && getText3(pointer).length === 0) { 546 remove4(pointer); 547 } 548 pointer = append3(newNode, ""); 549 }); 550 } 551 if (i2 === 0) { 552 if (onStartIndex && start === 0) { 553 onStartIndex(tree, pointer); 554 } 555 if (onEndIndex && end === 0) { 556 onEndIndex(tree, pointer); 557 } 558 } 559 if (character === OBJECT_REPLACEMENT_CHARACTER) { 560 const replacement = replacements[i2]; 561 if (!replacement) { 562 continue; 563 } 564 const { type, attributes, innerHTML } = replacement; 565 const formatType = getFormatType2(type); 566 if (isEditableTree && type === "#comment") { 567 pointer = append3(getParent3(pointer), { 568 type: "span", 569 attributes: { 570 contenteditable: "false", 571 "data-rich-text-comment": attributes["data-rich-text-comment"] 572 } 573 }); 574 append3( 575 append3(pointer, { type: "span" }), 576 attributes["data-rich-text-comment"].trim() 577 ); 578 } else if (!isEditableTree && type === "script") { 579 pointer = append3( 580 getParent3(pointer), 581 fromFormat({ 582 type: "script", 583 isEditableTree 584 }) 585 ); 586 append3(pointer, { 587 html: decodeURIComponent( 588 attributes["data-rich-text-script"] 589 ) 590 }); 591 } else if (formatType?.contentEditable === false) { 592 if (innerHTML || isEditableTree) { 593 pointer = getParent3(pointer); 594 if (isEditableTree) { 595 const attrs = { 596 contenteditable: "false", 597 "data-rich-text-bogus": true 598 }; 599 if (start === i2 && end === i2 + 1) { 600 attrs["data-rich-text-format-boundary"] = true; 601 } 602 pointer = append3(pointer, { 603 type: "span", 604 attributes: attrs 605 }); 606 if (isEditableTree && i2 + 1 === text.length) { 607 append3(getParent3(pointer), ZWNBSP); 608 } 609 } 610 pointer = append3( 611 pointer, 612 fromFormat({ 613 ...replacement, 614 isEditableTree 615 }) 616 ); 617 if (innerHTML) { 618 append3(pointer, { 619 html: innerHTML 620 }); 621 } 622 } 623 } else { 624 pointer = append3( 625 getParent3(pointer), 626 fromFormat({ 627 ...replacement, 628 object: true, 629 isEditableTree 630 }) 631 ); 632 } 633 pointer = append3(getParent3(pointer), ""); 634 } else if (!preserveWhiteSpace && character === "\n") { 635 pointer = append3(getParent3(pointer), { 636 type: "br", 637 attributes: isEditableTree ? { 638 "data-rich-text-line-break": "true" 639 } : void 0, 640 object: true 641 }); 642 pointer = append3(getParent3(pointer), ""); 643 } else if (!isText3(pointer)) { 644 pointer = append3(getParent3(pointer), character); 645 } else { 646 appendText3(pointer, character); 647 } 648 if (onStartIndex && start === i2 + 1) { 649 onStartIndex(tree, pointer); 650 } 651 if (onEndIndex && end === i2 + 1) { 652 onEndIndex(tree, pointer); 653 } 654 if (shouldInsertPadding && i2 === text.length) { 655 append3(getParent3(pointer), ZWNBSP); 656 if (placeholder && text.length === 0) { 657 append3(getParent3(pointer), { 658 type: "span", 659 attributes: { 660 "data-rich-text-placeholder": placeholder, 661 // Necessary to prevent the placeholder from catching 662 // selection and being editable. 663 style: "pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;" 664 } 665 }); 666 } 667 } 668 lastCharacterFormats = characterFormats; 669 lastCharacter = character; 670 } 671 return tree; 672 } 673 674 // packages/rich-text/build-module/to-html-string.js 675 function toHTMLString({ value, preserveWhiteSpace }) { 676 const tree = toTree({ 677 value, 678 preserveWhiteSpace, 679 createEmpty, 680 append, 681 getLastChild, 682 getParent, 683 isText, 684 getText, 685 remove, 686 appendText 687 }); 688 return createChildrenHTML(tree.children); 689 } 690 function createEmpty() { 691 return {}; 692 } 693 function getLastChild({ children }) { 694 return children && children[children.length - 1]; 695 } 696 function append(parent, object) { 697 if (typeof object === "string") { 698 object = { text: object }; 699 } 700 object.parent = parent; 701 parent.children = parent.children || []; 702 parent.children.push(object); 703 return object; 704 } 705 function appendText(object, text) { 706 object.text += text; 707 } 708 function getParent({ parent }) { 709 return parent; 710 } 711 function isText({ text }) { 712 return typeof text === "string"; 713 } 714 function getText({ text }) { 715 return text; 716 } 717 function remove(object) { 718 const index = object.parent.children.indexOf(object); 719 if (index !== -1) { 720 object.parent.children.splice(index, 1); 721 } 722 return object; 723 } 724 function createElementHTML({ type, attributes, object, children }) { 725 if (type === "#comment") { 726 return `<!--$attributes["data-rich-text-comment"]}-->`; 727 } 728 let attributeString = ""; 729 for (const key in attributes) { 730 if (!(0, import_escape_html.isValidAttributeName)(key)) { 731 continue; 732 } 733 attributeString += ` $key}="${(0, import_escape_html.escapeAttribute)( 734 attributes[key] 735 )}"`; 736 } 737 if (object) { 738 return `<$type}$attributeString}>`; 739 } 740 return `<$type}$attributeString}>$createChildrenHTML( 741 children 742 )}</$type}>`; 743 } 744 function createChildrenHTML(children = []) { 745 return children.map((child) => { 746 if (child.html !== void 0) { 747 return child.html; 748 } 749 return child.text === void 0 ? createElementHTML(child) : (0, import_escape_html.escapeEditableHTML)(child.text); 750 }).join(""); 751 } 752 753 // packages/rich-text/build-module/get-text-content.js 754 function getTextContent({ text }) { 755 return text.replace(OBJECT_REPLACEMENT_CHARACTER, ""); 756 } 757 758 // packages/rich-text/build-module/create.js 759 function createEmptyValue() { 760 return { 761 formats: [], 762 replacements: [], 763 text: "" 764 }; 765 } 766 function toFormat({ tagName, attributes }) { 767 let formatType; 768 if (attributes && attributes.class) { 769 formatType = (0, import_data5.select)(store).getFormatTypeForClassName( 770 attributes.class 771 ); 772 if (formatType) { 773 attributes.class = ` $attributes.class} `.replace(` $formatType.className} `, " ").trim(); 774 if (!attributes.class) { 775 delete attributes.class; 776 } 777 } 778 } 779 if (!formatType) { 780 formatType = (0, import_data5.select)(store).getFormatTypeForBareElement(tagName); 781 } 782 if (!formatType) { 783 return attributes ? { type: tagName, attributes } : { type: tagName }; 784 } 785 if (formatType.__experimentalCreatePrepareEditableTree && !formatType.__experimentalCreateOnChangeEditableValue) { 786 return null; 787 } 788 if (!attributes) { 789 return { formatType, type: formatType.name, tagName }; 790 } 791 const registeredAttributes = {}; 792 const unregisteredAttributes = {}; 793 const _attributes = { ...attributes }; 794 for (const key in formatType.attributes) { 795 const name = formatType.attributes[key]; 796 registeredAttributes[key] = _attributes[name]; 797 delete _attributes[name]; 798 if (typeof registeredAttributes[key] === "undefined") { 799 delete registeredAttributes[key]; 800 } 801 } 802 for (const name in _attributes) { 803 unregisteredAttributes[name] = attributes[name]; 804 } 805 if (formatType.contentEditable === false) { 806 delete unregisteredAttributes.contenteditable; 807 } 808 return { 809 formatType, 810 type: formatType.name, 811 tagName, 812 attributes: registeredAttributes, 813 unregisteredAttributes 814 }; 815 } 816 var RichTextData = class _RichTextData { 817 #value; 818 static empty() { 819 return new _RichTextData(); 820 } 821 static fromPlainText(text) { 822 return new _RichTextData(create({ text })); 823 } 824 static fromHTMLString(html) { 825 return new _RichTextData(create({ html })); 826 } 827 /** 828 * Create a RichTextData instance from an HTML element. 829 * 830 * @param {HTMLElement} htmlElement The HTML element to create the instance from. 831 * @param {{preserveWhiteSpace?: boolean}} options Options. 832 * @return {RichTextData} The RichTextData instance. 833 */ 834 static fromHTMLElement(htmlElement, options = {}) { 835 const { preserveWhiteSpace = false } = options; 836 const element = preserveWhiteSpace ? htmlElement : collapseWhiteSpace(htmlElement); 837 const richTextData = new _RichTextData(create({ element })); 838 Object.defineProperty(richTextData, "originalHTML", { 839 value: htmlElement.innerHTML 840 }); 841 return richTextData; 842 } 843 constructor(init = createEmptyValue()) { 844 this.#value = init; 845 } 846 toPlainText() { 847 return getTextContent(this.#value); 848 } 849 // We could expose `toHTMLElement` at some point as well, but we'd only use 850 // it internally. 851 /** 852 * Convert the rich text value to an HTML string. 853 * 854 * @param {{preserveWhiteSpace?: boolean}} options Options. 855 * @return {string} The HTML string. 856 */ 857 toHTMLString({ preserveWhiteSpace } = {}) { 858 return this.originalHTML || toHTMLString({ value: this.#value, preserveWhiteSpace }); 859 } 860 valueOf() { 861 return this.toHTMLString(); 862 } 863 toString() { 864 return this.toHTMLString(); 865 } 866 toJSON() { 867 return this.toHTMLString(); 868 } 869 get length() { 870 return this.text.length; 871 } 872 get formats() { 873 return this.#value.formats; 874 } 875 get replacements() { 876 return this.#value.replacements; 877 } 878 get text() { 879 return this.#value.text; 880 } 881 }; 882 for (const name of Object.getOwnPropertyNames(String.prototype)) { 883 if (RichTextData.prototype.hasOwnProperty(name)) { 884 continue; 885 } 886 Object.defineProperty(RichTextData.prototype, name, { 887 value(...args) { 888 return this.toHTMLString()[name](...args); 889 } 890 }); 891 } 892 function create({ 893 element, 894 text, 895 html, 896 range, 897 __unstableIsEditableTree: isEditableTree 898 } = {}) { 899 if (html instanceof RichTextData) { 900 return { 901 text: html.text, 902 formats: html.formats, 903 replacements: html.replacements 904 }; 905 } 906 if (typeof text === "string" && text.length > 0) { 907 return { 908 formats: Array(text.length), 909 replacements: Array(text.length), 910 text 911 }; 912 } 913 if (typeof html === "string" && html.length > 0) { 914 element = createElement(document, html); 915 } 916 if (typeof element !== "object") { 917 return createEmptyValue(); 918 } 919 return createFromElement({ 920 element, 921 range, 922 isEditableTree 923 }); 924 } 925 function accumulateSelection(accumulator, node, range, value) { 926 if (!range) { 927 return; 928 } 929 const { parentNode } = node; 930 const { startContainer, startOffset, endContainer, endOffset } = range; 931 const currentLength = accumulator.text.length; 932 if (value.start !== void 0) { 933 accumulator.start = currentLength + value.start; 934 } else if (node === startContainer && node.nodeType === node.TEXT_NODE) { 935 accumulator.start = currentLength + startOffset; 936 } else if (parentNode === startContainer && node === startContainer.childNodes[startOffset]) { 937 accumulator.start = currentLength; 938 } else if (parentNode === startContainer && node === startContainer.childNodes[startOffset - 1]) { 939 accumulator.start = currentLength + value.text.length; 940 } else if (node === startContainer) { 941 accumulator.start = currentLength; 942 } 943 if (value.end !== void 0) { 944 accumulator.end = currentLength + value.end; 945 } else if (node === endContainer && node.nodeType === node.TEXT_NODE) { 946 accumulator.end = currentLength + endOffset; 947 } else if (parentNode === endContainer && node === endContainer.childNodes[endOffset - 1]) { 948 accumulator.end = currentLength + value.text.length; 949 } else if (parentNode === endContainer && node === endContainer.childNodes[endOffset]) { 950 accumulator.end = currentLength; 951 } else if (node === endContainer) { 952 accumulator.end = currentLength + endOffset; 953 } 954 } 955 function filterRange(node, range, filter) { 956 if (!range) { 957 return; 958 } 959 const { startContainer, endContainer } = range; 960 let { startOffset, endOffset } = range; 961 if (node === startContainer) { 962 startOffset = filter(node.nodeValue.slice(0, startOffset)).length; 963 } 964 if (node === endContainer) { 965 endOffset = filter(node.nodeValue.slice(0, endOffset)).length; 966 } 967 return { startContainer, startOffset, endContainer, endOffset }; 968 } 969 function collapseWhiteSpace(element, isRoot = true) { 970 const clone = element.cloneNode(true); 971 clone.normalize(); 972 Array.from(clone.childNodes).forEach((node, i2, nodes) => { 973 if (node.nodeType === node.TEXT_NODE) { 974 let newNodeValue = node.nodeValue; 975 if (/[\n\t\r\f]/.test(newNodeValue)) { 976 newNodeValue = newNodeValue.replace(/[\n\t\r\f]+/g, " "); 977 } 978 if (newNodeValue.indexOf(" ") !== -1) { 979 newNodeValue = newNodeValue.replace(/ {2,}/g, " "); 980 } 981 if (i2 === 0 && newNodeValue.startsWith(" ")) { 982 newNodeValue = newNodeValue.slice(1); 983 } else if (isRoot && i2 === nodes.length - 1 && newNodeValue.endsWith(" ")) { 984 newNodeValue = newNodeValue.slice(0, -1); 985 } 986 node.nodeValue = newNodeValue; 987 } else if (node.nodeType === node.ELEMENT_NODE) { 988 node.replaceWith(collapseWhiteSpace(node, false)); 989 } 990 }); 991 return clone; 992 } 993 var CARRIAGE_RETURN = "\r"; 994 function removeReservedCharacters(string) { 995 return string.replace( 996 new RegExp( 997 `[$ZWNBSP}$OBJECT_REPLACEMENT_CHARACTER}$CARRIAGE_RETURN}]`, 998 "gu" 999 ), 1000 "" 1001 ); 1002 } 1003 function createFromElement({ element, range, isEditableTree }) { 1004 const accumulator = createEmptyValue(); 1005 if (!element) { 1006 return accumulator; 1007 } 1008 if (!element.hasChildNodes()) { 1009 accumulateSelection(accumulator, element, range, createEmptyValue()); 1010 return accumulator; 1011 } 1012 const length = element.childNodes.length; 1013 for (let index = 0; index < length; index++) { 1014 const node = element.childNodes[index]; 1015 const tagName = node.nodeName.toLowerCase(); 1016 if (node.nodeType === node.TEXT_NODE) { 1017 const text = removeReservedCharacters(node.nodeValue); 1018 range = filterRange(node, range, removeReservedCharacters); 1019 accumulateSelection(accumulator, node, range, { text }); 1020 accumulator.formats.length += text.length; 1021 accumulator.replacements.length += text.length; 1022 accumulator.text += text; 1023 continue; 1024 } 1025 if (node.nodeType === node.COMMENT_NODE || node.nodeType === node.ELEMENT_NODE && node.tagName === "SPAN" && node.hasAttribute("data-rich-text-comment")) { 1026 const value2 = { 1027 formats: [,], 1028 replacements: [ 1029 { 1030 type: "#comment", 1031 attributes: { 1032 "data-rich-text-comment": node.nodeType === node.COMMENT_NODE ? node.nodeValue : node.getAttribute( 1033 "data-rich-text-comment" 1034 ) 1035 } 1036 } 1037 ], 1038 text: OBJECT_REPLACEMENT_CHARACTER 1039 }; 1040 accumulateSelection(accumulator, node, range, value2); 1041 mergePair(accumulator, value2); 1042 continue; 1043 } 1044 if (node.nodeType !== node.ELEMENT_NODE) { 1045 continue; 1046 } 1047 if (isEditableTree && // Ignore any line breaks that are not inserted by us. 1048 tagName === "br" && !node.getAttribute("data-rich-text-line-break")) { 1049 accumulateSelection(accumulator, node, range, createEmptyValue()); 1050 continue; 1051 } 1052 if (tagName === "script") { 1053 const value2 = { 1054 formats: [,], 1055 replacements: [ 1056 { 1057 type: tagName, 1058 attributes: { 1059 "data-rich-text-script": node.getAttribute("data-rich-text-script") || encodeURIComponent(node.innerHTML) 1060 } 1061 } 1062 ], 1063 text: OBJECT_REPLACEMENT_CHARACTER 1064 }; 1065 accumulateSelection(accumulator, node, range, value2); 1066 mergePair(accumulator, value2); 1067 continue; 1068 } 1069 if (tagName === "br") { 1070 accumulateSelection(accumulator, node, range, createEmptyValue()); 1071 mergePair(accumulator, create({ text: "\n" })); 1072 continue; 1073 } 1074 const format = toFormat({ 1075 tagName, 1076 attributes: getAttributes({ element: node }) 1077 }); 1078 if (format?.formatType?.contentEditable === false) { 1079 delete format.formatType; 1080 accumulateSelection(accumulator, node, range, createEmptyValue()); 1081 mergePair(accumulator, { 1082 formats: [,], 1083 replacements: [ 1084 { 1085 ...format, 1086 innerHTML: node.innerHTML 1087 } 1088 ], 1089 text: OBJECT_REPLACEMENT_CHARACTER 1090 }); 1091 continue; 1092 } 1093 if (format) { 1094 delete format.formatType; 1095 } 1096 const value = createFromElement({ 1097 element: node, 1098 range, 1099 isEditableTree 1100 }); 1101 accumulateSelection(accumulator, node, range, value); 1102 if (!format || node.getAttribute("data-rich-text-placeholder") || node.getAttribute("data-rich-text-bogus")) { 1103 mergePair(accumulator, value); 1104 } else if (value.text.length === 0) { 1105 if (format.attributes) { 1106 mergePair(accumulator, { 1107 formats: [,], 1108 replacements: [format], 1109 text: OBJECT_REPLACEMENT_CHARACTER 1110 }); 1111 } 1112 } else { 1113 let mergeFormats2 = function(formats) { 1114 if (mergeFormats2.formats === formats) { 1115 return mergeFormats2.newFormats; 1116 } 1117 const newFormats = formats ? [format, ...formats] : [format]; 1118 mergeFormats2.formats = formats; 1119 mergeFormats2.newFormats = newFormats; 1120 return newFormats; 1121 }; 1122 var mergeFormats = mergeFormats2; 1123 mergeFormats2.newFormats = [format]; 1124 mergePair(accumulator, { 1125 ...value, 1126 formats: Array.from(value.formats, mergeFormats2) 1127 }); 1128 } 1129 } 1130 return accumulator; 1131 } 1132 function getAttributes({ element }) { 1133 if (!element.hasAttributes()) { 1134 return; 1135 } 1136 const length = element.attributes.length; 1137 let accumulator; 1138 for (let i2 = 0; i2 < length; i2++) { 1139 const { name, value } = element.attributes[i2]; 1140 if (name.indexOf("data-rich-text-") === 0) { 1141 continue; 1142 } 1143 const safeName = /^on/i.test(name) ? "data-disable-rich-text-" + name : name; 1144 accumulator = accumulator || {}; 1145 accumulator[safeName] = value; 1146 } 1147 return accumulator; 1148 } 1149 1150 // packages/rich-text/build-module/concat.js 1151 function mergePair(a2, b2) { 1152 a2.formats = a2.formats.concat(b2.formats); 1153 a2.replacements = a2.replacements.concat(b2.replacements); 1154 a2.text += b2.text; 1155 return a2; 1156 } 1157 function concat(...values) { 1158 return normaliseFormats(values.reduce(mergePair, create())); 1159 } 1160 1161 // packages/rich-text/build-module/get-active-format.js 1162 function getActiveFormat(value, formatType) { 1163 return getActiveFormats(value).find( 1164 ({ type }) => type === formatType 1165 ); 1166 } 1167 1168 // packages/rich-text/build-module/get-active-object.js 1169 function getActiveObject({ start, end, replacements, text }) { 1170 if (start + 1 !== end || text[start] !== OBJECT_REPLACEMENT_CHARACTER) { 1171 return; 1172 } 1173 return replacements[start]; 1174 } 1175 1176 // packages/rich-text/build-module/is-collapsed.js 1177 function isCollapsed({ 1178 start, 1179 end 1180 }) { 1181 if (start === void 0 || end === void 0) { 1182 return; 1183 } 1184 return start === end; 1185 } 1186 1187 // packages/rich-text/build-module/is-empty.js 1188 function isEmpty({ text }) { 1189 return text.length === 0; 1190 } 1191 1192 // packages/rich-text/build-module/join.js 1193 function join(values, separator = "") { 1194 if (typeof separator === "string") { 1195 separator = create({ text: separator }); 1196 } 1197 return normaliseFormats( 1198 values.reduce((accumulator, { formats, replacements, text }) => ({ 1199 formats: accumulator.formats.concat(separator.formats, formats), 1200 replacements: accumulator.replacements.concat( 1201 separator.replacements, 1202 replacements 1203 ), 1204 text: accumulator.text + separator.text + text 1205 })) 1206 ); 1207 } 1208 1209 // packages/rich-text/build-module/register-format-type.js 1210 var import_data6 = __toESM(require_data()); 1211 function registerFormatType(name, settings) { 1212 settings = { 1213 name, 1214 ...settings 1215 }; 1216 if (typeof settings.name !== "string") { 1217 window.console.error("Format names must be strings."); 1218 return; 1219 } 1220 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(settings.name)) { 1221 window.console.error( 1222 "Format names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-format" 1223 ); 1224 return; 1225 } 1226 if ((0, import_data6.select)(store).getFormatType(settings.name)) { 1227 window.console.error( 1228 'Format "' + settings.name + '" is already registered.' 1229 ); 1230 return; 1231 } 1232 if (typeof settings.tagName !== "string" || settings.tagName === "") { 1233 window.console.error("Format tag names must be a string."); 1234 return; 1235 } 1236 if ((typeof settings.className !== "string" || settings.className === "") && settings.className !== null) { 1237 window.console.error( 1238 "Format class names must be a string, or null to handle bare elements." 1239 ); 1240 return; 1241 } 1242 if (!/^[_a-zA-Z]+[a-zA-Z0-9_-]*$/.test(settings.className)) { 1243 window.console.error( 1244 "A class name must begin with a letter, followed by any number of hyphens, underscores, letters, or numbers." 1245 ); 1246 return; 1247 } 1248 if (settings.className === null) { 1249 const formatTypeForBareElement = (0, import_data6.select)( 1250 store 1251 ).getFormatTypeForBareElement(settings.tagName); 1252 if (formatTypeForBareElement && formatTypeForBareElement.name !== "core/unknown") { 1253 window.console.error( 1254 `Format "$formatTypeForBareElement.name}" is already registered to handle bare tag name "$settings.tagName}".` 1255 ); 1256 return; 1257 } 1258 } else { 1259 const formatTypeForClassName = (0, import_data6.select)( 1260 store 1261 ).getFormatTypeForClassName(settings.className); 1262 if (formatTypeForClassName) { 1263 window.console.error( 1264 `Format "$formatTypeForClassName.name}" is already registered to handle class name "$settings.className}".` 1265 ); 1266 return; 1267 } 1268 } 1269 if (!("title" in settings) || settings.title === "") { 1270 window.console.error( 1271 'The format "' + settings.name + '" must have a title.' 1272 ); 1273 return; 1274 } 1275 if ("keywords" in settings && settings.keywords.length > 3) { 1276 window.console.error( 1277 'The format "' + settings.name + '" can have a maximum of 3 keywords.' 1278 ); 1279 return; 1280 } 1281 if (typeof settings.title !== "string") { 1282 window.console.error("Format titles must be strings."); 1283 return; 1284 } 1285 (0, import_data6.dispatch)(store).addFormatTypes(settings); 1286 return settings; 1287 } 1288 1289 // packages/rich-text/build-module/remove-format.js 1290 function removeFormat(value, formatType, startIndex = value.start, endIndex = value.end) { 1291 const { formats, activeFormats } = value; 1292 const newFormats = formats.slice(); 1293 if (startIndex === endIndex) { 1294 const format = newFormats[startIndex]?.find( 1295 ({ type }) => type === formatType 1296 ); 1297 if (format) { 1298 while (newFormats[startIndex]?.find( 1299 (newFormat) => newFormat === format 1300 )) { 1301 filterFormats(newFormats, startIndex, formatType); 1302 startIndex--; 1303 } 1304 endIndex++; 1305 while (newFormats[endIndex]?.find( 1306 (newFormat) => newFormat === format 1307 )) { 1308 filterFormats(newFormats, endIndex, formatType); 1309 endIndex++; 1310 } 1311 } 1312 } else { 1313 for (let i2 = startIndex; i2 < endIndex; i2++) { 1314 if (newFormats[i2]) { 1315 filterFormats(newFormats, i2, formatType); 1316 } 1317 } 1318 } 1319 return normaliseFormats({ 1320 ...value, 1321 formats: newFormats, 1322 activeFormats: activeFormats?.filter(({ type }) => type !== formatType) || [] 1323 }); 1324 } 1325 function filterFormats(formats, index, formatType) { 1326 const newFormats = formats[index].filter( 1327 ({ type }) => type !== formatType 1328 ); 1329 if (newFormats.length) { 1330 formats[index] = newFormats; 1331 } else { 1332 delete formats[index]; 1333 } 1334 } 1335 1336 // packages/rich-text/build-module/insert.js 1337 function insert(value, valueToInsert, startIndex = value.start, endIndex = value.end) { 1338 const { formats, replacements, text } = value; 1339 if (typeof valueToInsert === "string") { 1340 valueToInsert = create({ text: valueToInsert }); 1341 } 1342 const index = startIndex + valueToInsert.text.length; 1343 return normaliseFormats({ 1344 formats: formats.slice(0, startIndex).concat(valueToInsert.formats, formats.slice(endIndex)), 1345 replacements: replacements.slice(0, startIndex).concat( 1346 valueToInsert.replacements, 1347 replacements.slice(endIndex) 1348 ), 1349 text: text.slice(0, startIndex) + valueToInsert.text + text.slice(endIndex), 1350 start: index, 1351 end: index 1352 }); 1353 } 1354 1355 // packages/rich-text/build-module/remove.js 1356 function remove2(value, startIndex, endIndex) { 1357 return insert(value, create(), startIndex, endIndex); 1358 } 1359 1360 // packages/rich-text/build-module/replace.js 1361 function replace2({ formats, replacements, text, start, end }, pattern, replacement) { 1362 text = text.replace(pattern, (match, ...rest) => { 1363 const offset = rest[rest.length - 2]; 1364 let newText = replacement; 1365 let newFormats; 1366 let newReplacements; 1367 if (typeof newText === "function") { 1368 newText = replacement(match, ...rest); 1369 } 1370 if (typeof newText === "object") { 1371 newFormats = newText.formats; 1372 newReplacements = newText.replacements; 1373 newText = newText.text; 1374 } else { 1375 newFormats = Array(newText.length); 1376 newReplacements = Array(newText.length); 1377 if (formats[offset]) { 1378 newFormats = newFormats.fill(formats[offset]); 1379 } 1380 } 1381 formats = formats.slice(0, offset).concat(newFormats, formats.slice(offset + match.length)); 1382 replacements = replacements.slice(0, offset).concat( 1383 newReplacements, 1384 replacements.slice(offset + match.length) 1385 ); 1386 if (start) { 1387 start = end = offset + newText.length; 1388 } 1389 return newText; 1390 }); 1391 return normaliseFormats({ formats, replacements, text, start, end }); 1392 } 1393 1394 // packages/rich-text/build-module/insert-object.js 1395 function insertObject(value, formatToInsert, startIndex, endIndex) { 1396 const valueToInsert = { 1397 formats: [,], 1398 replacements: [formatToInsert], 1399 text: OBJECT_REPLACEMENT_CHARACTER 1400 }; 1401 return insert(value, valueToInsert, startIndex, endIndex); 1402 } 1403 1404 // packages/rich-text/build-module/slice.js 1405 function slice(value, startIndex = value.start, endIndex = value.end) { 1406 const { formats, replacements, text } = value; 1407 if (startIndex === void 0 || endIndex === void 0) { 1408 return { ...value }; 1409 } 1410 return { 1411 formats: formats.slice(startIndex, endIndex), 1412 replacements: replacements.slice(startIndex, endIndex), 1413 text: text.slice(startIndex, endIndex) 1414 }; 1415 } 1416 1417 // packages/rich-text/build-module/split.js 1418 function split({ formats, replacements, text, start, end }, string) { 1419 if (typeof string !== "string") { 1420 return splitAtSelection(...arguments); 1421 } 1422 let nextStart = 0; 1423 return text.split(string).map((substring) => { 1424 const startIndex = nextStart; 1425 const value = { 1426 formats: formats.slice(startIndex, startIndex + substring.length), 1427 replacements: replacements.slice( 1428 startIndex, 1429 startIndex + substring.length 1430 ), 1431 text: substring 1432 }; 1433 nextStart += string.length + substring.length; 1434 if (start !== void 0 && end !== void 0) { 1435 if (start >= startIndex && start < nextStart) { 1436 value.start = start - startIndex; 1437 } else if (start < startIndex && end > startIndex) { 1438 value.start = 0; 1439 } 1440 if (end >= startIndex && end < nextStart) { 1441 value.end = end - startIndex; 1442 } else if (start < nextStart && end > nextStart) { 1443 value.end = substring.length; 1444 } 1445 } 1446 return value; 1447 }); 1448 } 1449 function splitAtSelection({ formats, replacements, text, start, end }, startIndex = start, endIndex = end) { 1450 if (start === void 0 || end === void 0) { 1451 return; 1452 } 1453 const before = { 1454 formats: formats.slice(0, startIndex), 1455 replacements: replacements.slice(0, startIndex), 1456 text: text.slice(0, startIndex) 1457 }; 1458 const after = { 1459 formats: formats.slice(endIndex), 1460 replacements: replacements.slice(endIndex), 1461 text: text.slice(endIndex), 1462 start: 0, 1463 end: 0 1464 }; 1465 return [before, after]; 1466 } 1467 1468 // packages/rich-text/build-module/is-range-equal.js 1469 function isRangeEqual(a2, b2) { 1470 return a2 === b2 || a2 && b2 && a2.startContainer === b2.startContainer && a2.startOffset === b2.startOffset && a2.endContainer === b2.endContainer && a2.endOffset === b2.endOffset; 1471 } 1472 1473 // packages/rich-text/build-module/to-dom.js 1474 var MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML"; 1475 function createPathToNode(node, rootNode, path) { 1476 const parentNode = node.parentNode; 1477 let i2 = 0; 1478 while (node = node.previousSibling) { 1479 i2++; 1480 } 1481 path = [i2, ...path]; 1482 if (parentNode !== rootNode) { 1483 path = createPathToNode(parentNode, rootNode, path); 1484 } 1485 return path; 1486 } 1487 function getNodeByPath(node, path) { 1488 path = [...path]; 1489 while (node && path.length > 1) { 1490 node = node.childNodes[path.shift()]; 1491 } 1492 return { 1493 node, 1494 offset: path[0] 1495 }; 1496 } 1497 function append2(element, child) { 1498 if (child.html !== void 0) { 1499 return element.innerHTML += child.html; 1500 } 1501 if (typeof child === "string") { 1502 child = element.ownerDocument.createTextNode(child); 1503 } 1504 const { type, attributes } = child; 1505 if (type) { 1506 if (type === "#comment") { 1507 child = element.ownerDocument.createComment( 1508 attributes["data-rich-text-comment"] 1509 ); 1510 } else { 1511 const parentNamespace = element.namespaceURI; 1512 if (type === "math") { 1513 child = element.ownerDocument.createElementNS( 1514 MATHML_NAMESPACE, 1515 type 1516 ); 1517 } else if (parentNamespace === MATHML_NAMESPACE) { 1518 if (element.tagName === "MTEXT") { 1519 child = element.ownerDocument.createElement(type); 1520 } else { 1521 child = element.ownerDocument.createElementNS( 1522 MATHML_NAMESPACE, 1523 type 1524 ); 1525 } 1526 } else { 1527 child = element.ownerDocument.createElement(type); 1528 } 1529 for (const key in attributes) { 1530 child.setAttribute(key, attributes[key]); 1531 } 1532 } 1533 } 1534 return element.appendChild(child); 1535 } 1536 function appendText2(node, text) { 1537 node.appendData(text); 1538 } 1539 function getLastChild2({ lastChild }) { 1540 return lastChild; 1541 } 1542 function getParent2({ parentNode }) { 1543 return parentNode; 1544 } 1545 function isText2(node) { 1546 return node.nodeType === node.TEXT_NODE; 1547 } 1548 function getText2({ nodeValue }) { 1549 return nodeValue; 1550 } 1551 function remove3(node) { 1552 return node.parentNode.removeChild(node); 1553 } 1554 function toDom({ 1555 value, 1556 prepareEditableTree, 1557 isEditableTree = true, 1558 placeholder, 1559 doc = document 1560 }) { 1561 let startPath = []; 1562 let endPath = []; 1563 if (prepareEditableTree) { 1564 value = { 1565 ...value, 1566 formats: prepareEditableTree(value) 1567 }; 1568 } 1569 const createEmpty2 = () => createElement(doc, ""); 1570 const tree = toTree({ 1571 value, 1572 createEmpty: createEmpty2, 1573 append: append2, 1574 getLastChild: getLastChild2, 1575 getParent: getParent2, 1576 isText: isText2, 1577 getText: getText2, 1578 remove: remove3, 1579 appendText: appendText2, 1580 onStartIndex(body, pointer) { 1581 startPath = createPathToNode(pointer, body, [ 1582 pointer.nodeValue.length 1583 ]); 1584 }, 1585 onEndIndex(body, pointer) { 1586 endPath = createPathToNode(pointer, body, [ 1587 pointer.nodeValue.length 1588 ]); 1589 }, 1590 isEditableTree, 1591 placeholder 1592 }); 1593 return { 1594 body: tree, 1595 selection: { startPath, endPath } 1596 }; 1597 } 1598 function apply({ 1599 value, 1600 current, 1601 prepareEditableTree, 1602 __unstableDomOnly, 1603 placeholder 1604 }) { 1605 const { body, selection } = toDom({ 1606 value, 1607 prepareEditableTree, 1608 placeholder, 1609 doc: current.ownerDocument 1610 }); 1611 applyValue(body, current); 1612 if (value.start !== void 0 && !__unstableDomOnly) { 1613 applySelection(selection, current); 1614 } 1615 } 1616 function applyValue(future, current) { 1617 let i2 = 0; 1618 let futureChild; 1619 while (futureChild = future.firstChild) { 1620 const currentChild = current.childNodes[i2]; 1621 if (!currentChild) { 1622 current.appendChild(futureChild); 1623 } else if (!currentChild.isEqualNode(futureChild)) { 1624 if (currentChild.nodeName !== futureChild.nodeName || currentChild.nodeType === currentChild.TEXT_NODE && currentChild.data !== futureChild.data) { 1625 current.replaceChild(futureChild, currentChild); 1626 } else { 1627 const currentAttributes = currentChild.attributes; 1628 const futureAttributes = futureChild.attributes; 1629 if (currentAttributes) { 1630 let ii = currentAttributes.length; 1631 while (ii--) { 1632 const { name } = currentAttributes[ii]; 1633 if (!futureChild.getAttribute(name)) { 1634 currentChild.removeAttribute(name); 1635 } 1636 } 1637 } 1638 if (futureAttributes) { 1639 for (let ii = 0; ii < futureAttributes.length; ii++) { 1640 const { name, value } = futureAttributes[ii]; 1641 if (currentChild.getAttribute(name) !== value) { 1642 currentChild.setAttribute(name, value); 1643 } 1644 } 1645 } 1646 applyValue(futureChild, currentChild); 1647 future.removeChild(futureChild); 1648 } 1649 } else { 1650 future.removeChild(futureChild); 1651 } 1652 i2++; 1653 } 1654 while (current.childNodes[i2]) { 1655 current.removeChild(current.childNodes[i2]); 1656 } 1657 } 1658 function applySelection({ startPath, endPath }, current) { 1659 const { node: startContainer, offset: startOffset } = getNodeByPath( 1660 current, 1661 startPath 1662 ); 1663 const { node: endContainer, offset: endOffset } = getNodeByPath( 1664 current, 1665 endPath 1666 ); 1667 const { ownerDocument } = current; 1668 const { defaultView } = ownerDocument; 1669 const selection = defaultView.getSelection(); 1670 const range = ownerDocument.createRange(); 1671 range.setStart(startContainer, startOffset); 1672 range.setEnd(endContainer, endOffset); 1673 const { activeElement } = ownerDocument; 1674 if (selection.rangeCount > 0) { 1675 if (isRangeEqual(range, selection.getRangeAt(0))) { 1676 return; 1677 } 1678 selection.removeAllRanges(); 1679 } 1680 selection.addRange(range); 1681 if (activeElement !== ownerDocument.activeElement) { 1682 if (activeElement instanceof defaultView.HTMLElement) { 1683 activeElement.focus(); 1684 } 1685 } 1686 } 1687 1688 // packages/rich-text/build-module/toggle-format.js 1689 var import_a11y = __toESM(require_a11y()); 1690 var import_i18n = __toESM(require_i18n()); 1691 function toggleFormat(value, format) { 1692 if (getActiveFormat(value, format.type)) { 1693 if (format.title) { 1694 (0, import_a11y.speak)((0, import_i18n.sprintf)((0, import_i18n.__)("%s removed."), format.title), "assertive"); 1695 } 1696 return removeFormat(value, format.type); 1697 } 1698 if (format.title) { 1699 (0, import_a11y.speak)((0, import_i18n.sprintf)((0, import_i18n.__)("%s applied."), format.title), "assertive"); 1700 } 1701 return applyFormat(value, format); 1702 } 1703 1704 // packages/rich-text/build-module/unregister-format-type.js 1705 var import_data7 = __toESM(require_data()); 1706 function unregisterFormatType(name) { 1707 const oldFormat = (0, import_data7.select)(store).getFormatType(name); 1708 if (!oldFormat) { 1709 window.console.error(`Format $name} is not registered.`); 1710 return; 1711 } 1712 (0, import_data7.dispatch)(store).removeFormatTypes(name); 1713 return oldFormat; 1714 } 1715 1716 // packages/rich-text/build-module/component/use-anchor-ref.js 1717 var import_element = __toESM(require_element()); 1718 var import_deprecated = __toESM(require_deprecated()); 1719 function useAnchorRef({ ref, value, settings = {} }) { 1720 (0, import_deprecated.default)("`useAnchorRef` hook", { 1721 since: "6.1", 1722 alternative: "`useAnchor` hook" 1723 }); 1724 const { tagName, className, name } = settings; 1725 const activeFormat = name ? getActiveFormat(value, name) : void 0; 1726 return (0, import_element.useMemo)(() => { 1727 if (!ref.current) { 1728 return; 1729 } 1730 const { 1731 ownerDocument: { defaultView } 1732 } = ref.current; 1733 const selection = defaultView.getSelection(); 1734 if (!selection.rangeCount) { 1735 return; 1736 } 1737 const range = selection.getRangeAt(0); 1738 if (!activeFormat) { 1739 return range; 1740 } 1741 let element = range.startContainer; 1742 element = element.nextElementSibling || element; 1743 while (element.nodeType !== element.ELEMENT_NODE) { 1744 element = element.parentNode; 1745 } 1746 return element.closest( 1747 tagName + (className ? "." + className : "") 1748 ); 1749 }, [activeFormat, value.start, value.end, tagName, className]); 1750 } 1751 1752 // packages/rich-text/build-module/component/use-anchor.js 1753 var import_compose = __toESM(require_compose()); 1754 var import_element2 = __toESM(require_element()); 1755 var import_dom = __toESM(require_dom()); 1756 function getFormatElement(range, editableContentElement, tagName, className) { 1757 let element = range.startContainer; 1758 if (element.nodeType === element.TEXT_NODE && range.startOffset === element.length && element.nextSibling) { 1759 element = element.nextSibling; 1760 while (element.firstChild) { 1761 element = element.firstChild; 1762 } 1763 } 1764 if (element.nodeType !== element.ELEMENT_NODE) { 1765 element = element.parentElement; 1766 } 1767 if (!element) { 1768 return; 1769 } 1770 if (element === editableContentElement) { 1771 return; 1772 } 1773 if (!editableContentElement.contains(element)) { 1774 return; 1775 } 1776 const selector = tagName + (className ? "." + className : ""); 1777 while (element !== editableContentElement) { 1778 if (element.matches(selector)) { 1779 return element; 1780 } 1781 element = element.parentElement; 1782 } 1783 } 1784 function createVirtualAnchorElement(range, editableContentElement) { 1785 return { 1786 contextElement: editableContentElement, 1787 getBoundingClientRect() { 1788 return editableContentElement.contains(range.startContainer) ? (0, import_dom.getRectangleFromRange)(range) : editableContentElement.getBoundingClientRect(); 1789 } 1790 }; 1791 } 1792 function getAnchor(editableContentElement, tagName, className) { 1793 if (!editableContentElement) { 1794 return; 1795 } 1796 const { ownerDocument } = editableContentElement; 1797 const { defaultView } = ownerDocument; 1798 const selection = defaultView.getSelection(); 1799 if (!selection) { 1800 return; 1801 } 1802 if (!selection.rangeCount) { 1803 return; 1804 } 1805 const range = selection.getRangeAt(0); 1806 if (!range || !range.startContainer) { 1807 return; 1808 } 1809 const formatElement = getFormatElement( 1810 range, 1811 editableContentElement, 1812 tagName, 1813 className 1814 ); 1815 if (formatElement) { 1816 return formatElement; 1817 } 1818 return createVirtualAnchorElement(range, editableContentElement); 1819 } 1820 function useAnchor({ editableContentElement, settings = {} }) { 1821 const { tagName, className, isActive } = settings; 1822 const [anchor, setAnchor] = (0, import_element2.useState)( 1823 () => getAnchor(editableContentElement, tagName, className) 1824 ); 1825 const wasActive = (0, import_compose.usePrevious)(isActive); 1826 (0, import_element2.useLayoutEffect)(() => { 1827 if (!editableContentElement) { 1828 return; 1829 } 1830 function callback() { 1831 setAnchor( 1832 getAnchor(editableContentElement, tagName, className) 1833 ); 1834 } 1835 function attach() { 1836 ownerDocument.addEventListener("selectionchange", callback); 1837 } 1838 function detach() { 1839 ownerDocument.removeEventListener("selectionchange", callback); 1840 } 1841 const { ownerDocument } = editableContentElement; 1842 if (editableContentElement === ownerDocument.activeElement || // When a link is created, we need to attach the popover to the newly created anchor. 1843 !wasActive && isActive || // Sometimes we're _removing_ an active anchor, such as the inline color popover. 1844 // When we add the color, it switches from a virtual anchor to a `<mark>` element. 1845 // When we _remove_ the color, it switches from a `<mark>` element to a virtual anchor. 1846 wasActive && !isActive) { 1847 setAnchor( 1848 getAnchor(editableContentElement, tagName, className) 1849 ); 1850 attach(); 1851 } 1852 editableContentElement.addEventListener("focusin", attach); 1853 editableContentElement.addEventListener("focusout", detach); 1854 return () => { 1855 detach(); 1856 editableContentElement.removeEventListener("focusin", attach); 1857 editableContentElement.removeEventListener("focusout", detach); 1858 }; 1859 }, [editableContentElement, tagName, className, isActive, wasActive]); 1860 return anchor; 1861 } 1862 1863 // packages/rich-text/build-module/component/index.js 1864 var import_element6 = __toESM(require_element()); 1865 var import_compose3 = __toESM(require_compose()); 1866 var import_data8 = __toESM(require_data()); 1867 1868 // packages/rich-text/build-module/component/use-default-style.js 1869 var import_element3 = __toESM(require_element()); 1870 var whiteSpace = "pre-wrap"; 1871 var minWidth = "1px"; 1872 function useDefaultStyle() { 1873 return (0, import_element3.useCallback)((element) => { 1874 if (!element) { 1875 return; 1876 } 1877 element.style.whiteSpace = whiteSpace; 1878 element.style.minWidth = minWidth; 1879 }, []); 1880 } 1881 1882 // node_modules/colord/index.mjs 1883 var r = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) }; 1884 var t = function(r2) { 1885 return "string" == typeof r2 ? r2.length > 0 : "number" == typeof r2; 1886 }; 1887 var n = function(r2, t2, n2) { 1888 return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = Math.pow(10, t2)), Math.round(n2 * r2) / n2 + 0; 1889 }; 1890 var e = function(r2, t2, n2) { 1891 return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = 1), r2 > n2 ? n2 : r2 > t2 ? r2 : t2; 1892 }; 1893 var u = function(r2) { 1894 return (r2 = isFinite(r2) ? r2 % 360 : 0) > 0 ? r2 : r2 + 360; 1895 }; 1896 var a = function(r2) { 1897 return { r: e(r2.r, 0, 255), g: e(r2.g, 0, 255), b: e(r2.b, 0, 255), a: e(r2.a) }; 1898 }; 1899 var o = function(r2) { 1900 return { r: n(r2.r), g: n(r2.g), b: n(r2.b), a: n(r2.a, 3) }; 1901 }; 1902 var i = /^#([0-9a-f]{3,8})$/i; 1903 var s = function(r2) { 1904 var t2 = r2.toString(16); 1905 return t2.length < 2 ? "0" + t2 : t2; 1906 }; 1907 var h = function(r2) { 1908 var t2 = r2.r, n2 = r2.g, e2 = r2.b, u2 = r2.a, a2 = Math.max(t2, n2, e2), o2 = a2 - Math.min(t2, n2, e2), i2 = o2 ? a2 === t2 ? (n2 - e2) / o2 : a2 === n2 ? 2 + (e2 - t2) / o2 : 4 + (t2 - n2) / o2 : 0; 1909 return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o2 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 }; 1910 }; 1911 var b = function(r2) { 1912 var t2 = r2.h, n2 = r2.s, e2 = r2.v, u2 = r2.a; 1913 t2 = t2 / 360 * 6, n2 /= 100, e2 /= 100; 1914 var a2 = Math.floor(t2), o2 = e2 * (1 - n2), i2 = e2 * (1 - (t2 - a2) * n2), s2 = e2 * (1 - (1 - t2 + a2) * n2), h2 = a2 % 6; 1915 return { r: 255 * [e2, i2, o2, o2, s2, e2][h2], g: 255 * [s2, e2, e2, i2, o2, o2][h2], b: 255 * [o2, o2, s2, e2, e2, i2][h2], a: u2 }; 1916 }; 1917 var g = function(r2) { 1918 return { h: u(r2.h), s: e(r2.s, 0, 100), l: e(r2.l, 0, 100), a: e(r2.a) }; 1919 }; 1920 var d = function(r2) { 1921 return { h: n(r2.h), s: n(r2.s), l: n(r2.l), a: n(r2.a, 3) }; 1922 }; 1923 var f = function(r2) { 1924 return b((n2 = (t2 = r2).s, { h: t2.h, s: (n2 *= ((e2 = t2.l) < 50 ? e2 : 100 - e2) / 100) > 0 ? 2 * n2 / (e2 + n2) * 100 : 0, v: e2 + n2, a: t2.a })); 1925 var t2, n2, e2; 1926 }; 1927 var c = function(r2) { 1928 return { h: (t2 = h(r2)).h, s: (u2 = (200 - (n2 = t2.s)) * (e2 = t2.v) / 100) > 0 && u2 < 200 ? n2 * e2 / 100 / (u2 <= 100 ? u2 : 200 - u2) * 100 : 0, l: u2 / 2, a: t2.a }; 1929 var t2, n2, e2, u2; 1930 }; 1931 var l = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; 1932 var p = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; 1933 var v = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; 1934 var m = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; 1935 var y = { string: [[function(r2) { 1936 var t2 = i.exec(r2); 1937 return t2 ? (r2 = t2[1]).length <= 4 ? { r: parseInt(r2[0] + r2[0], 16), g: parseInt(r2[1] + r2[1], 16), b: parseInt(r2[2] + r2[2], 16), a: 4 === r2.length ? n(parseInt(r2[3] + r2[3], 16) / 255, 2) : 1 } : 6 === r2.length || 8 === r2.length ? { r: parseInt(r2.substr(0, 2), 16), g: parseInt(r2.substr(2, 2), 16), b: parseInt(r2.substr(4, 2), 16), a: 8 === r2.length ? n(parseInt(r2.substr(6, 2), 16) / 255, 2) : 1 } : null : null; 1938 }, "hex"], [function(r2) { 1939 var t2 = v.exec(r2) || m.exec(r2); 1940 return t2 ? t2[2] !== t2[4] || t2[4] !== t2[6] ? null : a({ r: Number(t2[1]) / (t2[2] ? 100 / 255 : 1), g: Number(t2[3]) / (t2[4] ? 100 / 255 : 1), b: Number(t2[5]) / (t2[6] ? 100 / 255 : 1), a: void 0 === t2[7] ? 1 : Number(t2[7]) / (t2[8] ? 100 : 1) }) : null; 1941 }, "rgb"], [function(t2) { 1942 var n2 = l.exec(t2) || p.exec(t2); 1943 if (!n2) return null; 1944 var e2, u2, a2 = g({ h: (e2 = n2[1], u2 = n2[2], void 0 === u2 && (u2 = "deg"), Number(e2) * (r[u2] || 1)), s: Number(n2[3]), l: Number(n2[4]), a: void 0 === n2[5] ? 1 : Number(n2[5]) / (n2[6] ? 100 : 1) }); 1945 return f(a2); 1946 }, "hsl"]], object: [[function(r2) { 1947 var n2 = r2.r, e2 = r2.g, u2 = r2.b, o2 = r2.a, i2 = void 0 === o2 ? 1 : o2; 1948 return t(n2) && t(e2) && t(u2) ? a({ r: Number(n2), g: Number(e2), b: Number(u2), a: Number(i2) }) : null; 1949 }, "rgb"], [function(r2) { 1950 var n2 = r2.h, e2 = r2.s, u2 = r2.l, a2 = r2.a, o2 = void 0 === a2 ? 1 : a2; 1951 if (!t(n2) || !t(e2) || !t(u2)) return null; 1952 var i2 = g({ h: Number(n2), s: Number(e2), l: Number(u2), a: Number(o2) }); 1953 return f(i2); 1954 }, "hsl"], [function(r2) { 1955 var n2 = r2.h, a2 = r2.s, o2 = r2.v, i2 = r2.a, s2 = void 0 === i2 ? 1 : i2; 1956 if (!t(n2) || !t(a2) || !t(o2)) return null; 1957 var h2 = (function(r3) { 1958 return { h: u(r3.h), s: e(r3.s, 0, 100), v: e(r3.v, 0, 100), a: e(r3.a) }; 1959 })({ h: Number(n2), s: Number(a2), v: Number(o2), a: Number(s2) }); 1960 return b(h2); 1961 }, "hsv"]] }; 1962 var N = function(r2, t2) { 1963 for (var n2 = 0; n2 < t2.length; n2++) { 1964 var e2 = t2[n2][0](r2); 1965 if (e2) return [e2, t2[n2][1]]; 1966 } 1967 return [null, void 0]; 1968 }; 1969 var x = function(r2) { 1970 return "string" == typeof r2 ? N(r2.trim(), y.string) : "object" == typeof r2 && null !== r2 ? N(r2, y.object) : [null, void 0]; 1971 }; 1972 var M = function(r2, t2) { 1973 var n2 = c(r2); 1974 return { h: n2.h, s: e(n2.s + 100 * t2, 0, 100), l: n2.l, a: n2.a }; 1975 }; 1976 var H = function(r2) { 1977 return (299 * r2.r + 587 * r2.g + 114 * r2.b) / 1e3 / 255; 1978 }; 1979 var $ = function(r2, t2) { 1980 var n2 = c(r2); 1981 return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t2, 0, 100), a: n2.a }; 1982 }; 1983 var j = (function() { 1984 function r2(r3) { 1985 this.parsed = x(r3)[0], this.rgba = this.parsed || { r: 0, g: 0, b: 0, a: 1 }; 1986 } 1987 return r2.prototype.isValid = function() { 1988 return null !== this.parsed; 1989 }, r2.prototype.brightness = function() { 1990 return n(H(this.rgba), 2); 1991 }, r2.prototype.isDark = function() { 1992 return H(this.rgba) < 0.5; 1993 }, r2.prototype.isLight = function() { 1994 return H(this.rgba) >= 0.5; 1995 }, r2.prototype.toHex = function() { 1996 return r3 = o(this.rgba), t2 = r3.r, e2 = r3.g, u2 = r3.b, i2 = (a2 = r3.a) < 1 ? s(n(255 * a2)) : "", "#" + s(t2) + s(e2) + s(u2) + i2; 1997 var r3, t2, e2, u2, a2, i2; 1998 }, r2.prototype.toRgb = function() { 1999 return o(this.rgba); 2000 }, r2.prototype.toRgbString = function() { 2001 return r3 = o(this.rgba), t2 = r3.r, n2 = r3.g, e2 = r3.b, (u2 = r3.a) < 1 ? "rgba(" + t2 + ", " + n2 + ", " + e2 + ", " + u2 + ")" : "rgb(" + t2 + ", " + n2 + ", " + e2 + ")"; 2002 var r3, t2, n2, e2, u2; 2003 }, r2.prototype.toHsl = function() { 2004 return d(c(this.rgba)); 2005 }, r2.prototype.toHslString = function() { 2006 return r3 = d(c(this.rgba)), t2 = r3.h, n2 = r3.s, e2 = r3.l, (u2 = r3.a) < 1 ? "hsla(" + t2 + ", " + n2 + "%, " + e2 + "%, " + u2 + ")" : "hsl(" + t2 + ", " + n2 + "%, " + e2 + "%)"; 2007 var r3, t2, n2, e2, u2; 2008 }, r2.prototype.toHsv = function() { 2009 return r3 = h(this.rgba), { h: n(r3.h), s: n(r3.s), v: n(r3.v), a: n(r3.a, 3) }; 2010 var r3; 2011 }, r2.prototype.invert = function() { 2012 return w({ r: 255 - (r3 = this.rgba).r, g: 255 - r3.g, b: 255 - r3.b, a: r3.a }); 2013 var r3; 2014 }, r2.prototype.saturate = function(r3) { 2015 return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, r3)); 2016 }, r2.prototype.desaturate = function(r3) { 2017 return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, -r3)); 2018 }, r2.prototype.grayscale = function() { 2019 return w(M(this.rgba, -1)); 2020 }, r2.prototype.lighten = function(r3) { 2021 return void 0 === r3 && (r3 = 0.1), w($(this.rgba, r3)); 2022 }, r2.prototype.darken = function(r3) { 2023 return void 0 === r3 && (r3 = 0.1), w($(this.rgba, -r3)); 2024 }, r2.prototype.rotate = function(r3) { 2025 return void 0 === r3 && (r3 = 15), this.hue(this.hue() + r3); 2026 }, r2.prototype.alpha = function(r3) { 2027 return "number" == typeof r3 ? w({ r: (t2 = this.rgba).r, g: t2.g, b: t2.b, a: r3 }) : n(this.rgba.a, 3); 2028 var t2; 2029 }, r2.prototype.hue = function(r3) { 2030 var t2 = c(this.rgba); 2031 return "number" == typeof r3 ? w({ h: r3, s: t2.s, l: t2.l, a: t2.a }) : n(t2.h); 2032 }, r2.prototype.isEqual = function(r3) { 2033 return this.toHex() === w(r3).toHex(); 2034 }, r2; 2035 })(); 2036 var w = function(r2) { 2037 return r2 instanceof j ? r2 : new j(r2); 2038 }; 2039 2040 // packages/rich-text/build-module/component/use-boundary-style.js 2041 var import_element4 = __toESM(require_element()); 2042 function useBoundaryStyle({ record }) { 2043 const ref = (0, import_element4.useRef)(); 2044 const { activeFormats = [], replacements, start } = record.current; 2045 const activeReplacement = replacements[start]; 2046 (0, import_element4.useEffect)(() => { 2047 if ((!activeFormats || !activeFormats.length) && !activeReplacement) { 2048 return; 2049 } 2050 const boundarySelector = "*[data-rich-text-format-boundary]"; 2051 const element = ref.current.querySelector(boundarySelector); 2052 if (!element) { 2053 return; 2054 } 2055 const { ownerDocument } = element; 2056 const { defaultView } = ownerDocument; 2057 const computedStyle = defaultView.getComputedStyle(element); 2058 const newColor = w(computedStyle.color).alpha(0.2).toRgbString(); 2059 const selector = `.rich-text:focus $boundarySelector}`; 2060 const rule = `background-color: $newColor}`; 2061 const style = `$selector} {$rule}}`; 2062 const globalStyleId = "rich-text-boundary-style"; 2063 let globalStyle = ownerDocument.getElementById(globalStyleId); 2064 if (!globalStyle) { 2065 globalStyle = ownerDocument.createElement("style"); 2066 globalStyle.id = globalStyleId; 2067 ownerDocument.head.appendChild(globalStyle); 2068 } 2069 if (globalStyle.innerHTML !== style) { 2070 globalStyle.innerHTML = style; 2071 } 2072 }, [activeFormats, activeReplacement]); 2073 return ref; 2074 } 2075 2076 // packages/rich-text/build-module/component/event-listeners/index.js 2077 var import_element5 = __toESM(require_element()); 2078 var import_compose2 = __toESM(require_compose()); 2079 2080 // packages/rich-text/build-module/component/event-listeners/copy-handler.js 2081 var copy_handler_default = (props) => (element) => { 2082 function onCopy(event) { 2083 const { record } = props.current; 2084 const { ownerDocument } = element; 2085 if (isCollapsed(record.current) || !element.contains(ownerDocument.activeElement)) { 2086 return; 2087 } 2088 const selectedRecord = slice(record.current); 2089 const plainText = getTextContent(selectedRecord); 2090 const html = toHTMLString({ value: selectedRecord }); 2091 event.clipboardData.setData("text/plain", plainText); 2092 event.clipboardData.setData("text/html", html); 2093 event.clipboardData.setData("rich-text", "true"); 2094 event.preventDefault(); 2095 if (event.type === "cut") { 2096 ownerDocument.execCommand("delete"); 2097 } 2098 } 2099 const { defaultView } = element.ownerDocument; 2100 defaultView.addEventListener("copy", onCopy); 2101 defaultView.addEventListener("cut", onCopy); 2102 return () => { 2103 defaultView.removeEventListener("copy", onCopy); 2104 defaultView.removeEventListener("cut", onCopy); 2105 }; 2106 }; 2107 2108 // packages/rich-text/build-module/component/event-listeners/select-object.js 2109 var select_object_default = () => (element) => { 2110 function onClick(event) { 2111 const { target } = event; 2112 if (target === element || target.textContent && target.isContentEditable) { 2113 return; 2114 } 2115 const { ownerDocument } = target; 2116 const { defaultView } = ownerDocument; 2117 const selection = defaultView.getSelection(); 2118 if (selection.containsNode(target)) { 2119 return; 2120 } 2121 const range = ownerDocument.createRange(); 2122 const nodeToSelect = target.isContentEditable ? target : target.closest("[contenteditable]"); 2123 range.selectNode(nodeToSelect); 2124 selection.removeAllRanges(); 2125 selection.addRange(range); 2126 event.preventDefault(); 2127 } 2128 function onFocusIn(event) { 2129 if (event.relatedTarget && !element.contains(event.relatedTarget) && event.relatedTarget.tagName === "A") { 2130 onClick(event); 2131 } 2132 } 2133 element.addEventListener("click", onClick); 2134 element.addEventListener("focusin", onFocusIn); 2135 return () => { 2136 element.removeEventListener("click", onClick); 2137 element.removeEventListener("focusin", onFocusIn); 2138 }; 2139 }; 2140 2141 // packages/rich-text/build-module/component/event-listeners/format-boundaries.js 2142 var import_keycodes = __toESM(require_keycodes()); 2143 var EMPTY_ACTIVE_FORMATS = []; 2144 var format_boundaries_default = (props) => (element) => { 2145 function onKeyDown(event) { 2146 const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; 2147 if ( 2148 // Only override left and right keys without modifiers pressed. 2149 shiftKey || altKey || metaKey || ctrlKey || keyCode !== import_keycodes.LEFT && keyCode !== import_keycodes.RIGHT 2150 ) { 2151 return; 2152 } 2153 const { record, applyRecord, forceRender } = props.current; 2154 const { 2155 text, 2156 formats, 2157 start, 2158 end, 2159 activeFormats: currentActiveFormats = [] 2160 } = record.current; 2161 const collapsed = isCollapsed(record.current); 2162 const { ownerDocument } = element; 2163 const { defaultView } = ownerDocument; 2164 const { direction } = defaultView.getComputedStyle(element); 2165 const reverseKey = direction === "rtl" ? import_keycodes.RIGHT : import_keycodes.LEFT; 2166 const isReverse = event.keyCode === reverseKey; 2167 if (collapsed && currentActiveFormats.length === 0) { 2168 if (start === 0 && isReverse) { 2169 return; 2170 } 2171 if (end === text.length && !isReverse) { 2172 return; 2173 } 2174 } 2175 if (!collapsed) { 2176 return; 2177 } 2178 const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS; 2179 const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS; 2180 const destination = isReverse ? formatsBefore : formatsAfter; 2181 const isIncreasing = currentActiveFormats.every( 2182 (format, index) => format === destination[index] 2183 ); 2184 let newActiveFormatsLength = currentActiveFormats.length; 2185 if (!isIncreasing) { 2186 newActiveFormatsLength--; 2187 } else if (newActiveFormatsLength < destination.length) { 2188 newActiveFormatsLength++; 2189 } 2190 if (newActiveFormatsLength === currentActiveFormats.length) { 2191 record.current._newActiveFormats = destination; 2192 return; 2193 } 2194 event.preventDefault(); 2195 const origin = isReverse ? formatsAfter : formatsBefore; 2196 const source = isIncreasing ? destination : origin; 2197 const newActiveFormats = source.slice(0, newActiveFormatsLength); 2198 const newValue = { 2199 ...record.current, 2200 activeFormats: newActiveFormats 2201 }; 2202 record.current = newValue; 2203 applyRecord(newValue); 2204 forceRender(); 2205 } 2206 element.addEventListener("keydown", onKeyDown); 2207 return () => { 2208 element.removeEventListener("keydown", onKeyDown); 2209 }; 2210 }; 2211 2212 // packages/rich-text/build-module/component/event-listeners/delete.js 2213 var import_keycodes2 = __toESM(require_keycodes()); 2214 var delete_default = (props) => (element) => { 2215 function onKeyDown(event) { 2216 const { keyCode } = event; 2217 const { createRecord, handleChange } = props.current; 2218 if (event.defaultPrevented) { 2219 return; 2220 } 2221 if (keyCode !== import_keycodes2.DELETE && keyCode !== import_keycodes2.BACKSPACE) { 2222 return; 2223 } 2224 const currentValue = createRecord(); 2225 const { start, end, text } = currentValue; 2226 if (start === 0 && end !== 0 && end === text.length) { 2227 handleChange(remove2(currentValue)); 2228 event.preventDefault(); 2229 } 2230 } 2231 element.addEventListener("keydown", onKeyDown); 2232 return () => { 2233 element.removeEventListener("keydown", onKeyDown); 2234 }; 2235 }; 2236 2237 // packages/rich-text/build-module/update-formats.js 2238 function updateFormats({ value, start, end, formats }) { 2239 const min = Math.min(start, end); 2240 const max = Math.max(start, end); 2241 const formatsBefore = value.formats[min - 1] || []; 2242 const formatsAfter = value.formats[max] || []; 2243 value.activeFormats = formats.map((format, index) => { 2244 if (formatsBefore[index]) { 2245 if (isFormatEqual(format, formatsBefore[index])) { 2246 return formatsBefore[index]; 2247 } 2248 } else if (formatsAfter[index]) { 2249 if (isFormatEqual(format, formatsAfter[index])) { 2250 return formatsAfter[index]; 2251 } 2252 } 2253 return format; 2254 }); 2255 while (--end >= start) { 2256 if (value.activeFormats.length > 0) { 2257 value.formats[end] = value.activeFormats; 2258 } else { 2259 delete value.formats[end]; 2260 } 2261 } 2262 return value; 2263 } 2264 2265 // packages/rich-text/build-module/component/event-listeners/input-and-selection.js 2266 var INSERTION_INPUT_TYPES_TO_IGNORE = /* @__PURE__ */ new Set([ 2267 "insertParagraph", 2268 "insertOrderedList", 2269 "insertUnorderedList", 2270 "insertHorizontalRule", 2271 "insertLink" 2272 ]); 2273 var EMPTY_ACTIVE_FORMATS2 = []; 2274 var PLACEHOLDER_ATTR_NAME = "data-rich-text-placeholder"; 2275 function fixPlaceholderSelection(defaultView) { 2276 const selection = defaultView.getSelection(); 2277 const { anchorNode, anchorOffset } = selection; 2278 if (anchorNode.nodeType !== anchorNode.ELEMENT_NODE) { 2279 return; 2280 } 2281 const targetNode = anchorNode.childNodes[anchorOffset]; 2282 if (!targetNode || targetNode.nodeType !== targetNode.ELEMENT_NODE || !targetNode.hasAttribute(PLACEHOLDER_ATTR_NAME)) { 2283 return; 2284 } 2285 selection.collapseToStart(); 2286 } 2287 var input_and_selection_default = (props) => (element) => { 2288 const { ownerDocument } = element; 2289 const { defaultView } = ownerDocument; 2290 let isComposing = false; 2291 function onInput(event) { 2292 if (isComposing) { 2293 return; 2294 } 2295 let inputType; 2296 if (event) { 2297 inputType = event.inputType; 2298 } 2299 const { record, applyRecord, createRecord, handleChange } = props.current; 2300 if (inputType && (inputType.indexOf("format") === 0 || INSERTION_INPUT_TYPES_TO_IGNORE.has(inputType))) { 2301 applyRecord(record.current); 2302 return; 2303 } 2304 const currentValue = createRecord(); 2305 const { start, activeFormats: oldActiveFormats = [] } = record.current; 2306 const change = updateFormats({ 2307 value: currentValue, 2308 start, 2309 end: currentValue.start, 2310 formats: oldActiveFormats 2311 }); 2312 handleChange(change); 2313 } 2314 function handleSelectionChange() { 2315 const { record, applyRecord, createRecord, onSelectionChange } = props.current; 2316 if (element.contentEditable !== "true") { 2317 return; 2318 } 2319 if (ownerDocument.activeElement !== element) { 2320 ownerDocument.removeEventListener( 2321 "selectionchange", 2322 handleSelectionChange 2323 ); 2324 return; 2325 } 2326 if (isComposing) { 2327 return; 2328 } 2329 const { start, end, text } = createRecord(); 2330 const oldRecord = record.current; 2331 if (text !== oldRecord.text) { 2332 onInput(); 2333 return; 2334 } 2335 if (start === oldRecord.start && end === oldRecord.end) { 2336 if (oldRecord.text.length === 0 && start === 0) { 2337 fixPlaceholderSelection(defaultView); 2338 } 2339 return; 2340 } 2341 const newValue = { 2342 ...oldRecord, 2343 start, 2344 end, 2345 // _newActiveFormats may be set on arrow key navigation to control 2346 // the right boundary position. If undefined, getActiveFormats will 2347 // give the active formats according to the browser. 2348 activeFormats: oldRecord._newActiveFormats, 2349 _newActiveFormats: void 0 2350 }; 2351 const newActiveFormats = getActiveFormats( 2352 newValue, 2353 EMPTY_ACTIVE_FORMATS2 2354 ); 2355 newValue.activeFormats = newActiveFormats; 2356 record.current = newValue; 2357 applyRecord(newValue, { domOnly: true }); 2358 onSelectionChange(start, end); 2359 } 2360 function onCompositionStart() { 2361 isComposing = true; 2362 ownerDocument.removeEventListener( 2363 "selectionchange", 2364 handleSelectionChange 2365 ); 2366 element.querySelector(`[$PLACEHOLDER_ATTR_NAME}]`)?.remove(); 2367 } 2368 function onCompositionEnd() { 2369 isComposing = false; 2370 onInput({ inputType: "insertText" }); 2371 ownerDocument.addEventListener( 2372 "selectionchange", 2373 handleSelectionChange 2374 ); 2375 } 2376 function onFocus() { 2377 const { record, isSelected, onSelectionChange, applyRecord } = props.current; 2378 if (element.parentElement.closest('[contenteditable="true"]')) { 2379 return; 2380 } 2381 if (!isSelected) { 2382 const index = void 0; 2383 record.current = { 2384 ...record.current, 2385 start: index, 2386 end: index, 2387 activeFormats: EMPTY_ACTIVE_FORMATS2 2388 }; 2389 } else { 2390 applyRecord(record.current, { domOnly: true }); 2391 } 2392 onSelectionChange(record.current.start, record.current.end); 2393 window.queueMicrotask(handleSelectionChange); 2394 ownerDocument.addEventListener( 2395 "selectionchange", 2396 handleSelectionChange 2397 ); 2398 } 2399 element.addEventListener("input", onInput); 2400 element.addEventListener("compositionstart", onCompositionStart); 2401 element.addEventListener("compositionend", onCompositionEnd); 2402 element.addEventListener("focus", onFocus); 2403 return () => { 2404 element.removeEventListener("input", onInput); 2405 element.removeEventListener("compositionstart", onCompositionStart); 2406 element.removeEventListener("compositionend", onCompositionEnd); 2407 element.removeEventListener("focus", onFocus); 2408 }; 2409 }; 2410 2411 // packages/rich-text/build-module/component/event-listeners/selection-change-compat.js 2412 var selection_change_compat_default = () => (element) => { 2413 const { ownerDocument } = element; 2414 const { defaultView } = ownerDocument; 2415 const selection = defaultView?.getSelection(); 2416 let range; 2417 function getRange() { 2418 return selection.rangeCount ? selection.getRangeAt(0) : null; 2419 } 2420 function onDown(event) { 2421 const type = event.type === "keydown" ? "keyup" : "pointerup"; 2422 function onCancel() { 2423 ownerDocument.removeEventListener(type, onUp); 2424 ownerDocument.removeEventListener("selectionchange", onCancel); 2425 ownerDocument.removeEventListener("input", onCancel); 2426 } 2427 function onUp() { 2428 onCancel(); 2429 if (isRangeEqual(range, getRange())) { 2430 return; 2431 } 2432 ownerDocument.dispatchEvent(new Event("selectionchange")); 2433 } 2434 ownerDocument.addEventListener(type, onUp); 2435 ownerDocument.addEventListener("selectionchange", onCancel); 2436 ownerDocument.addEventListener("input", onCancel); 2437 range = getRange(); 2438 } 2439 element.addEventListener("pointerdown", onDown); 2440 element.addEventListener("keydown", onDown); 2441 return () => { 2442 element.removeEventListener("pointerdown", onDown); 2443 element.removeEventListener("keydown", onDown); 2444 }; 2445 }; 2446 2447 // packages/rich-text/build-module/component/event-listeners/prevent-focus-capture.js 2448 function preventFocusCapture() { 2449 return (element) => { 2450 const { ownerDocument } = element; 2451 const { defaultView } = ownerDocument; 2452 let value = null; 2453 function onPointerDown(event) { 2454 if (event.defaultPrevented) { 2455 return; 2456 } 2457 if (event.target === element) { 2458 return; 2459 } 2460 if (!event.target.contains(element)) { 2461 return; 2462 } 2463 value = element.getAttribute("contenteditable"); 2464 element.setAttribute("contenteditable", "false"); 2465 defaultView.getSelection().removeAllRanges(); 2466 } 2467 function onPointerUp() { 2468 if (value !== null) { 2469 element.setAttribute("contenteditable", value); 2470 value = null; 2471 } 2472 } 2473 defaultView.addEventListener("pointerdown", onPointerDown); 2474 defaultView.addEventListener("pointerup", onPointerUp); 2475 return () => { 2476 defaultView.removeEventListener("pointerdown", onPointerDown); 2477 defaultView.removeEventListener("pointerup", onPointerUp); 2478 }; 2479 }; 2480 } 2481 2482 // packages/rich-text/build-module/component/event-listeners/index.js 2483 var allEventListeners = [ 2484 copy_handler_default, 2485 select_object_default, 2486 format_boundaries_default, 2487 delete_default, 2488 input_and_selection_default, 2489 selection_change_compat_default, 2490 preventFocusCapture 2491 ]; 2492 function useEventListeners(props) { 2493 const propsRef = (0, import_element5.useRef)(props); 2494 (0, import_element5.useInsertionEffect)(() => { 2495 propsRef.current = props; 2496 }); 2497 const refEffects = (0, import_element5.useMemo)( 2498 () => allEventListeners.map((refEffect) => refEffect(propsRef)), 2499 [propsRef] 2500 ); 2501 return (0, import_compose2.useRefEffect)( 2502 (element) => { 2503 const cleanups = refEffects.map((effect) => effect(element)); 2504 return () => { 2505 cleanups.forEach((cleanup) => cleanup()); 2506 }; 2507 }, 2508 [refEffects] 2509 ); 2510 } 2511 2512 // packages/rich-text/build-module/component/index.js 2513 function useRichText({ 2514 value = "", 2515 selectionStart, 2516 selectionEnd, 2517 placeholder, 2518 onSelectionChange, 2519 preserveWhiteSpace, 2520 onChange, 2521 __unstableDisableFormats: disableFormats, 2522 __unstableIsSelected: isSelected, 2523 __unstableDependencies = [], 2524 __unstableAfterParse, 2525 __unstableBeforeSerialize, 2526 __unstableAddInvisibleFormats 2527 }) { 2528 const registry = (0, import_data8.useRegistry)(); 2529 const [, forceRender] = (0, import_element6.useReducer)(() => ({})); 2530 const ref = (0, import_element6.useRef)(); 2531 function createRecord() { 2532 const { 2533 ownerDocument: { defaultView } 2534 } = ref.current; 2535 const selection = defaultView.getSelection(); 2536 const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null; 2537 return create({ 2538 element: ref.current, 2539 range, 2540 __unstableIsEditableTree: true 2541 }); 2542 } 2543 function applyRecord(newRecord, { domOnly } = {}) { 2544 apply({ 2545 value: newRecord, 2546 current: ref.current, 2547 prepareEditableTree: __unstableAddInvisibleFormats, 2548 __unstableDomOnly: domOnly, 2549 placeholder 2550 }); 2551 } 2552 const _valueRef = (0, import_element6.useRef)(value); 2553 const recordRef = (0, import_element6.useRef)(); 2554 function setRecordFromProps() { 2555 const activeFormats = recordRef.current?.activeFormats; 2556 _valueRef.current = value; 2557 recordRef.current = value; 2558 if (!(value instanceof RichTextData)) { 2559 recordRef.current = value ? RichTextData.fromHTMLString(value, { preserveWhiteSpace }) : RichTextData.empty(); 2560 } 2561 recordRef.current = { 2562 text: recordRef.current.text, 2563 formats: recordRef.current.formats, 2564 replacements: recordRef.current.replacements, 2565 activeFormats 2566 }; 2567 if (disableFormats) { 2568 recordRef.current.formats = Array(value.length); 2569 recordRef.current.replacements = Array(value.length); 2570 } 2571 if (__unstableAfterParse) { 2572 recordRef.current.formats = __unstableAfterParse( 2573 recordRef.current 2574 ); 2575 } 2576 recordRef.current.start = selectionStart; 2577 recordRef.current.end = selectionEnd; 2578 } 2579 const hadSelectionUpdateRef = (0, import_element6.useRef)(false); 2580 if (!recordRef.current) { 2581 hadSelectionUpdateRef.current = isSelected; 2582 setRecordFromProps(); 2583 } else if (selectionStart !== recordRef.current.start || selectionEnd !== recordRef.current.end) { 2584 hadSelectionUpdateRef.current = isSelected; 2585 recordRef.current = { 2586 ...recordRef.current, 2587 start: selectionStart, 2588 end: selectionEnd, 2589 activeFormats: void 0 2590 }; 2591 } 2592 function handleChange(newRecord) { 2593 recordRef.current = newRecord; 2594 applyRecord(newRecord); 2595 if (disableFormats) { 2596 _valueRef.current = newRecord.text; 2597 } else { 2598 const newFormats = __unstableBeforeSerialize ? __unstableBeforeSerialize(newRecord) : newRecord.formats; 2599 newRecord = { ...newRecord, formats: newFormats }; 2600 if (typeof value === "string") { 2601 _valueRef.current = toHTMLString({ 2602 value: newRecord, 2603 preserveWhiteSpace 2604 }); 2605 } else { 2606 _valueRef.current = new RichTextData(newRecord); 2607 } 2608 } 2609 const { start, end, formats, text } = recordRef.current; 2610 registry.batch(() => { 2611 onSelectionChange(start, end); 2612 onChange(_valueRef.current, { 2613 __unstableFormats: formats, 2614 __unstableText: text 2615 }); 2616 }); 2617 forceRender(); 2618 } 2619 function applyFromProps() { 2620 const previousValue = _valueRef.current; 2621 setRecordFromProps(); 2622 const contentLengthChanged = previousValue && typeof previousValue === "string" && typeof value === "string" && previousValue.length !== value.length; 2623 const hasFocus = ref.current?.contains( 2624 ref.current.ownerDocument.activeElement 2625 ); 2626 const skipSelection = contentLengthChanged && !hasFocus; 2627 applyRecord(recordRef.current, { domOnly: skipSelection }); 2628 } 2629 const didMountRef = (0, import_element6.useRef)(false); 2630 (0, import_element6.useLayoutEffect)(() => { 2631 if (didMountRef.current && value !== _valueRef.current) { 2632 applyFromProps(); 2633 forceRender(); 2634 } 2635 }, [value]); 2636 (0, import_element6.useLayoutEffect)(() => { 2637 if (!hadSelectionUpdateRef.current) { 2638 return; 2639 } 2640 if (ref.current.ownerDocument.activeElement !== ref.current) { 2641 ref.current.focus(); 2642 } 2643 applyRecord(recordRef.current); 2644 hadSelectionUpdateRef.current = false; 2645 }, [hadSelectionUpdateRef.current]); 2646 const mergedRefs = (0, import_compose3.useMergeRefs)([ 2647 ref, 2648 useDefaultStyle(), 2649 useBoundaryStyle({ record: recordRef }), 2650 useEventListeners({ 2651 record: recordRef, 2652 handleChange, 2653 applyRecord, 2654 createRecord, 2655 isSelected, 2656 onSelectionChange, 2657 forceRender 2658 }), 2659 (0, import_compose3.useRefEffect)(() => { 2660 applyFromProps(); 2661 didMountRef.current = true; 2662 }, [placeholder, ...__unstableDependencies]) 2663 ]); 2664 return { 2665 value: recordRef.current, 2666 // A function to get the most recent value so event handlers in 2667 // useRichText implementations have access to it. For example when 2668 // listening to input events, we internally update the state, but this 2669 // state is not yet available to the input event handler because React 2670 // may re-render asynchronously. 2671 getValue: () => recordRef.current, 2672 onChange: handleChange, 2673 ref: mergedRefs 2674 }; 2675 } 2676 function __experimentalRichText() { 2677 } 2678 return __toCommonJS(index_exports); 2679 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Tue Apr 21 08:20:12 2026 | Cross-referenced by PHPXref |