[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/ -> rich-text.js (source)

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


Generated : Sun Jun 14 08:20:09 2026 Cross-referenced by PHPXref