[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

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


Generated : Fri Aug 14 08:20:23 2026 Cross-referenced by PHPXref