[ 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: () => useDeprecatedRichText,
 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_compose9 = __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 = 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_compose8 = __toESM(require_compose(), 1);
1957  
1958    // packages/rich-text/build-module/hook/event-listeners/copy-handler.mjs
1959    var import_compose = __toESM(require_compose(), 1);
1960    var { subscribeDelegatedListener } = unlock(import_compose.privateApis);
1961    var copy_handler_default = (props) => (element) => {
1962      function onCopy(event) {
1963        const { record } = props.current;
1964        const { ownerDocument } = element;
1965        if (isCollapsed(record.current) || !element.contains(ownerDocument.activeElement)) {
1966          return;
1967        }
1968        const selectedRecord = slice(record.current);
1969        const plainText = getTextContent(selectedRecord);
1970        const html = toHTMLString({ value: selectedRecord });
1971        event.clipboardData.setData("text/plain", plainText);
1972        event.clipboardData.setData("text/html", html);
1973        event.clipboardData.setData("rich-text", "true");
1974        event.preventDefault();
1975        if (event.type === "cut") {
1976          ownerDocument.execCommand("delete");
1977        }
1978      }
1979      const { defaultView } = element.ownerDocument;
1980      const unsubscribeCopy = subscribeDelegatedListener(
1981        defaultView,
1982        "copy",
1983        onCopy
1984      );
1985      const unsubscribeCut = subscribeDelegatedListener(
1986        defaultView,
1987        "cut",
1988        onCopy
1989      );
1990      return () => {
1991        unsubscribeCopy();
1992        unsubscribeCut();
1993      };
1994    };
1995  
1996    // packages/rich-text/build-module/hook/event-listeners/select-object.mjs
1997    var import_compose2 = __toESM(require_compose(), 1);
1998    var { subscribeDelegatedListener: subscribeDelegatedListener2 } = unlock(import_compose2.privateApis);
1999    var select_object_default = () => (element) => {
2000      function onClick(event) {
2001        const { target } = event;
2002        if (target === element || target.textContent && target.isContentEditable) {
2003          return;
2004        }
2005        const { ownerDocument } = target;
2006        const { defaultView } = ownerDocument;
2007        const selection = defaultView.getSelection();
2008        if (selection.containsNode(target)) {
2009          return;
2010        }
2011        const range = ownerDocument.createRange();
2012        const nodeToSelect = target.isContentEditable ? target : target.closest("[contenteditable]");
2013        range.selectNode(nodeToSelect);
2014        selection.removeAllRanges();
2015        selection.addRange(range);
2016        event.preventDefault();
2017      }
2018      function onFocusIn(event) {
2019        if (event.relatedTarget && !element.contains(event.relatedTarget) && event.relatedTarget.tagName === "A") {
2020          onClick(event);
2021        }
2022      }
2023      const unsubscribeClick = subscribeDelegatedListener2(
2024        element,
2025        "click",
2026        onClick
2027      );
2028      const unsubscribeFocusIn = subscribeDelegatedListener2(
2029        element,
2030        "focusin",
2031        onFocusIn
2032      );
2033      return () => {
2034        unsubscribeClick();
2035        unsubscribeFocusIn();
2036      };
2037    };
2038  
2039    // packages/rich-text/build-module/hook/event-listeners/format-boundaries.mjs
2040    var import_keycodes = __toESM(require_keycodes(), 1);
2041    var import_compose3 = __toESM(require_compose(), 1);
2042    var { subscribeDelegatedListener: subscribeDelegatedListener3 } = unlock(import_compose3.privateApis);
2043    var EMPTY_ACTIVE_FORMATS = [];
2044    var format_boundaries_default = (props) => (element) => {
2045      function onKeyDown(event) {
2046        const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event;
2047        if (
2048          // Only override left and right keys without modifiers pressed.
2049          shiftKey || altKey || metaKey || ctrlKey || keyCode !== import_keycodes.LEFT && keyCode !== import_keycodes.RIGHT
2050        ) {
2051          return;
2052        }
2053        const { record, applyRecord, forceRender } = props.current;
2054        const {
2055          text,
2056          formats,
2057          start,
2058          end,
2059          activeFormats: currentActiveFormats = []
2060        } = record.current;
2061        const collapsed = isCollapsed(record.current);
2062        const { defaultView } = element.ownerDocument;
2063        const { direction } = defaultView.getComputedStyle(element);
2064        const reverseKey = direction === "rtl" ? import_keycodes.RIGHT : import_keycodes.LEFT;
2065        const isReverse = event.keyCode === reverseKey;
2066        if (collapsed && currentActiveFormats.length === 0) {
2067          if (start === 0 && isReverse) {
2068            return;
2069          }
2070          if (end === text.length && !isReverse) {
2071            return;
2072          }
2073        }
2074        if (!collapsed) {
2075          return;
2076        }
2077        const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS;
2078        const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS;
2079        const destination = isReverse ? formatsBefore : formatsAfter;
2080        const isIncreasing = currentActiveFormats.every(
2081          (format, index) => format === destination[index]
2082        );
2083        let newActiveFormatsLength = currentActiveFormats.length;
2084        if (!isIncreasing) {
2085          newActiveFormatsLength--;
2086        } else if (newActiveFormatsLength < destination.length) {
2087          newActiveFormatsLength++;
2088        }
2089        if (newActiveFormatsLength === currentActiveFormats.length) {
2090          record.current._newActiveFormats = destination;
2091          return;
2092        }
2093        event.preventDefault();
2094        const origin = isReverse ? formatsAfter : formatsBefore;
2095        const source = isIncreasing ? destination : origin;
2096        const newActiveFormats = source.slice(0, newActiveFormatsLength);
2097        const newValue = {
2098          ...record.current,
2099          activeFormats: newActiveFormats
2100        };
2101        record.current = newValue;
2102        applyRecord(newValue);
2103        forceRender();
2104      }
2105      return subscribeDelegatedListener3(element, "keydown", onKeyDown, true);
2106    };
2107  
2108    // packages/rich-text/build-module/hook/event-listeners/delete.mjs
2109    var import_keycodes2 = __toESM(require_keycodes(), 1);
2110    var import_compose4 = __toESM(require_compose(), 1);
2111    var { subscribeDelegatedListener: subscribeDelegatedListener4 } = unlock(import_compose4.privateApis);
2112    var delete_default = (props) => (element) => {
2113      function onKeyDown(event) {
2114        const { keyCode } = event;
2115        if (event.defaultPrevented) {
2116          return;
2117        }
2118        if (keyCode !== import_keycodes2.DELETE && keyCode !== import_keycodes2.BACKSPACE) {
2119          return;
2120        }
2121        const { createRecord, handleChange } = props.current;
2122        const currentValue = createRecord();
2123        const { start, end, text } = currentValue;
2124        if (start === 0 && end !== 0 && end === text.length) {
2125          handleChange(remove2(currentValue));
2126          event.preventDefault();
2127        }
2128      }
2129      return subscribeDelegatedListener4(element, "keydown", onKeyDown);
2130    };
2131  
2132    // packages/rich-text/build-module/hook/event-listeners/input-and-selection.mjs
2133    var import_compose5 = __toESM(require_compose(), 1);
2134  
2135    // packages/rich-text/build-module/update-formats.mjs
2136    function updateFormats({ value, start, end, formats }) {
2137      const min = Math.min(start, end);
2138      const max = Math.max(start, end);
2139      const formatsBefore = value.formats[min - 1] || [];
2140      const formatsAfter = value.formats[max] || [];
2141      value.activeFormats = formats.map((format, index) => {
2142        if (formatsBefore[index]) {
2143          if (isFormatEqual(format, formatsBefore[index])) {
2144            return formatsBefore[index];
2145          }
2146        } else if (formatsAfter[index]) {
2147          if (isFormatEqual(format, formatsAfter[index])) {
2148            return formatsAfter[index];
2149          }
2150        }
2151        return format;
2152      });
2153      while (--end >= start) {
2154        if (value.activeFormats.length > 0) {
2155          value.formats[end] = value.activeFormats;
2156        } else {
2157          delete value.formats[end];
2158        }
2159      }
2160      return value;
2161    }
2162  
2163    // packages/rich-text/build-module/hook/event-listeners/input-and-selection.mjs
2164    var { subscribeDelegatedListener: subscribeDelegatedListener5 } = unlock(import_compose5.privateApis);
2165    var INSERTION_INPUT_TYPES_TO_IGNORE = /* @__PURE__ */ new Set([
2166      "insertParagraph",
2167      "insertOrderedList",
2168      "insertUnorderedList",
2169      "insertHorizontalRule",
2170      "insertLink"
2171    ]);
2172    var EMPTY_ACTIVE_FORMATS2 = [];
2173    var PLACEHOLDER_ATTR_NAME = "data-rich-text-placeholder";
2174    function fixPlaceholderSelection(defaultView) {
2175      const selection = defaultView.getSelection();
2176      const { anchorNode, anchorOffset } = selection;
2177      if (anchorNode.nodeType !== anchorNode.ELEMENT_NODE) {
2178        return;
2179      }
2180      const targetNode = anchorNode.childNodes[anchorOffset];
2181      if (!targetNode || targetNode.nodeType !== targetNode.ELEMENT_NODE || !targetNode.hasAttribute(PLACEHOLDER_ATTR_NAME)) {
2182        return;
2183      }
2184      selection.collapseToStart();
2185    }
2186    var input_and_selection_default = (props) => (element) => {
2187      const { ownerDocument } = element;
2188      const { defaultView } = ownerDocument;
2189      let isComposing = false;
2190      function onInput(event) {
2191        if (isComposing) {
2192          return;
2193        }
2194        let inputType;
2195        if (event) {
2196          inputType = event.inputType;
2197        }
2198        const { record, applyRecord, createRecord, handleChange } = props.current;
2199        if (inputType && (inputType.indexOf("format") === 0 || INSERTION_INPUT_TYPES_TO_IGNORE.has(inputType))) {
2200          applyRecord(record.current);
2201          return;
2202        }
2203        const currentValue = createRecord();
2204        const { start, activeFormats: oldActiveFormats = [] } = record.current;
2205        const clearFormats = !isCollapsed(record.current) && currentValue.start <= start;
2206        const change = updateFormats({
2207          value: currentValue,
2208          start,
2209          end: currentValue.start,
2210          formats: clearFormats ? [] : oldActiveFormats
2211        });
2212        handleChange(change);
2213      }
2214      function handleSelectionChange() {
2215        const { record, applyRecord, createRecord, onSelectionChange } = props.current;
2216        if (element.contentEditable !== "true") {
2217          return;
2218        }
2219        if (ownerDocument.activeElement !== element) {
2220          ownerDocument.removeEventListener(
2221            "selectionchange",
2222            handleSelectionChange
2223          );
2224          return;
2225        }
2226        if (isComposing) {
2227          return;
2228        }
2229        const { start, end, text } = createRecord();
2230        const oldRecord = record.current;
2231        if (text !== oldRecord.text) {
2232          onInput();
2233          return;
2234        }
2235        if (start === oldRecord.start && end === oldRecord.end) {
2236          if (oldRecord.text.length === 0 && start === 0) {
2237            fixPlaceholderSelection(defaultView);
2238          }
2239          return;
2240        }
2241        const newValue = {
2242          ...oldRecord,
2243          start,
2244          end,
2245          // _newActiveFormats may be set on arrow key navigation to control
2246          // the right boundary position. If undefined, getActiveFormats will
2247          // give the active formats according to the browser.
2248          activeFormats: oldRecord._newActiveFormats,
2249          _newActiveFormats: void 0
2250        };
2251        const newActiveFormats = getActiveFormats(
2252          newValue,
2253          EMPTY_ACTIVE_FORMATS2
2254        );
2255        newValue.activeFormats = newActiveFormats;
2256        record.current = newValue;
2257        applyRecord(newValue, { domOnly: true });
2258        onSelectionChange(start, end);
2259      }
2260      function onCompositionStart() {
2261        isComposing = true;
2262        ownerDocument.removeEventListener(
2263          "selectionchange",
2264          handleSelectionChange
2265        );
2266        element.querySelector(`[$PLACEHOLDER_ATTR_NAME}]`)?.remove();
2267      }
2268      function onCompositionEnd() {
2269        isComposing = false;
2270        onInput({ inputType: "insertText" });
2271        ownerDocument.addEventListener(
2272          "selectionchange",
2273          handleSelectionChange
2274        );
2275      }
2276      function onFocus(event) {
2277        if (event.target !== element) {
2278          return;
2279        }
2280        if (element.contentEditable !== "true") {
2281          return;
2282        }
2283        const { record, isSelected, onSelectionChange, applyRecord } = props.current;
2284        if (element.parentElement.closest('[contenteditable="true"]')) {
2285          return;
2286        }
2287        if (!isSelected) {
2288          const index = void 0;
2289          record.current = {
2290            ...record.current,
2291            start: index,
2292            end: index,
2293            activeFormats: EMPTY_ACTIVE_FORMATS2
2294          };
2295        } else {
2296          applyRecord(record.current, { domOnly: true });
2297        }
2298        onSelectionChange(record.current.start, record.current.end);
2299        window.queueMicrotask(handleSelectionChange);
2300        ownerDocument.addEventListener(
2301          "selectionchange",
2302          handleSelectionChange
2303        );
2304      }
2305      const unsubscribeInput = subscribeDelegatedListener5(
2306        element,
2307        "input",
2308        onInput,
2309        true
2310      );
2311      const unsubscribeCompositionStart = subscribeDelegatedListener5(
2312        element,
2313        "compositionstart",
2314        onCompositionStart
2315      );
2316      const unsubscribeCompositionEnd = subscribeDelegatedListener5(
2317        element,
2318        "compositionend",
2319        onCompositionEnd,
2320        true
2321      );
2322      const unsubscribeFocus = subscribeDelegatedListener5(
2323        element,
2324        "focusin",
2325        onFocus
2326      );
2327      return () => {
2328        unsubscribeInput();
2329        unsubscribeCompositionStart();
2330        unsubscribeCompositionEnd();
2331        unsubscribeFocus();
2332      };
2333    };
2334  
2335    // packages/rich-text/build-module/hook/event-listeners/selection-change-compat.mjs
2336    var import_compose6 = __toESM(require_compose(), 1);
2337    var { subscribeDelegatedListener: subscribeDelegatedListener6 } = unlock(import_compose6.privateApis);
2338    var selection_change_compat_default = () => (element) => {
2339      const { ownerDocument } = element;
2340      const { defaultView } = ownerDocument;
2341      const selection = defaultView?.getSelection();
2342      let range;
2343      function getRange() {
2344        return selection.rangeCount ? selection.getRangeAt(0) : null;
2345      }
2346      function onDown(event) {
2347        const type = event.type === "keydown" ? "keyup" : "pointerup";
2348        function onCancel() {
2349          ownerDocument.removeEventListener(type, onUp);
2350          ownerDocument.removeEventListener("selectionchange", onCancel);
2351          ownerDocument.removeEventListener("input", onCancel);
2352        }
2353        function onUp() {
2354          onCancel();
2355          if (isRangeEqual(range, getRange())) {
2356            return;
2357          }
2358          ownerDocument.dispatchEvent(new Event("selectionchange"));
2359        }
2360        ownerDocument.addEventListener(type, onUp);
2361        ownerDocument.addEventListener("selectionchange", onCancel);
2362        ownerDocument.addEventListener("input", onCancel);
2363        range = getRange();
2364      }
2365      const unsubscribePointerDown = subscribeDelegatedListener6(
2366        element,
2367        "pointerdown",
2368        onDown
2369      );
2370      const unsubscribeKeyDown = subscribeDelegatedListener6(
2371        element,
2372        "keydown",
2373        onDown
2374      );
2375      return () => {
2376        unsubscribePointerDown();
2377        unsubscribeKeyDown();
2378      };
2379    };
2380  
2381    // packages/rich-text/build-module/hook/event-listeners/prevent-focus-capture.mjs
2382    var import_compose7 = __toESM(require_compose(), 1);
2383    var { subscribeDelegatedListener: subscribeDelegatedListener7 } = unlock(import_compose7.privateApis);
2384    function preventFocusCapture() {
2385      return (element) => {
2386        const { ownerDocument } = element;
2387        const { defaultView } = ownerDocument;
2388        let value = null;
2389        function onPointerDown(event) {
2390          if (event.defaultPrevented) {
2391            return;
2392          }
2393          if (event.target === element) {
2394            return;
2395          }
2396          if (!event.target.contains(element)) {
2397            return;
2398          }
2399          value = element.getAttribute("contenteditable");
2400          element.setAttribute("contenteditable", "false");
2401          defaultView.getSelection().removeAllRanges();
2402        }
2403        function onPointerUp() {
2404          if (value !== null) {
2405            element.setAttribute("contenteditable", value);
2406            value = null;
2407          }
2408        }
2409        const unsubscribePointerDown = subscribeDelegatedListener7(
2410          defaultView,
2411          "pointerdown",
2412          onPointerDown
2413        );
2414        const unsubscribePointerUp = subscribeDelegatedListener7(
2415          defaultView,
2416          "pointerup",
2417          onPointerUp
2418        );
2419        return () => {
2420          unsubscribePointerDown();
2421          unsubscribePointerUp();
2422        };
2423      };
2424    }
2425  
2426    // packages/rich-text/build-module/hook/event-listeners/index.mjs
2427    var allEventListeners = [
2428      copy_handler_default,
2429      select_object_default,
2430      format_boundaries_default,
2431      delete_default,
2432      input_and_selection_default,
2433      selection_change_compat_default,
2434      preventFocusCapture
2435    ];
2436    function useEventListeners(props) {
2437      const propsRef = (0, import_element3.useRef)(props);
2438      (0, import_element3.useInsertionEffect)(() => {
2439        propsRef.current = props;
2440      });
2441      const refEffects = (0, import_element3.useMemo)(
2442        () => allEventListeners.map((refEffect) => refEffect(propsRef)),
2443        [propsRef]
2444      );
2445      return (0, import_compose8.useRefEffect)(
2446        (element) => {
2447          const cleanups = refEffects.map((effect) => effect(element));
2448          return () => {
2449            cleanups.forEach((cleanup) => cleanup());
2450          };
2451        },
2452        [refEffects]
2453      );
2454    }
2455  
2456    // packages/rich-text/build-module/hook/use-format-types.mjs
2457    var import_element4 = __toESM(require_element(), 1);
2458    var import_data8 = __toESM(require_data(), 1);
2459    function formatTypesSelector(select5) {
2460      return select5(store).getFormatTypes();
2461    }
2462    var interactiveContentTags = /* @__PURE__ */ new Set([
2463      "a",
2464      "audio",
2465      "button",
2466      "details",
2467      "embed",
2468      "iframe",
2469      "input",
2470      "label",
2471      "select",
2472      "textarea",
2473      "video"
2474    ]);
2475    function prefixSelectKeys(selected, prefix) {
2476      if (typeof selected !== "object") {
2477        return { [prefix]: selected };
2478      }
2479      return Object.fromEntries(
2480        Object.entries(selected).map(([key, value]) => [
2481          `$prefix}.$key}`,
2482          value
2483        ])
2484      );
2485    }
2486    function getPrefixedSelectKeys(selected, prefix) {
2487      if (selected[prefix]) {
2488        return selected[prefix];
2489      }
2490      return Object.keys(selected).filter((key) => key.startsWith(prefix + ".")).reduce((accumulator, key) => {
2491        accumulator[key.slice(prefix.length + 1)] = selected[key];
2492        return accumulator;
2493      }, {});
2494    }
2495    function useFormatTypes({
2496      allowedFormats,
2497      withoutInteractiveFormatting,
2498      __unstableFormatTypeHandlerContext
2499    }) {
2500      const allFormatTypes = (0, import_data8.useSelect)(formatTypesSelector, []);
2501      const formatTypes2 = (0, import_element4.useMemo)(() => {
2502        return allFormatTypes.filter(({ name, interactive, tagName }) => {
2503          if (allowedFormats && !allowedFormats.includes(name)) {
2504            return false;
2505          }
2506          if (withoutInteractiveFormatting && (interactive || interactiveContentTags.has(tagName))) {
2507            return false;
2508          }
2509          return true;
2510        });
2511      }, [allFormatTypes, allowedFormats, withoutInteractiveFormatting]);
2512      const keyedSelected = (0, import_data8.useSelect)(
2513        (select5) => formatTypes2.reduce((accumulator, type) => {
2514          if (!type.__experimentalGetPropsForEditableTreePreparation || !__unstableFormatTypeHandlerContext) {
2515            return accumulator;
2516          }
2517          return {
2518            ...accumulator,
2519            ...prefixSelectKeys(
2520              type.__experimentalGetPropsForEditableTreePreparation(
2521                select5,
2522                __unstableFormatTypeHandlerContext
2523              ),
2524              type.name
2525            )
2526          };
2527        }, {}),
2528        [formatTypes2, __unstableFormatTypeHandlerContext]
2529      );
2530      const dispatch3 = (0, import_data8.useDispatch)();
2531      const prepareHandlers = [];
2532      const valueHandlers = [];
2533      const changeHandlers = [];
2534      const dependencies = [];
2535      for (const key in keyedSelected) {
2536        dependencies.push(keyedSelected[key]);
2537      }
2538      formatTypes2.forEach((type) => {
2539        if (type.__experimentalCreatePrepareEditableTree && __unstableFormatTypeHandlerContext) {
2540          const handler = type.__experimentalCreatePrepareEditableTree(
2541            getPrefixedSelectKeys(keyedSelected, type.name),
2542            __unstableFormatTypeHandlerContext
2543          );
2544          if (type.__experimentalCreateOnChangeEditableValue) {
2545            valueHandlers.push(handler);
2546          } else {
2547            prepareHandlers.push(handler);
2548          }
2549        }
2550        if (type.__experimentalCreateOnChangeEditableValue && __unstableFormatTypeHandlerContext) {
2551          let dispatchers = {};
2552          if (type.__experimentalGetPropsForEditableTreeChangeHandler) {
2553            dispatchers = type.__experimentalGetPropsForEditableTreeChangeHandler(
2554              dispatch3,
2555              __unstableFormatTypeHandlerContext
2556            );
2557          }
2558          const selected = getPrefixedSelectKeys(keyedSelected, type.name);
2559          changeHandlers.push(
2560            type.__experimentalCreateOnChangeEditableValue(
2561              {
2562                ...typeof selected === "object" ? selected : {},
2563                ...dispatchers
2564              },
2565              __unstableFormatTypeHandlerContext
2566            )
2567          );
2568        }
2569      });
2570      return {
2571        formatTypes: formatTypes2,
2572        prepareHandlers,
2573        valueHandlers,
2574        changeHandlers,
2575        dependencies
2576      };
2577    }
2578  
2579    // packages/rich-text/build-module/hook/index.mjs
2580    function useRichTextBase({
2581      value = "",
2582      selectionStart,
2583      selectionEnd,
2584      placeholder,
2585      onSelectionChange,
2586      preserveWhiteSpace,
2587      onChange,
2588      __unstableDisableFormats: disableFormats,
2589      __unstableIsSelected: isSelected,
2590      __unstableDependencies = [],
2591      __unstableAfterParse,
2592      __unstableBeforeSerialize,
2593      __unstableAddInvisibleFormats
2594    }) {
2595      const registry = (0, import_data9.useRegistry)();
2596      const [, forceRender] = (0, import_element5.useReducer)(() => ({}));
2597      const ref = (0, import_element5.useRef)();
2598      function createRecord() {
2599        const {
2600          ownerDocument: { defaultView }
2601        } = ref.current;
2602        const selection = defaultView.getSelection();
2603        const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
2604        return create({
2605          element: ref.current,
2606          range,
2607          __unstableIsEditableTree: true
2608        });
2609      }
2610      function applyRecord(newRecord, { domOnly } = {}) {
2611        apply({
2612          value: newRecord,
2613          current: ref.current,
2614          prepareEditableTree: __unstableAddInvisibleFormats,
2615          __unstableDomOnly: domOnly,
2616          placeholder
2617        });
2618      }
2619      const _valueRef = (0, import_element5.useRef)(value);
2620      const recordRef = (0, import_element5.useRef)();
2621      function setRecordFromProps() {
2622        const activeFormats = recordRef.current?.activeFormats;
2623        _valueRef.current = value;
2624        recordRef.current = value;
2625        if (!(value instanceof RichTextData)) {
2626          recordRef.current = value ? RichTextData.fromHTMLString(value, { preserveWhiteSpace }) : RichTextData.empty();
2627        }
2628        recordRef.current = {
2629          text: recordRef.current.text,
2630          formats: recordRef.current.formats,
2631          replacements: recordRef.current.replacements,
2632          activeFormats
2633        };
2634        if (disableFormats) {
2635          recordRef.current.formats = Array(value.length);
2636          recordRef.current.replacements = Array(value.length);
2637        }
2638        if (__unstableAfterParse) {
2639          recordRef.current.formats = __unstableAfterParse(
2640            recordRef.current
2641          );
2642        }
2643        recordRef.current.start = selectionStart;
2644        recordRef.current.end = selectionEnd;
2645      }
2646      const hadSelectionUpdateRef = (0, import_element5.useRef)(false);
2647      if (!recordRef.current) {
2648        hadSelectionUpdateRef.current = isSelected;
2649        setRecordFromProps();
2650      } else if (selectionStart !== recordRef.current.start || selectionEnd !== recordRef.current.end) {
2651        hadSelectionUpdateRef.current = isSelected;
2652        recordRef.current = {
2653          ...recordRef.current,
2654          start: selectionStart,
2655          end: selectionEnd,
2656          activeFormats: void 0
2657        };
2658      }
2659      function handleChange(newRecord) {
2660        recordRef.current = newRecord;
2661        applyRecord(newRecord);
2662        if (disableFormats) {
2663          _valueRef.current = newRecord.text;
2664        } else {
2665          const newFormats = __unstableBeforeSerialize ? __unstableBeforeSerialize(newRecord) : newRecord.formats;
2666          newRecord = { ...newRecord, formats: newFormats };
2667          if (typeof value === "string") {
2668            _valueRef.current = toHTMLString({
2669              value: newRecord,
2670              preserveWhiteSpace
2671            });
2672          } else {
2673            _valueRef.current = new RichTextData(newRecord);
2674          }
2675        }
2676        const { start, end, formats, text } = recordRef.current;
2677        registry.batch(() => {
2678          onSelectionChange(start, end);
2679          onChange(_valueRef.current, {
2680            __unstableFormats: formats,
2681            __unstableText: text
2682          });
2683        });
2684        forceRender();
2685      }
2686      function applyFromProps() {
2687        const previousValue = _valueRef.current;
2688        setRecordFromProps();
2689        const contentLengthChanged = previousValue && typeof previousValue === "string" && typeof value === "string" && previousValue.length !== value.length;
2690        const hasFocus = ref.current?.contains(
2691          ref.current.ownerDocument.activeElement
2692        );
2693        const skipSelection = contentLengthChanged && !hasFocus;
2694        applyRecord(recordRef.current, { domOnly: skipSelection });
2695      }
2696      const didMountRef = (0, import_element5.useRef)(false);
2697      (0, import_element5.useLayoutEffect)(() => {
2698        if (didMountRef.current && value !== _valueRef.current) {
2699          applyFromProps();
2700          forceRender();
2701        }
2702      }, [value]);
2703      (0, import_element5.useLayoutEffect)(() => {
2704        if (!hadSelectionUpdateRef.current) {
2705          return;
2706        }
2707        if (ref.current.ownerDocument.activeElement !== ref.current) {
2708          ref.current.focus();
2709        }
2710        applyRecord(recordRef.current);
2711        hadSelectionUpdateRef.current = false;
2712      }, [hadSelectionUpdateRef.current]);
2713      const mergedRefs = (0, import_compose9.useMergeRefs)([
2714        ref,
2715        useDefaultStyle(),
2716        useBoundaryStyle({ record: recordRef }),
2717        useEventListeners({
2718          record: recordRef,
2719          handleChange,
2720          applyRecord,
2721          createRecord,
2722          isSelected,
2723          onSelectionChange,
2724          forceRender
2725        }),
2726        (0, import_compose9.useRefEffect)(() => {
2727          applyFromProps();
2728          didMountRef.current = true;
2729        }, [placeholder, ...__unstableDependencies])
2730      ]);
2731      return {
2732        value: recordRef.current,
2733        // A function to get the most recent value so event handlers in
2734        // useRichText implementations have access to it. For example when
2735        // listening to input events, we internally update the state, but this
2736        // state is not yet available to the input event handler because React
2737        // may re-render asynchronously.
2738        getValue: () => recordRef.current,
2739        onChange: handleChange,
2740        ref: mergedRefs
2741      };
2742    }
2743    function useRichText({
2744      allowedFormats,
2745      withoutInteractiveFormatting,
2746      onChange,
2747      __unstableDependencies = [],
2748      __unstableFormatTypeHandlerContext,
2749      ...props
2750    }) {
2751      const {
2752        formatTypes: formatTypes2,
2753        prepareHandlers,
2754        valueHandlers,
2755        changeHandlers,
2756        dependencies
2757      } = useFormatTypes({
2758        allowedFormats,
2759        withoutInteractiveFormatting,
2760        __unstableFormatTypeHandlerContext
2761      });
2762      function addEditorOnlyFormats(record) {
2763        return valueHandlers.reduce(
2764          (accumulator, fn) => fn(accumulator, record.text),
2765          record.formats
2766        );
2767      }
2768      function removeEditorOnlyFormats(record) {
2769        formatTypes2.forEach((formatType) => {
2770          if (formatType.__experimentalCreatePrepareEditableTree) {
2771            record = removeFormat(
2772              record,
2773              formatType.name,
2774              0,
2775              record.text.length
2776            );
2777          }
2778        });
2779        return record.formats;
2780      }
2781      function addInvisibleFormats(record) {
2782        return prepareHandlers.reduce(
2783          (accumulator, fn) => fn(accumulator, record.text),
2784          record.formats
2785        );
2786      }
2787      const result = useRichTextBase({
2788        ...props,
2789        onChange(value, { __unstableFormats, __unstableText }) {
2790          onChange(value, { __unstableFormats, __unstableText });
2791          Object.values(changeHandlers).forEach((changeHandler) => {
2792            changeHandler(__unstableFormats, __unstableText);
2793          });
2794        },
2795        __unstableDependencies: [...dependencies, ...__unstableDependencies],
2796        __unstableAfterParse: addEditorOnlyFormats,
2797        __unstableBeforeSerialize: removeEditorOnlyFormats,
2798        __unstableAddInvisibleFormats: addInvisibleFormats
2799      });
2800      return { ...result, formatTypes: formatTypes2 };
2801    }
2802    function useDeprecatedRichText(props) {
2803      (0, import_deprecated.default)("`__unstableUseRichText` hook", {
2804        since: "7.0"
2805      });
2806      return useRichTextBase(props);
2807    }
2808  
2809    // packages/rich-text/build-module/private-apis.mjs
2810    var privateApis = {};
2811    lock(privateApis, {
2812      useRichText
2813    });
2814  
2815    // packages/rich-text/build-module/hook/use-anchor-ref.mjs
2816    var import_element6 = __toESM(require_element(), 1);
2817    var import_deprecated2 = __toESM(require_deprecated(), 1);
2818    function useAnchorRef({ ref, value, settings = {} }) {
2819      (0, import_deprecated2.default)("`useAnchorRef` hook", {
2820        since: "6.1",
2821        alternative: "`useAnchor` hook"
2822      });
2823      const { tagName, className, name } = settings;
2824      const activeFormat = name ? getActiveFormat(value, name) : void 0;
2825      return (0, import_element6.useMemo)(() => {
2826        if (!ref.current) {
2827          return;
2828        }
2829        const {
2830          ownerDocument: { defaultView }
2831        } = ref.current;
2832        const selection = defaultView.getSelection();
2833        if (!selection.rangeCount) {
2834          return;
2835        }
2836        const range = selection.getRangeAt(0);
2837        if (!activeFormat) {
2838          return range;
2839        }
2840        let element = range.startContainer;
2841        element = element.nextElementSibling || element;
2842        while (element.nodeType !== element.ELEMENT_NODE) {
2843          element = element.parentNode;
2844        }
2845        return element.closest(
2846          tagName + (className ? "." + className : "")
2847        );
2848      }, [activeFormat, value.start, value.end, tagName, className]);
2849    }
2850  
2851    // packages/rich-text/build-module/hook/use-anchor.mjs
2852    var import_compose10 = __toESM(require_compose(), 1);
2853    var import_element7 = __toESM(require_element(), 1);
2854    var import_dom = __toESM(require_dom(), 1);
2855    function getFormatElement(range, editableContentElement, tagName, className) {
2856      let element = range.startContainer;
2857      if (element.nodeType === element.TEXT_NODE && element instanceof window.Text && range.startOffset === element.length && element.nextSibling) {
2858        element = element.nextSibling;
2859        while (element.firstChild) {
2860          element = element.firstChild;
2861        }
2862      }
2863      if (element.nodeType !== element.ELEMENT_NODE) {
2864        if (!element.parentElement) {
2865          return;
2866        }
2867        element = element.parentElement;
2868      }
2869      if (element === editableContentElement) {
2870        return;
2871      }
2872      if (!editableContentElement.contains(element)) {
2873        return;
2874      }
2875      const selector = tagName + (className ? "." + className : "");
2876      if (!selector) {
2877        return;
2878      }
2879      if (!(element instanceof window.HTMLElement)) {
2880        return;
2881      }
2882      let closestElement = element;
2883      while (closestElement && closestElement !== editableContentElement) {
2884        if (closestElement.matches(selector)) {
2885          return closestElement;
2886        }
2887        closestElement = closestElement.parentElement;
2888      }
2889      return void 0;
2890    }
2891    function createVirtualAnchorElement(range, editableContentElement) {
2892      return {
2893        contextElement: editableContentElement,
2894        getBoundingClientRect() {
2895          if (editableContentElement.contains(range.startContainer)) {
2896            return (0, import_dom.getRectangleFromRange)(range) ?? range.getBoundingClientRect();
2897          }
2898          return editableContentElement.getBoundingClientRect();
2899        }
2900      };
2901    }
2902    function getAnchor(editableContentElement, tagName, className) {
2903      if (!editableContentElement) {
2904        return;
2905      }
2906      const { ownerDocument } = editableContentElement;
2907      const { defaultView } = ownerDocument;
2908      const selection = defaultView?.getSelection();
2909      if (!selection) {
2910        return;
2911      }
2912      if (!selection.rangeCount) {
2913        return;
2914      }
2915      const range = selection.getRangeAt(0);
2916      if (!range || !range.startContainer) {
2917        return;
2918      }
2919      if (!tagName && !className) {
2920        return createVirtualAnchorElement(range, editableContentElement);
2921      }
2922      return getFormatElement(range, editableContentElement, tagName, className) ?? createVirtualAnchorElement(range, editableContentElement);
2923    }
2924    var DEFAULT_SETTINGS = {
2925      tagName: "",
2926      className: ""
2927    };
2928    function useAnchor({
2929      editableContentElement,
2930      settings
2931    }) {
2932      const { tagName, className } = settings ?? DEFAULT_SETTINGS;
2933      const isActive = !!(settings && "isActive" in settings && settings.isActive);
2934      const [anchor, setAnchor] = (0, import_element7.useState)(
2935        () => getAnchor(editableContentElement, tagName, className ?? "")
2936      );
2937      const wasActive = (0, import_compose10.usePrevious)(isActive);
2938      (0, import_element7.useLayoutEffect)(() => {
2939        if (!editableContentElement) {
2940          return;
2941        }
2942        function callback() {
2943          setAnchor(
2944            getAnchor(editableContentElement, tagName, className ?? "")
2945          );
2946        }
2947        function attach() {
2948          ownerDocument.addEventListener("selectionchange", callback);
2949        }
2950        function detach() {
2951          ownerDocument.removeEventListener("selectionchange", callback);
2952        }
2953        const { ownerDocument } = editableContentElement;
2954        if (editableContentElement === ownerDocument.activeElement || // When a link is created, we need to attach the popover to the newly created anchor.
2955        !wasActive && isActive || // Sometimes we're _removing_ an active anchor, such as the inline color popover.
2956        // When we add the color, it switches from a virtual anchor to a `<mark>` element.
2957        // When we _remove_ the color, it switches from a `<mark>` element to a virtual anchor.
2958        wasActive && !isActive) {
2959          setAnchor(
2960            getAnchor(editableContentElement, tagName, className ?? "")
2961          );
2962          attach();
2963        }
2964        editableContentElement.addEventListener("focusin", attach);
2965        editableContentElement.addEventListener("focusout", detach);
2966        return () => {
2967          detach();
2968          editableContentElement.removeEventListener("focusin", attach);
2969          editableContentElement.removeEventListener("focusout", detach);
2970        };
2971      }, [editableContentElement, tagName, className, isActive, wasActive]);
2972      return anchor;
2973    }
2974  
2975    // packages/rich-text/build-module/index.mjs
2976    function __experimentalRichText() {
2977    }
2978    return __toCommonJS(index_exports);
2979  })();


Generated : Sat Jul 4 08:20:12 2026 Cross-referenced by PHPXref