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


Generated : Thu Jul 16 08:20:16 2026 Cross-referenced by PHPXref