wp/wp-includes/js/dist/rich-text.js
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
--- a/wp/wp-includes/js/dist/rich-text.js	Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/js/dist/rich-text.js	Fri Sep 05 18:40:08 2025 +0200
@@ -1,36 +1,48 @@
-/******/ (function() { // webpackBootstrap
+/******/ (() => { // webpackBootstrap
 /******/ 	"use strict";
 /******/ 	// The require scope
 /******/ 	var __webpack_require__ = {};
 /******/ 	
 /************************************************************************/
+/******/ 	/* webpack/runtime/compat get default export */
+/******/ 	(() => {
+/******/ 		// getDefaultExport function for compatibility with non-harmony modules
+/******/ 		__webpack_require__.n = (module) => {
+/******/ 			var getter = module && module.__esModule ?
+/******/ 				() => (module['default']) :
+/******/ 				() => (module);
+/******/ 			__webpack_require__.d(getter, { a: getter });
+/******/ 			return getter;
+/******/ 		};
+/******/ 	})();
+/******/ 	
 /******/ 	/* webpack/runtime/define property getters */
-/******/ 	!function() {
+/******/ 	(() => {
 /******/ 		// define getter functions for harmony exports
-/******/ 		__webpack_require__.d = function(exports, definition) {
+/******/ 		__webpack_require__.d = (exports, definition) => {
 /******/ 			for(var key in definition) {
 /******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
 /******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
 /******/ 				}
 /******/ 			}
 /******/ 		};
-/******/ 	}();
+/******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
-/******/ 	!function() {
-/******/ 		__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
-/******/ 	}();
+/******/ 	(() => {
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
+/******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/make namespace object */
-/******/ 	!function() {
+/******/ 	(() => {
 /******/ 		// define __esModule on exports
-/******/ 		__webpack_require__.r = function(exports) {
+/******/ 		__webpack_require__.r = (exports) => {
 /******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
 /******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
 /******/ 			}
 /******/ 			Object.defineProperty(exports, '__esModule', { value: true });
 /******/ 		};
-/******/ 	}();
+/******/ 	})();
 /******/ 	
 /************************************************************************/
 var __webpack_exports__ = {};
@@ -39,74 +51,59 @@
 
 // EXPORTS
 __webpack_require__.d(__webpack_exports__, {
-  "__UNSTABLE_LINE_SEPARATOR": function() { return /* reexport */ LINE_SEPARATOR; },
-  "__experimentalRichText": function() { return /* reexport */ __experimentalRichText; },
-  "__unstableCanIndentListItems": function() { return /* reexport */ canIndentListItems; },
-  "__unstableCanOutdentListItems": function() { return /* reexport */ canOutdentListItems; },
-  "__unstableChangeListType": function() { return /* reexport */ changeListType; },
-  "__unstableCreateElement": function() { return /* reexport */ createElement; },
-  "__unstableFormatEdit": function() { return /* reexport */ FormatEdit; },
-  "__unstableIndentListItems": function() { return /* reexport */ indentListItems; },
-  "__unstableInsertLineSeparator": function() { return /* reexport */ insertLineSeparator; },
-  "__unstableIsActiveListType": function() { return /* reexport */ isActiveListType; },
-  "__unstableIsEmptyLine": function() { return /* reexport */ isEmptyLine; },
-  "__unstableIsListRootSelected": function() { return /* reexport */ isListRootSelected; },
-  "__unstableOutdentListItems": function() { return /* reexport */ outdentListItems; },
-  "__unstableRemoveLineSeparator": function() { return /* reexport */ removeLineSeparator; },
-  "__unstableToDom": function() { return /* reexport */ toDom; },
-  "__unstableUseRichText": function() { return /* reexport */ useRichText; },
-  "applyFormat": function() { return /* reexport */ applyFormat; },
-  "concat": function() { return /* reexport */ concat; },
-  "create": function() { return /* reexport */ create; },
-  "getActiveFormat": function() { return /* reexport */ getActiveFormat; },
-  "getActiveObject": function() { return /* reexport */ getActiveObject; },
-  "getTextContent": function() { return /* reexport */ getTextContent; },
-  "insert": function() { return /* reexport */ insert; },
-  "insertObject": function() { return /* reexport */ insertObject; },
-  "isCollapsed": function() { return /* reexport */ isCollapsed; },
-  "isEmpty": function() { return /* reexport */ isEmpty; },
-  "join": function() { return /* reexport */ join; },
-  "registerFormatType": function() { return /* reexport */ registerFormatType; },
-  "remove": function() { return /* reexport */ remove; },
-  "removeFormat": function() { return /* reexport */ removeFormat; },
-  "replace": function() { return /* reexport */ replace_replace; },
-  "slice": function() { return /* reexport */ slice; },
-  "split": function() { return /* reexport */ split; },
-  "store": function() { return /* reexport */ store; },
-  "toHTMLString": function() { return /* reexport */ toHTMLString; },
-  "toggleFormat": function() { return /* reexport */ toggleFormat; },
-  "unregisterFormatType": function() { return /* reexport */ unregisterFormatType; },
-  "useAnchorRef": function() { return /* reexport */ useAnchorRef; }
+  RichTextData: () => (/* reexport */ RichTextData),
+  __experimentalRichText: () => (/* reexport */ __experimentalRichText),
+  __unstableCreateElement: () => (/* reexport */ createElement),
+  __unstableToDom: () => (/* reexport */ toDom),
+  __unstableUseRichText: () => (/* reexport */ useRichText),
+  applyFormat: () => (/* reexport */ applyFormat),
+  concat: () => (/* reexport */ concat),
+  create: () => (/* reexport */ create),
+  getActiveFormat: () => (/* reexport */ getActiveFormat),
+  getActiveFormats: () => (/* reexport */ getActiveFormats),
+  getActiveObject: () => (/* reexport */ getActiveObject),
+  getTextContent: () => (/* reexport */ getTextContent),
+  insert: () => (/* reexport */ insert),
+  insertObject: () => (/* reexport */ insertObject),
+  isCollapsed: () => (/* reexport */ isCollapsed),
+  isEmpty: () => (/* reexport */ isEmpty),
+  join: () => (/* reexport */ join),
+  registerFormatType: () => (/* reexport */ registerFormatType),
+  remove: () => (/* reexport */ remove_remove),
+  removeFormat: () => (/* reexport */ removeFormat),
+  replace: () => (/* reexport */ replace_replace),
+  slice: () => (/* reexport */ slice),
+  split: () => (/* reexport */ split),
+  store: () => (/* reexport */ store),
+  toHTMLString: () => (/* reexport */ toHTMLString),
+  toggleFormat: () => (/* reexport */ toggleFormat),
+  unregisterFormatType: () => (/* reexport */ unregisterFormatType),
+  useAnchor: () => (/* reexport */ useAnchor),
+  useAnchorRef: () => (/* reexport */ useAnchorRef)
 });
 
 // NAMESPACE OBJECT: ./node_modules/@wordpress/rich-text/build-module/store/selectors.js
 var selectors_namespaceObject = {};
 __webpack_require__.r(selectors_namespaceObject);
 __webpack_require__.d(selectors_namespaceObject, {
-  "getFormatType": function() { return getFormatType; },
-  "getFormatTypeForBareElement": function() { return getFormatTypeForBareElement; },
-  "getFormatTypeForClassName": function() { return getFormatTypeForClassName; },
-  "getFormatTypes": function() { return getFormatTypes; }
+  getFormatType: () => (getFormatType),
+  getFormatTypeForBareElement: () => (getFormatTypeForBareElement),
+  getFormatTypeForClassName: () => (getFormatTypeForClassName),
+  getFormatTypes: () => (getFormatTypes)
 });
 
 // NAMESPACE OBJECT: ./node_modules/@wordpress/rich-text/build-module/store/actions.js
 var actions_namespaceObject = {};
 __webpack_require__.r(actions_namespaceObject);
 __webpack_require__.d(actions_namespaceObject, {
-  "addFormatTypes": function() { return addFormatTypes; },
-  "removeFormatTypes": function() { return removeFormatTypes; }
+  addFormatTypes: () => (addFormatTypes),
+  removeFormatTypes: () => (removeFormatTypes)
 });
 
 ;// CONCATENATED MODULE: external ["wp","data"]
-var external_wp_data_namespaceObject = window["wp"]["data"];
-;// CONCATENATED MODULE: external "lodash"
-var external_lodash_namespaceObject = window["lodash"];
+const external_wp_data_namespaceObject = window["wp"]["data"];
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/reducer.js
 /**
- * External dependencies
- */
-
-/**
  * WordPress dependencies
  */
 
@@ -119,306 +116,29 @@
  *
  * @return {Object} Updated state.
  */
-
-function formatTypes() {
-  let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-  let action = arguments.length > 1 ? arguments[1] : undefined;
-
+function formatTypes(state = {}, action) {
   switch (action.type) {
     case 'ADD_FORMAT_TYPES':
-      return { ...state,
-        ...(0,external_lodash_namespaceObject.keyBy)(action.formatTypes, 'name')
+      return {
+        ...state,
+        // Key format types by their name.
+        ...action.formatTypes.reduce((newFormatTypes, type) => ({
+          ...newFormatTypes,
+          [type.name]: type
+        }), {})
       };
-
     case 'REMOVE_FORMAT_TYPES':
-      return (0,external_lodash_namespaceObject.omit)(state, action.names);
+      return Object.fromEntries(Object.entries(state).filter(([key]) => !action.names.includes(key)));
   }
-
   return state;
 }
-/* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
+/* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
   formatTypes
 }));
 
-;// CONCATENATED MODULE: ./node_modules/rememo/es/rememo.js
-
-
-var LEAF_KEY, hasWeakMap;
-
-/**
- * Arbitrary value used as key for referencing cache object in WeakMap tree.
- *
- * @type {Object}
- */
-LEAF_KEY = {};
-
-/**
- * Whether environment supports WeakMap.
- *
- * @type {boolean}
- */
-hasWeakMap = typeof WeakMap !== 'undefined';
-
-/**
- * Returns the first argument as the sole entry in an array.
- *
- * @param {*} value Value to return.
- *
- * @return {Array} Value returned as entry in array.
- */
-function arrayOf( value ) {
-	return [ value ];
-}
-
-/**
- * Returns true if the value passed is object-like, or false otherwise. A value
- * is object-like if it can support property assignment, e.g. object or array.
- *
- * @param {*} value Value to test.
- *
- * @return {boolean} Whether value is object-like.
- */
-function isObjectLike( value ) {
-	return !! value && 'object' === typeof value;
-}
-
-/**
- * Creates and returns a new cache object.
- *
- * @return {Object} Cache object.
- */
-function createCache() {
-	var cache = {
-		clear: function() {
-			cache.head = null;
-		},
-	};
-
-	return cache;
-}
-
-/**
- * Returns true if entries within the two arrays are strictly equal by
- * reference from a starting index.
- *
- * @param {Array}  a         First array.
- * @param {Array}  b         Second array.
- * @param {number} fromIndex Index from which to start comparison.
- *
- * @return {boolean} Whether arrays are shallowly equal.
- */
-function isShallowEqual( a, b, fromIndex ) {
-	var i;
-
-	if ( a.length !== b.length ) {
-		return false;
-	}
-
-	for ( i = fromIndex; i < a.length; i++ ) {
-		if ( a[ i ] !== b[ i ] ) {
-			return false;
-		}
-	}
-
-	return true;
-}
-
-/**
- * Returns a memoized selector function. The getDependants function argument is
- * called before the memoized selector and is expected to return an immutable
- * reference or array of references on which the selector depends for computing
- * its own return value. The memoize cache is preserved only as long as those
- * dependant references remain the same. If getDependants returns a different
- * reference(s), the cache is cleared and the selector value regenerated.
- *
- * @param {Function} selector      Selector function.
- * @param {Function} getDependants Dependant getter returning an immutable
- *                                 reference or array of reference used in
- *                                 cache bust consideration.
- *
- * @return {Function} Memoized selector.
- */
-/* harmony default export */ function rememo(selector, getDependants ) {
-	var rootCache, getCache;
-
-	// Use object source as dependant if getter not provided
-	if ( ! getDependants ) {
-		getDependants = arrayOf;
-	}
-
-	/**
-	 * Returns the root cache. If WeakMap is supported, this is assigned to the
-	 * root WeakMap cache set, otherwise it is a shared instance of the default
-	 * cache object.
-	 *
-	 * @return {(WeakMap|Object)} Root cache object.
-	 */
-	function getRootCache() {
-		return rootCache;
-	}
-
-	/**
-	 * Returns the cache for a given dependants array. When possible, a WeakMap
-	 * will be used to create a unique cache for each set of dependants. This
-	 * is feasible due to the nature of WeakMap in allowing garbage collection
-	 * to occur on entries where the key object is no longer referenced. Since
-	 * WeakMap requires the key to be an object, this is only possible when the
-	 * dependant is object-like. The root cache is created as a hierarchy where
-	 * each top-level key is the first entry in a dependants set, the value a
-	 * WeakMap where each key is the next dependant, and so on. This continues
-	 * so long as the dependants are object-like. If no dependants are object-
-	 * like, then the cache is shared across all invocations.
-	 *
-	 * @see isObjectLike
-	 *
-	 * @param {Array} dependants Selector dependants.
-	 *
-	 * @return {Object} Cache object.
-	 */
-	function getWeakMapCache( dependants ) {
-		var caches = rootCache,
-			isUniqueByDependants = true,
-			i, dependant, map, cache;
-
-		for ( i = 0; i < dependants.length; i++ ) {
-			dependant = dependants[ i ];
-
-			// Can only compose WeakMap from object-like key.
-			if ( ! isObjectLike( dependant ) ) {
-				isUniqueByDependants = false;
-				break;
-			}
-
-			// Does current segment of cache already have a WeakMap?
-			if ( caches.has( dependant ) ) {
-				// Traverse into nested WeakMap.
-				caches = caches.get( dependant );
-			} else {
-				// Create, set, and traverse into a new one.
-				map = new WeakMap();
-				caches.set( dependant, map );
-				caches = map;
-			}
-		}
-
-		// We use an arbitrary (but consistent) object as key for the last item
-		// in the WeakMap to serve as our running cache.
-		if ( ! caches.has( LEAF_KEY ) ) {
-			cache = createCache();
-			cache.isUniqueByDependants = isUniqueByDependants;
-			caches.set( LEAF_KEY, cache );
-		}
-
-		return caches.get( LEAF_KEY );
-	}
-
-	// Assign cache handler by availability of WeakMap
-	getCache = hasWeakMap ? getWeakMapCache : getRootCache;
-
-	/**
-	 * Resets root memoization cache.
-	 */
-	function clear() {
-		rootCache = hasWeakMap ? new WeakMap() : createCache();
-	}
-
-	// eslint-disable-next-line jsdoc/check-param-names
-	/**
-	 * The augmented selector call, considering first whether dependants have
-	 * changed before passing it to underlying memoize function.
-	 *
-	 * @param {Object} source    Source object for derivation.
-	 * @param {...*}   extraArgs Additional arguments to pass to selector.
-	 *
-	 * @return {*} Selector result.
-	 */
-	function callSelector( /* source, ...extraArgs */ ) {
-		var len = arguments.length,
-			cache, node, i, args, dependants;
-
-		// Create copy of arguments (avoid leaking deoptimization).
-		args = new Array( len );
-		for ( i = 0; i < len; i++ ) {
-			args[ i ] = arguments[ i ];
-		}
-
-		dependants = getDependants.apply( null, args );
-		cache = getCache( dependants );
-
-		// If not guaranteed uniqueness by dependants (primitive type or lack
-		// of WeakMap support), shallow compare against last dependants and, if
-		// references have changed, destroy cache to recalculate result.
-		if ( ! cache.isUniqueByDependants ) {
-			if ( cache.lastDependants && ! isShallowEqual( dependants, cache.lastDependants, 0 ) ) {
-				cache.clear();
-			}
-
-			cache.lastDependants = dependants;
-		}
-
-		node = cache.head;
-		while ( node ) {
-			// Check whether node arguments match arguments
-			if ( ! isShallowEqual( node.args, args, 1 ) ) {
-				node = node.next;
-				continue;
-			}
-
-			// At this point we can assume we've found a match
-
-			// Surface matched node to head if not already
-			if ( node !== cache.head ) {
-				// Adjust siblings to point to each other.
-				node.prev.next = node.next;
-				if ( node.next ) {
-					node.next.prev = node.prev;
-				}
-
-				node.next = cache.head;
-				node.prev = null;
-				cache.head.prev = node;
-				cache.head = node;
-			}
-
-			// Return immediately
-			return node.val;
-		}
-
-		// No cached value found. Continue to insertion phase:
-
-		node = {
-			// Generate the result from original function
-			val: selector.apply( null, args ),
-		};
-
-		// Avoid including the source object in the cache.
-		args[ 0 ] = null;
-		node.args = args;
-
-		// Don't need to check whether node is already head, since it would
-		// have been returned above already if it was
-
-		// Shift existing head down list
-		if ( cache.head ) {
-			cache.head.prev = node;
-			node.next = cache.head;
-		}
-
-		cache.head = node;
-
-		return node.val;
-	}
-
-	callSelector.getDependants = getDependants;
-	callSelector.clear = clear;
-	clear();
-
-	return callSelector;
-}
-
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/selectors.js
 /**
- * External dependencies
+ * WordPress dependencies
  */
 
 
@@ -427,22 +147,76 @@
  *
  * @param {Object} state Data state.
  *
+ * @example
+ * ```js
+ * import { __, sprintf } from '@wordpress/i18n';
+ * import { store as richTextStore } from '@wordpress/rich-text';
+ * import { useSelect } from '@wordpress/data';
+ *
+ * const ExampleComponent = () => {
+ *    const { getFormatTypes } = useSelect(
+ *        ( select ) => select( richTextStore ),
+ *        []
+ *    );
+ *
+ *    const availableFormats = getFormatTypes();
+ *
+ *    return availableFormats ? (
+ *        <ul>
+ *            { availableFormats?.map( ( format ) => (
+ *                <li>{ format.name }</li>
+ *           ) ) }
+ *        </ul>
+ *    ) : (
+ *        __( 'No Formats available' )
+ *    );
+ * };
+ * ```
+ *
  * @return {Array} Format types.
  */
-
-const getFormatTypes = rememo(state => Object.values(state.formatTypes), state => [state.formatTypes]);
+const getFormatTypes = (0,external_wp_data_namespaceObject.createSelector)(state => Object.values(state.formatTypes), state => [state.formatTypes]);
+
 /**
  * Returns a format type by name.
  *
  * @param {Object} state Data state.
  * @param {string} name  Format type name.
  *
+ * @example
+ * ```js
+ * import { __, sprintf } from '@wordpress/i18n';
+ * import { store as richTextStore } from '@wordpress/rich-text';
+ * import { useSelect } from '@wordpress/data';
+ *
+ * const ExampleComponent = () => {
+ *    const { getFormatType } = useSelect(
+ *        ( select ) => select( richTextStore ),
+ *        []
+ *    );
+ *
+ *    const boldFormat = getFormatType( 'core/bold' );
+ *
+ *    return boldFormat ? (
+ *        <ul>
+ *            { Object.entries( boldFormat )?.map( ( [ key, value ] ) => (
+ *                <li>
+ *                    { key } : { value }
+ *                </li>
+ *           ) ) }
+ *       </ul>
+ *    ) : (
+ *        __( 'Not Found' )
+ *    ;
+ * };
+ * ```
+ *
  * @return {Object?} Format type.
  */
-
 function getFormatType(state, name) {
   return state.formatTypes[name];
 }
+
 /**
  * Gets the format type, if any, that can handle a bare element (without a
  * data-format-type attribute), given the tag name of this element.
@@ -450,73 +224,114 @@
  * @param {Object} state              Data state.
  * @param {string} bareElementTagName The tag name of the element to find a
  *                                    format type for.
+ *
+ * @example
+ * ```js
+ * import { __, sprintf } from '@wordpress/i18n';
+ * import { store as richTextStore } from '@wordpress/rich-text';
+ * import { useSelect } from '@wordpress/data';
+ *
+ * const ExampleComponent = () => {
+ *    const { getFormatTypeForBareElement } = useSelect(
+ *        ( select ) => select( richTextStore ),
+ *        []
+ *    );
+ *
+ *    const format = getFormatTypeForBareElement( 'strong' );
+ *
+ *    return format && <p>{ sprintf( __( 'Format name: %s' ), format.name ) }</p>;
+ * }
+ * ```
+ *
  * @return {?Object} Format type.
  */
-
 function getFormatTypeForBareElement(state, bareElementTagName) {
-  return (0,external_lodash_namespaceObject.find)(getFormatTypes(state), _ref => {
-    let {
-      className,
-      tagName
-    } = _ref;
+  const formatTypes = getFormatTypes(state);
+  return formatTypes.find(({
+    className,
+    tagName
+  }) => {
     return className === null && bareElementTagName === tagName;
+  }) || formatTypes.find(({
+    className,
+    tagName
+  }) => {
+    return className === null && '*' === tagName;
   });
 }
+
 /**
  * Gets the format type, if any, that can handle an element, given its classes.
  *
  * @param {Object} state            Data state.
  * @param {string} elementClassName The classes of the element to find a format
  *                                  type for.
+ *
+ * @example
+ * ```js
+ * import { __, sprintf } from '@wordpress/i18n';
+ * import { store as richTextStore } from '@wordpress/rich-text';
+ * import { useSelect } from '@wordpress/data';
+ *
+ * const ExampleComponent = () => {
+ *    const { getFormatTypeForClassName } = useSelect(
+ *        ( select ) => select( richTextStore ),
+ *        []
+ *    );
+ *
+ *    const format = getFormatTypeForClassName( 'has-inline-color' );
+ *
+ *    return format && <p>{ sprintf( __( 'Format name: %s' ), format.name ) }</p>;
+ * };
+ * ```
+ *
  * @return {?Object} Format type.
  */
-
 function getFormatTypeForClassName(state, elementClassName) {
-  return (0,external_lodash_namespaceObject.find)(getFormatTypes(state), _ref2 => {
-    let {
-      className
-    } = _ref2;
-
+  return getFormatTypes(state).find(({
+    className
+  }) => {
     if (className === null) {
       return false;
     }
-
     return ` ${elementClassName} `.indexOf(` ${className} `) >= 0;
   });
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/store/actions.js
 /**
- * External dependencies
- */
-
-/**
  * Returns an action object used in signalling that format types have been
  * added.
+ * Ignored from documentation as registerFormatType should be used instead from @wordpress/rich-text
+ *
+ * @ignore
  *
  * @param {Array|Object} formatTypes Format types received.
  *
  * @return {Object} Action object.
  */
-
 function addFormatTypes(formatTypes) {
   return {
     type: 'ADD_FORMAT_TYPES',
-    formatTypes: (0,external_lodash_namespaceObject.castArray)(formatTypes)
+    formatTypes: Array.isArray(formatTypes) ? formatTypes : [formatTypes]
   };
 }
+
 /**
  * Returns an action object used to remove a registered format type.
  *
+ * Ignored from documentation as unregisterFormatType should be used instead from @wordpress/rich-text
+ *
+ * @ignore
+ *
  * @param {string|Array} names Format name.
  *
  * @return {Object} Action object.
  */
-
 function removeFormatTypes(names) {
   return {
     type: 'REMOVE_FORMAT_TYPES',
-    names: (0,external_lodash_namespaceObject.castArray)(names)
+    names: Array.isArray(names) ? names : [names]
   };
 }
 
@@ -525,14 +340,15 @@
  * WordPress dependencies
  */
 
+
 /**
  * Internal dependencies
  */
 
 
 
-
 const STORE_NAME = 'core/rich-text';
+
 /**
  * Store definition for the rich-text namespace.
  *
@@ -540,7 +356,6 @@
  *
  * @type {Object}
  */
-
 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
   reducer: reducer,
   selectors: selectors_namespaceObject,
@@ -549,7 +364,7 @@
 (0,external_wp_data_namespaceObject.register)(store);
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-format-equal.js
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
+/** @typedef {import('./types').RichTextFormat} RichTextFormat */
 
 /**
  * Optimised equality check for format objects.
@@ -563,46 +378,41 @@
   // Both not defined.
   if (format1 === format2) {
     return true;
-  } // Either not defined.
-
-
+  }
+
+  // Either not defined.
   if (!format1 || !format2) {
     return false;
   }
-
   if (format1.type !== format2.type) {
     return false;
   }
-
   const attributes1 = format1.attributes;
-  const attributes2 = format2.attributes; // Both not defined.
-
+  const attributes2 = format2.attributes;
+
+  // Both not defined.
   if (attributes1 === attributes2) {
     return true;
-  } // Either not defined.
-
-
+  }
+
+  // Either not defined.
   if (!attributes1 || !attributes2) {
     return false;
   }
-
   const keys1 = Object.keys(attributes1);
   const keys2 = Object.keys(attributes2);
-
   if (keys1.length !== keys2.length) {
     return false;
   }
-
-  const length = keys1.length; // Optimise for speed.
-
+  const length = keys1.length;
+
+  // Optimise for speed.
   for (let i = 0; i < length; i++) {
     const name = keys1[i];
-
     if (attributes1[name] !== attributes2[name]) {
       return false;
     }
   }
-
   return true;
 }
 
@@ -611,7 +421,9 @@
  * Internal dependencies
  */
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Normalises formats: ensures subsequent adjacent equal formats have the same
@@ -621,17 +433,14 @@
  *
  * @return {RichTextValue} New value with normalised formats.
  */
-
 function normaliseFormats(value) {
   const newFormats = value.formats.slice();
   newFormats.forEach((formatsAtIndex, index) => {
     const formatsAtPreviousIndex = newFormats[index - 1];
-
     if (formatsAtPreviousIndex) {
       const newFormatsAtIndex = formatsAtIndex.slice();
       newFormatsAtIndex.forEach((format, formatIndex) => {
         const previousFormat = formatsAtPreviousIndex[formatIndex];
-
         if (isFormatEqual(format, previousFormat)) {
           newFormatsAtIndex[formatIndex] = previousFormat;
         }
@@ -639,30 +448,28 @@
       newFormats[index] = newFormatsAtIndex;
     }
   });
-  return { ...value,
+  return {
+    ...value,
     formats: newFormats
   };
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/apply-format.js
 /**
- * External dependencies
- */
-
-/**
  * Internal dependencies
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextFormat} RichTextFormat */
 
 function replace(array, index, value) {
   array = array.slice();
   array[index] = value;
   return array;
 }
+
 /**
  * Apply a format object to a Rich Text value from the given `startIndex` to the
  * given `endIndex`. Indices are retrieved from the selection if none are
@@ -675,33 +482,28 @@
  *
  * @return {RichTextValue} A new value with the format applied.
  */
-
-
-function applyFormat(value, format) {
-  let startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : value.start;
-  let endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : value.end;
+function applyFormat(value, format, startIndex = value.start, endIndex = value.end) {
   const {
     formats,
     activeFormats
   } = value;
-  const newFormats = formats.slice(); // The selection is collapsed.
-
+  const newFormats = formats.slice();
+
+  // The selection is collapsed.
   if (startIndex === endIndex) {
-    const startFormat = (0,external_lodash_namespaceObject.find)(newFormats[startIndex], {
-      type: format.type
-    }); // If the caret is at a format of the same type, expand start and end to
+    const startFormat = newFormats[startIndex]?.find(({
+      type
+    }) => type === format.type);
+
+    // If the caret is at a format of the same type, expand start and end to
     // the edges of the format. This is useful to apply new attributes.
-
     if (startFormat) {
       const index = newFormats[startIndex].indexOf(startFormat);
-
       while (newFormats[startIndex] && newFormats[startIndex][index] === startFormat) {
         newFormats[startIndex] = replace(newFormats[startIndex], index, format);
         startIndex--;
       }
-
       endIndex++;
-
       while (newFormats[endIndex] && newFormats[endIndex][index] === startFormat) {
         newFormats[endIndex] = replace(newFormats[endIndex], index, format);
         endIndex++;
@@ -710,17 +512,12 @@
   } else {
     // Determine the highest position the new format can be inserted at.
     let position = +Infinity;
-
     for (let index = startIndex; index < endIndex; index++) {
       if (newFormats[index]) {
-        newFormats[index] = newFormats[index].filter(_ref => {
-          let {
-            type
-          } = _ref;
-          return type !== format.type;
-        });
+        newFormats[index] = newFormats[index].filter(({
+          type
+        }) => type !== format.type);
         const length = newFormats[index].length;
-
         if (length < position) {
           position = length;
         }
@@ -729,20 +526,19 @@
         position = 0;
       }
     }
-
     for (let index = startIndex; index < endIndex; index++) {
       newFormats[index].splice(position, 0, format);
     }
   }
-
-  return normaliseFormats({ ...value,
+  return normaliseFormats({
+    ...value,
     formats: newFormats,
     // Always revise active formats. This serves as a placeholder for new
     // inputs with the format so new input appears with the format applied,
     // and ensures a format of the same type uses the latest values.
-    activeFormats: [...(0,external_lodash_namespaceObject.reject)(activeFormats, {
-      type: format.type
-    }), format]
+    activeFormats: [...(activeFormats?.filter(({
+      type
+    }) => type !== format.type) || []), format]
   });
 }
 
@@ -759,11 +555,9 @@
  *
  * @return {HTMLBodyElement} Body element with parsed HTML.
  */
-function createElement(_ref, html) {
-  let {
-    implementation
-  } = _ref;
-
+function createElement({
+  implementation
+}, html) {
   // Because `createHTMLDocument` is an expensive operation, and with this
   // function being internal to `rich-text` (full control in avoiding a risk
   // of asynchronous operations on the shared reference), a single document
@@ -771,29 +565,109 @@
   if (!createElement.body) {
     createElement.body = implementation.createHTMLDocument('').body;
   }
-
   createElement.body.innerHTML = html;
   return createElement.body;
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/special-characters.js
 /**
- * Line separator character, used for multiline text.
- */
-const LINE_SEPARATOR = '\u2028';
-/**
  * Object replacement character, used as a placeholder for objects.
  */
-
 const OBJECT_REPLACEMENT_CHARACTER = '\ufffc';
+
 /**
  * Zero width non-breaking space, used as padding in the editable DOM tree when
  * it is empty otherwise.
  */
-
 const ZWNBSP = '\ufeff';
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/create.js
+;// CONCATENATED MODULE: external ["wp","escapeHtml"]
+const external_wp_escapeHtml_namespaceObject = window["wp"]["escapeHtml"];
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-active-formats.js
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextFormatList} RichTextFormatList */
+
+/**
+ * Internal dependencies
+ */
+
+
+/**
+ * Gets the all format objects at the start of the selection.
+ *
+ * @param {RichTextValue} value                Value to inspect.
+ * @param {Array}         EMPTY_ACTIVE_FORMATS Array to return if there are no
+ *                                             active formats.
+ *
+ * @return {RichTextFormatList} Active format objects.
+ */
+function getActiveFormats(value, EMPTY_ACTIVE_FORMATS = []) {
+  const {
+    formats,
+    start,
+    end,
+    activeFormats
+  } = value;
+  if (start === undefined) {
+    return EMPTY_ACTIVE_FORMATS;
+  }
+  if (start === end) {
+    // For a collapsed caret, it is possible to override the active formats.
+    if (activeFormats) {
+      return activeFormats;
+    }
+    const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS;
+    const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS;
+
+    // By default, select the lowest amount of formats possible (which means
+    // the caret is positioned outside the format boundary). The user can
+    // then use arrow keys to define `activeFormats`.
+    if (formatsBefore.length < formatsAfter.length) {
+      return formatsBefore;
+    }
+    return formatsAfter;
+  }
+
+  // If there's no formats at the start index, there are not active formats.
+  if (!formats[start]) {
+    return EMPTY_ACTIVE_FORMATS;
+  }
+  const selectedFormats = formats.slice(start, end);
+
+  // Clone the formats so we're not mutating the live value.
+  const _activeFormats = [...selectedFormats[0]];
+  let i = selectedFormats.length;
+
+  // For performance reasons, start from the end where it's much quicker to
+  // realise that there are no active formats.
+  while (i--) {
+    const formatsAtIndex = selectedFormats[i];
+
+    // If we run into any index without formats, we're sure that there's no
+    // active formats.
+    if (!formatsAtIndex) {
+      return EMPTY_ACTIVE_FORMATS;
+    }
+    let ii = _activeFormats.length;
+
+    // Loop over the active formats and remove any that are not present at
+    // the current index.
+    while (ii--) {
+      const format = _activeFormats[ii];
+      if (!formatsAtIndex.find(_format => isFormatEqual(format, _format))) {
+        _activeFormats.splice(ii, 1);
+      }
+    }
+
+    // If there are no active formats, we can stop.
+    if (_activeFormats.length === 0) {
+      return EMPTY_ACTIVE_FORMATS;
+    }
+  }
+  return _activeFormats || EMPTY_ACTIVE_FORMATS;
+}
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-format-type.js
 /**
  * WordPress dependencies
  */
@@ -803,29 +677,448 @@
  */
 
 
+/** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */
+
+/**
+ * Returns a registered format type.
+ *
+ * @param {string} name Format name.
+ *
+ * @return {RichTextFormatType|undefined} Format type.
+ */
+function get_format_type_getFormatType(name) {
+  return (0,external_wp_data_namespaceObject.select)(store).getFormatType(name);
+}
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-tree.js
+/**
+ * Internal dependencies
+ */
+
+
+
+
+function restoreOnAttributes(attributes, isEditableTree) {
+  if (isEditableTree) {
+    return attributes;
+  }
+  const newAttributes = {};
+  for (const key in attributes) {
+    let newKey = key;
+    if (key.startsWith('data-disable-rich-text-')) {
+      newKey = key.slice('data-disable-rich-text-'.length);
+    }
+    newAttributes[newKey] = attributes[key];
+  }
+  return newAttributes;
+}
+
+/**
+ * Converts a format object to information that can be used to create an element
+ * from (type, attributes and object).
+ *
+ * @param {Object}  $1                        Named parameters.
+ * @param {string}  $1.type                   The format type.
+ * @param {string}  $1.tagName                The tag name.
+ * @param {Object}  $1.attributes             The format attributes.
+ * @param {Object}  $1.unregisteredAttributes The unregistered format
+ *                                            attributes.
+ * @param {boolean} $1.object                 Whether or not it is an object
+ *                                            format.
+ * @param {boolean} $1.boundaryClass          Whether or not to apply a boundary
+ *                                            class.
+ * @param {boolean} $1.isEditableTree
+ *
+ * @return {Object} Information to be used for element creation.
+ */
+function fromFormat({
+  type,
+  tagName,
+  attributes,
+  unregisteredAttributes,
+  object,
+  boundaryClass,
+  isEditableTree
+}) {
+  const formatType = get_format_type_getFormatType(type);
+  let elementAttributes = {};
+  if (boundaryClass && isEditableTree) {
+    elementAttributes['data-rich-text-format-boundary'] = 'true';
+  }
+  if (!formatType) {
+    if (attributes) {
+      elementAttributes = {
+        ...attributes,
+        ...elementAttributes
+      };
+    }
+    return {
+      type,
+      attributes: restoreOnAttributes(elementAttributes, isEditableTree),
+      object
+    };
+  }
+  elementAttributes = {
+    ...unregisteredAttributes,
+    ...elementAttributes
+  };
+  for (const name in attributes) {
+    const key = formatType.attributes ? formatType.attributes[name] : false;
+    if (key) {
+      elementAttributes[key] = attributes[name];
+    } else {
+      elementAttributes[name] = attributes[name];
+    }
+  }
+  if (formatType.className) {
+    if (elementAttributes.class) {
+      elementAttributes.class = `${formatType.className} ${elementAttributes.class}`;
+    } else {
+      elementAttributes.class = formatType.className;
+    }
+  }
+
+  // When a format is declared as non editable, make it non editable in the
+  // editor.
+  if (isEditableTree && formatType.contentEditable === false) {
+    elementAttributes.contenteditable = 'false';
+  }
+  return {
+    type: tagName || formatType.tagName,
+    object: formatType.object,
+    attributes: restoreOnAttributes(elementAttributes, isEditableTree)
+  };
+}
+
+/**
+ * Checks if both arrays of formats up until a certain index are equal.
+ *
+ * @param {Array}  a     Array of formats to compare.
+ * @param {Array}  b     Array of formats to compare.
+ * @param {number} index Index to check until.
+ */
+function isEqualUntil(a, b, index) {
+  do {
+    if (a[index] !== b[index]) {
+      return false;
+    }
+  } while (index--);
+  return true;
+}
+function toTree({
+  value,
+  preserveWhiteSpace,
+  createEmpty,
+  append,
+  getLastChild,
+  getParent,
+  isText,
+  getText,
+  remove,
+  appendText,
+  onStartIndex,
+  onEndIndex,
+  isEditableTree,
+  placeholder
+}) {
+  const {
+    formats,
+    replacements,
+    text,
+    start,
+    end
+  } = value;
+  const formatsLength = formats.length + 1;
+  const tree = createEmpty();
+  const activeFormats = getActiveFormats(value);
+  const deepestActiveFormat = activeFormats[activeFormats.length - 1];
+  let lastCharacterFormats;
+  let lastCharacter;
+  append(tree, '');
+  for (let i = 0; i < formatsLength; i++) {
+    const character = text.charAt(i);
+    const shouldInsertPadding = isEditableTree && (
+    // Pad the line if the line is empty.
+    !lastCharacter ||
+    // Pad the line if the previous character is a line break, otherwise
+    // the line break won't be visible.
+    lastCharacter === '\n');
+    const characterFormats = formats[i];
+    let pointer = getLastChild(tree);
+    if (characterFormats) {
+      characterFormats.forEach((format, formatIndex) => {
+        if (pointer && lastCharacterFormats &&
+        // Reuse the last element if all formats remain the same.
+        isEqualUntil(characterFormats, lastCharacterFormats, formatIndex)) {
+          pointer = getLastChild(pointer);
+          return;
+        }
+        const {
+          type,
+          tagName,
+          attributes,
+          unregisteredAttributes
+        } = format;
+        const boundaryClass = isEditableTree && format === deepestActiveFormat;
+        const parent = getParent(pointer);
+        const newNode = append(parent, fromFormat({
+          type,
+          tagName,
+          attributes,
+          unregisteredAttributes,
+          boundaryClass,
+          isEditableTree
+        }));
+        if (isText(pointer) && getText(pointer).length === 0) {
+          remove(pointer);
+        }
+        pointer = append(newNode, '');
+      });
+    }
+
+    // If there is selection at 0, handle it before characters are inserted.
+    if (i === 0) {
+      if (onStartIndex && start === 0) {
+        onStartIndex(tree, pointer);
+      }
+      if (onEndIndex && end === 0) {
+        onEndIndex(tree, pointer);
+      }
+    }
+    if (character === OBJECT_REPLACEMENT_CHARACTER) {
+      const replacement = replacements[i];
+      if (!replacement) {
+        continue;
+      }
+      const {
+        type,
+        attributes,
+        innerHTML
+      } = replacement;
+      const formatType = get_format_type_getFormatType(type);
+      if (!isEditableTree && type === 'script') {
+        pointer = append(getParent(pointer), fromFormat({
+          type: 'script',
+          isEditableTree
+        }));
+        append(pointer, {
+          html: decodeURIComponent(attributes['data-rich-text-script'])
+        });
+      } else if (formatType?.contentEditable === false) {
+        // For non editable formats, render the stored inner HTML.
+        pointer = append(getParent(pointer), fromFormat({
+          ...replacement,
+          isEditableTree,
+          boundaryClass: start === i && end === i + 1
+        }));
+        if (innerHTML) {
+          append(pointer, {
+            html: innerHTML
+          });
+        }
+      } else {
+        pointer = append(getParent(pointer), fromFormat({
+          ...replacement,
+          object: true,
+          isEditableTree
+        }));
+      }
+      // Ensure pointer is text node.
+      pointer = append(getParent(pointer), '');
+    } else if (!preserveWhiteSpace && character === '\n') {
+      pointer = append(getParent(pointer), {
+        type: 'br',
+        attributes: isEditableTree ? {
+          'data-rich-text-line-break': 'true'
+        } : undefined,
+        object: true
+      });
+      // Ensure pointer is text node.
+      pointer = append(getParent(pointer), '');
+    } else if (!isText(pointer)) {
+      pointer = append(getParent(pointer), character);
+    } else {
+      appendText(pointer, character);
+    }
+    if (onStartIndex && start === i + 1) {
+      onStartIndex(tree, pointer);
+    }
+    if (onEndIndex && end === i + 1) {
+      onEndIndex(tree, pointer);
+    }
+    if (shouldInsertPadding && i === text.length) {
+      append(getParent(pointer), ZWNBSP);
+      if (placeholder && text.length === 0) {
+        append(getParent(pointer), {
+          type: 'span',
+          attributes: {
+            'data-rich-text-placeholder': placeholder,
+            // Necessary to prevent the placeholder from catching
+            // selection and being editable.
+            style: 'pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;'
+          }
+        });
+      }
+    }
+    lastCharacterFormats = characterFormats;
+    lastCharacter = character;
+  }
+  return tree;
+}
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-html-string.js
+/**
+ * WordPress dependencies
+ */
 
 
 
 /**
- * @typedef {Object} RichTextFormat
- *
- * @property {string} type Format type.
+ * Internal dependencies
  */
 
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+
 /**
- * @typedef {Array<RichTextFormat>} RichTextFormatList
+ * Create an HTML string from a Rich Text value.
+ *
+ * @param {Object}        $1                      Named argements.
+ * @param {RichTextValue} $1.value                Rich text value.
+ * @param {boolean}       [$1.preserveWhiteSpace] Preserves newlines if true.
+ *
+ * @return {string} HTML string.
  */
+function toHTMLString({
+  value,
+  preserveWhiteSpace
+}) {
+  const tree = toTree({
+    value,
+    preserveWhiteSpace,
+    createEmpty,
+    append,
+    getLastChild,
+    getParent,
+    isText,
+    getText,
+    remove,
+    appendText
+  });
+  return createChildrenHTML(tree.children);
+}
+function createEmpty() {
+  return {};
+}
+function getLastChild({
+  children
+}) {
+  return children && children[children.length - 1];
+}
+function append(parent, object) {
+  if (typeof object === 'string') {
+    object = {
+      text: object
+    };
+  }
+  object.parent = parent;
+  parent.children = parent.children || [];
+  parent.children.push(object);
+  return object;
+}
+function appendText(object, text) {
+  object.text += text;
+}
+function getParent({
+  parent
+}) {
+  return parent;
+}
+function isText({
+  text
+}) {
+  return typeof text === 'string';
+}
+function getText({
+  text
+}) {
+  return text;
+}
+function remove(object) {
+  const index = object.parent.children.indexOf(object);
+  if (index !== -1) {
+    object.parent.children.splice(index, 1);
+  }
+  return object;
+}
+function createElementHTML({
+  type,
+  attributes,
+  object,
+  children
+}) {
+  let attributeString = '';
+  for (const key in attributes) {
+    if (!(0,external_wp_escapeHtml_namespaceObject.isValidAttributeName)(key)) {
+      continue;
+    }
+    attributeString += ` ${key}="${(0,external_wp_escapeHtml_namespaceObject.escapeAttribute)(attributes[key])}"`;
+  }
+  if (object) {
+    return `<${type}${attributeString}>`;
+  }
+  return `<${type}${attributeString}>${createChildrenHTML(children)}</${type}>`;
+}
+function createChildrenHTML(children = []) {
+  return children.map(child => {
+    if (child.html !== undefined) {
+      return child.html;
+    }
+    return child.text === undefined ? createElementHTML(child) : (0,external_wp_escapeHtml_namespaceObject.escapeEditableHTML)(child.text);
+  }).join('');
+}
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-text-content.js
+/**
+ * Internal dependencies
+ */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
- * @typedef {Object} RichTextValue
+ * Get the textual content of a Rich Text value. This is similar to
+ * `Element.textContent`.
+ *
+ * @param {RichTextValue} value Value to use.
  *
- * @property {string}                    text         Text.
- * @property {Array<RichTextFormatList>} formats      Formats.
- * @property {Array<RichTextFormat>}     replacements Replacements.
- * @property {number|undefined}          start        Selection start.
- * @property {number|undefined}          end          Selection end.
+ * @return {string} The text content.
+ */
+function getTextContent({
+  text
+}) {
+  return text.replace(OBJECT_REPLACEMENT_CHARACTER, '');
+}
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/create.js
+/**
+ * WordPress dependencies
  */
 
+
+/**
+ * Internal dependencies
+ */
+
+
+
+
+
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+
 function createEmptyValue() {
   return {
     formats: [],
@@ -833,89 +1126,171 @@
     text: ''
   };
 }
-
-function toFormat(_ref) {
-  let {
-    type,
-    attributes
-  } = _ref;
+function toFormat({
+  tagName,
+  attributes
+}) {
   let formatType;
-
   if (attributes && attributes.class) {
     formatType = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForClassName(attributes.class);
-
     if (formatType) {
       // Preserve any additional classes.
       attributes.class = ` ${attributes.class} `.replace(` ${formatType.className} `, ' ').trim();
-
       if (!attributes.class) {
         delete attributes.class;
       }
     }
   }
-
   if (!formatType) {
-    formatType = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForBareElement(type);
+    formatType = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForBareElement(tagName);
   }
-
   if (!formatType) {
     return attributes ? {
-      type,
+      type: tagName,
       attributes
     } : {
-      type
+      type: tagName
     };
   }
-
   if (formatType.__experimentalCreatePrepareEditableTree && !formatType.__experimentalCreateOnChangeEditableValue) {
     return null;
   }
-
   if (!attributes) {
     return {
-      type: formatType.name
+      formatType,
+      type: formatType.name,
+      tagName
     };
   }
-
   const registeredAttributes = {};
   const unregisteredAttributes = {};
-  const _attributes = { ...attributes
+  const _attributes = {
+    ...attributes
   };
-
   for (const key in formatType.attributes) {
     const name = formatType.attributes[key];
     registeredAttributes[key] = _attributes[name];
 
-    if (formatType.__unstableFilterAttributeValue) {
-      registeredAttributes[key] = formatType.__unstableFilterAttributeValue(key, registeredAttributes[key]);
-    } // delete the attribute and what's left is considered
+    // delete the attribute and what's left is considered
     // to be unregistered.
-
-
     delete _attributes[name];
-
     if (typeof registeredAttributes[key] === 'undefined') {
       delete registeredAttributes[key];
     }
   }
-
   for (const name in _attributes) {
     unregisteredAttributes[name] = attributes[name];
   }
-
+  if (formatType.contentEditable === false) {
+    delete unregisteredAttributes.contenteditable;
+  }
   return {
+    formatType,
     type: formatType.name,
+    tagName,
     attributes: registeredAttributes,
     unregisteredAttributes
   };
 }
+
+/**
+ * The RichTextData class is used to instantiate a wrapper around rich text
+ * values, with methods that can be used to transform or manipulate the data.
+ *
+ * - Create an empty instance: `new RichTextData()`.
+ * - Create one from an HTML string: `RichTextData.fromHTMLString(
+ *   '<em>hello</em>' )`.
+ * - Create one from a wrapper HTMLElement: `RichTextData.fromHTMLElement(
+ *   document.querySelector( 'p' ) )`.
+ * - Create one from plain text: `RichTextData.fromPlainText( '1\n2' )`.
+ * - Create one from a rich text value: `new RichTextData( { text: '...',
+ *   formats: [ ... ] } )`.
+ *
+ * @todo Add methods to manipulate the data, such as applyFormat, slice etc.
+ */
+class RichTextData {
+  #value;
+  static empty() {
+    return new RichTextData();
+  }
+  static fromPlainText(text) {
+    return new RichTextData(create({
+      text
+    }));
+  }
+  static fromHTMLString(html) {
+    return new RichTextData(create({
+      html
+    }));
+  }
+  static fromHTMLElement(htmlElement, options = {}) {
+    const {
+      preserveWhiteSpace = false
+    } = options;
+    const element = preserveWhiteSpace ? htmlElement : collapseWhiteSpace(htmlElement);
+    const richTextData = new RichTextData(create({
+      element
+    }));
+    Object.defineProperty(richTextData, 'originalHTML', {
+      value: htmlElement.innerHTML
+    });
+    return richTextData;
+  }
+  constructor(init = createEmptyValue()) {
+    this.#value = init;
+  }
+  toPlainText() {
+    return getTextContent(this.#value);
+  }
+  // We could expose `toHTMLElement` at some point as well, but we'd only use
+  // it internally.
+  toHTMLString({
+    preserveWhiteSpace
+  } = {}) {
+    return this.originalHTML || toHTMLString({
+      value: this.#value,
+      preserveWhiteSpace
+    });
+  }
+  valueOf() {
+    return this.toHTMLString();
+  }
+  toString() {
+    return this.toHTMLString();
+  }
+  toJSON() {
+    return this.toHTMLString();
+  }
+  get length() {
+    return this.text.length;
+  }
+  get formats() {
+    return this.#value.formats;
+  }
+  get replacements() {
+    return this.#value.replacements;
+  }
+  get text() {
+    return this.#value.text;
+  }
+}
+for (const name of Object.getOwnPropertyNames(String.prototype)) {
+  if (RichTextData.prototype.hasOwnProperty(name)) {
+    continue;
+  }
+  Object.defineProperty(RichTextData.prototype, name, {
+    value(...args) {
+      // Should we convert back to RichTextData?
+      return this.toHTMLString()[name](...args);
+    }
+  });
+}
+
 /**
  * Create a RichText value from an `Element` tree (DOM), an HTML string or a
  * plain text string, with optionally a `Range` object to set the selection. If
- * called without any input, an empty value will be created. If
- * `multilineTag` is provided, any content of direct children whose type matches
- * `multilineTag` will be separated by two newlines. The optional functions can
- * be used to filter out content.
+ * called without any input, an empty value will be created. The optional
+ * functions can be used to filter out content.
  *
  * A value will have the following shape, which you are strongly encouraged not
  * to modify without the use of helper functions:
@@ -942,30 +1317,23 @@
  * @param {string}  [$1.text]                     Text to create value from.
  * @param {string}  [$1.html]                     HTML to create value from.
  * @param {Range}   [$1.range]                    Range to create value from.
- * @param {string}  [$1.multilineTag]             Multiline tag if the structure is
- *                                                multiline.
- * @param {Array}   [$1.multilineWrapperTags]     Tags where lines can be found if
- *                                                nesting is possible.
- * @param {boolean} [$1.preserveWhiteSpace]       Whether or not to collapse white
- *                                                space characters.
  * @param {boolean} [$1.__unstableIsEditableTree]
- *
  * @return {RichTextValue} A rich text value.
  */
-
-
-function create() {
-  let {
-    element,
-    text,
-    html,
-    range,
-    multilineTag,
-    multilineWrapperTags,
-    __unstableIsEditableTree: isEditableTree,
-    preserveWhiteSpace
-  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
+function create({
+  element,
+  text,
+  html,
+  range,
+  __unstableIsEditableTree: isEditableTree
+} = {}) {
+  if (html instanceof RichTextData) {
+    return {
+      text: html.text,
+      formats: html.formats,
+      replacements: html.replacements
+    };
+  }
   if (typeof text === 'string' && text.length > 0) {
     return {
       formats: Array(text.length),
@@ -973,35 +1341,21 @@
       text
     };
   }
-
   if (typeof html === 'string' && html.length > 0) {
     // It does not matter which document this is, we're just using it to
     // parse.
     element = createElement(document, html);
   }
-
   if (typeof element !== 'object') {
     return createEmptyValue();
   }
-
-  if (!multilineTag) {
-    return createFromElement({
-      element,
-      range,
-      isEditableTree,
-      preserveWhiteSpace
-    });
-  }
-
-  return createFromMultilineElement({
+  return createFromElement({
     element,
     range,
-    multilineTag,
-    multilineWrapperTags,
-    isEditableTree,
-    preserveWhiteSpace
+    isEditableTree
   });
 }
+
 /**
  * Helper to accumulate the value's selection start and end from the current
  * node and range.
@@ -1011,12 +1365,10 @@
  * @param {Range}  range       Range to create value with.
  * @param {Object} value       Value that is being accumulated.
  */
-
 function accumulateSelection(accumulator, node, range, value) {
   if (!range) {
     return;
   }
-
   const {
     parentNode
   } = node;
@@ -1026,33 +1378,43 @@
     endContainer,
     endOffset
   } = range;
-  const currentLength = accumulator.text.length; // Selection can be extracted from value.
-
+  const currentLength = accumulator.text.length;
+
+  // Selection can be extracted from value.
   if (value.start !== undefined) {
-    accumulator.start = currentLength + value.start; // Range indicates that the current node has selection.
+    accumulator.start = currentLength + value.start;
+    // Range indicates that the current node has selection.
   } else if (node === startContainer && node.nodeType === node.TEXT_NODE) {
-    accumulator.start = currentLength + startOffset; // Range indicates that the current node is selected.
+    accumulator.start = currentLength + startOffset;
+    // Range indicates that the current node is selected.
   } else if (parentNode === startContainer && node === startContainer.childNodes[startOffset]) {
-    accumulator.start = currentLength; // Range indicates that the selection is after the current node.
+    accumulator.start = currentLength;
+    // Range indicates that the selection is after the current node.
   } else if (parentNode === startContainer && node === startContainer.childNodes[startOffset - 1]) {
-    accumulator.start = currentLength + value.text.length; // Fallback if no child inside handled the selection.
+    accumulator.start = currentLength + value.text.length;
+    // Fallback if no child inside handled the selection.
   } else if (node === startContainer) {
     accumulator.start = currentLength;
-  } // Selection can be extracted from value.
-
-
+  }
+
+  // Selection can be extracted from value.
   if (value.end !== undefined) {
-    accumulator.end = currentLength + value.end; // Range indicates that the current node has selection.
+    accumulator.end = currentLength + value.end;
+    // Range indicates that the current node has selection.
   } else if (node === endContainer && node.nodeType === node.TEXT_NODE) {
-    accumulator.end = currentLength + endOffset; // Range indicates that the current node is selected.
+    accumulator.end = currentLength + endOffset;
+    // Range indicates that the current node is selected.
   } else if (parentNode === endContainer && node === endContainer.childNodes[endOffset - 1]) {
-    accumulator.end = currentLength + value.text.length; // Range indicates that the selection is before the current node.
+    accumulator.end = currentLength + value.text.length;
+    // Range indicates that the selection is before the current node.
   } else if (parentNode === endContainer && node === endContainer.childNodes[endOffset]) {
-    accumulator.end = currentLength; // Fallback if no child inside handled the selection.
+    accumulator.end = currentLength;
+    // Fallback if no child inside handled the selection.
   } else if (node === endContainer) {
     accumulator.end = currentLength + endOffset;
   }
 }
+
 /**
  * Adjusts the start and end offsets from a range based on a text filter.
  *
@@ -1062,13 +1424,10 @@
  *
  * @return {Object|void} Object containing range properties.
  */
-
-
 function filterRange(node, range, filter) {
   if (!range) {
     return;
   }
-
   const {
     startContainer,
     endContainer
@@ -1077,15 +1436,12 @@
     startOffset,
     endOffset
   } = range;
-
   if (node === startContainer) {
     startOffset = filter(node.nodeValue.slice(0, startOffset)).length;
   }
-
   if (node === endContainer) {
     endOffset = filter(node.nodeValue.slice(0, endOffset)).length;
   }
-
   return {
     startContainer,
     startOffset,
@@ -1093,109 +1449,124 @@
     endOffset
   };
 }
+
 /**
  * Collapse any whitespace used for HTML formatting to one space character,
  * because it will also be displayed as such by the browser.
  *
- * @param {string} string
+ * We need to strip it from the content because we use white-space: pre-wrap for
+ * displaying editable rich text. Without using white-space: pre-wrap, the
+ * browser will litter the content with non breaking spaces, among other issues.
+ * See packages/rich-text/src/component/use-default-style.js.
+ *
+ * @see
+ * https://developer.mozilla.org/en-US/docs/Web/CSS/white-space-collapse#collapsing_of_white_space
+ *
+ * @param {HTMLElement} element
+ * @param {boolean}     isRoot
+ *
+ * @return {HTMLElement} New element with collapsed whitespace.
  */
-
-
-function collapseWhiteSpace(string) {
-  return string.replace(/[\n\r\t]+/g, ' ');
+function collapseWhiteSpace(element, isRoot = true) {
+  const clone = element.cloneNode(true);
+  clone.normalize();
+  Array.from(clone.childNodes).forEach((node, i, nodes) => {
+    if (node.nodeType === node.TEXT_NODE) {
+      let newNodeValue = node.nodeValue;
+      if (/[\n\t\r\f]/.test(newNodeValue)) {
+        newNodeValue = newNodeValue.replace(/[\n\t\r\f]+/g, ' ');
+      }
+      if (newNodeValue.indexOf('  ') !== -1) {
+        newNodeValue = newNodeValue.replace(/ {2,}/g, ' ');
+      }
+      if (i === 0 && newNodeValue.startsWith(' ')) {
+        newNodeValue = newNodeValue.slice(1);
+      } else if (isRoot && i === nodes.length - 1 && newNodeValue.endsWith(' ')) {
+        newNodeValue = newNodeValue.slice(0, -1);
+      }
+      node.nodeValue = newNodeValue;
+    } else if (node.nodeType === node.ELEMENT_NODE) {
+      collapseWhiteSpace(node, false);
+    }
+  });
+  return clone;
 }
+
 /**
- * Removes reserved characters used by rich-text (zero width non breaking spaces added by `toTree` and object replacement characters).
+ * We need to normalise line breaks to `\n` so they are consistent across
+ * platforms and serialised properly. Not removing \r would cause it to
+ * linger and result in double line breaks when whitespace is preserved.
+ */
+const CARRIAGE_RETURN = '\r';
+
+/**
+ * Removes reserved characters used by rich-text (zero width non breaking spaces
+ * added by `toTree` and object replacement characters).
  *
  * @param {string} string
  */
-
-
 function removeReservedCharacters(string) {
-  // with the global flag, note that we should create a new regex each time OR reset lastIndex state.
-  return string.replace(new RegExp(`[${ZWNBSP}${OBJECT_REPLACEMENT_CHARACTER}]`, 'gu'), '');
+  // with the global flag, note that we should create a new regex each time OR
+  // reset lastIndex state.
+  return string.replace(new RegExp(`[${ZWNBSP}${OBJECT_REPLACEMENT_CHARACTER}${CARRIAGE_RETURN}]`, 'gu'), '');
 }
+
 /**
  * Creates a Rich Text value from a DOM element and range.
  *
- * @param {Object}  $1                        Named argements.
- * @param {Element} [$1.element]              Element to create value from.
- * @param {Range}   [$1.range]                Range to create value from.
- * @param {string}  [$1.multilineTag]         Multiline tag if the structure is
- *                                            multiline.
- * @param {Array}   [$1.multilineWrapperTags] Tags where lines can be found if
- *                                            nesting is possible.
- * @param {boolean} [$1.preserveWhiteSpace]   Whether or not to collapse white
- *                                            space characters.
- * @param {Array}   [$1.currentWrapperTags]
+ * @param {Object}  $1                  Named argements.
+ * @param {Element} [$1.element]        Element to create value from.
+ * @param {Range}   [$1.range]          Range to create value from.
  * @param {boolean} [$1.isEditableTree]
  *
  * @return {RichTextValue} A rich text value.
  */
-
-function createFromElement(_ref2) {
-  let {
-    element,
-    range,
-    multilineTag,
-    multilineWrapperTags,
-    currentWrapperTags = [],
-    isEditableTree,
-    preserveWhiteSpace
-  } = _ref2;
+function createFromElement({
+  element,
+  range,
+  isEditableTree
+}) {
   const accumulator = createEmptyValue();
-
   if (!element) {
     return accumulator;
   }
-
   if (!element.hasChildNodes()) {
     accumulateSelection(accumulator, element, range, createEmptyValue());
     return accumulator;
   }
-
-  const length = element.childNodes.length; // Optimise for speed.
-
+  const length = element.childNodes.length;
+
+  // Optimise for speed.
   for (let index = 0; index < length; index++) {
     const node = element.childNodes[index];
-    const type = node.nodeName.toLowerCase();
-
+    const tagName = node.nodeName.toLowerCase();
     if (node.nodeType === node.TEXT_NODE) {
-      let filter = removeReservedCharacters;
-
-      if (!preserveWhiteSpace) {
-        filter = string => removeReservedCharacters(collapseWhiteSpace(string));
-      }
-
-      const text = filter(node.nodeValue);
-      range = filterRange(node, range, filter);
+      const text = removeReservedCharacters(node.nodeValue);
+      range = filterRange(node, range, removeReservedCharacters);
       accumulateSelection(accumulator, node, range, {
         text
-      }); // Create a sparse array of the same length as `text`, in which
+      });
+      // Create a sparse array of the same length as `text`, in which
       // formats can be added.
-
       accumulator.formats.length += text.length;
       accumulator.replacements.length += text.length;
       accumulator.text += text;
       continue;
     }
-
     if (node.nodeType !== node.ELEMENT_NODE) {
       continue;
     }
-
-    if (isEditableTree && ( // Ignore any placeholders.
-    node.getAttribute('data-rich-text-placeholder') || // Ignore any line breaks that are not inserted by us.
-    type === 'br' && !node.getAttribute('data-rich-text-line-break'))) {
+    if (isEditableTree &&
+    // Ignore any line breaks that are not inserted by us.
+    tagName === 'br' && !node.getAttribute('data-rich-text-line-break')) {
       accumulateSelection(accumulator, node, range, createEmptyValue());
       continue;
     }
-
-    if (type === 'script') {
+    if (tagName === 'script') {
       const value = {
         formats: [,],
         replacements: [{
-          type,
+          type: tagName,
           attributes: {
             'data-rich-text-script': node.getAttribute('data-rich-text-script') || encodeURIComponent(node.innerHTML)
           }
@@ -1206,48 +1577,48 @@
       mergePair(accumulator, value);
       continue;
     }
-
-    if (type === 'br') {
+    if (tagName === 'br') {
       accumulateSelection(accumulator, node, range, createEmptyValue());
       mergePair(accumulator, create({
         text: '\n'
       }));
       continue;
     }
-
     const format = toFormat({
-      type,
+      tagName,
       attributes: getAttributes({
         element: node
       })
     });
 
-    if (multilineWrapperTags && multilineWrapperTags.indexOf(type) !== -1) {
-      const value = createFromMultilineElement({
-        element: node,
-        range,
-        multilineTag,
-        multilineWrapperTags,
-        currentWrapperTags: [...currentWrapperTags, format],
-        isEditableTree,
-        preserveWhiteSpace
+    // When a format type is declared as not editable, replace it with an
+    // object replacement character and preserve the inner HTML.
+    if (format?.formatType?.contentEditable === false) {
+      delete format.formatType;
+      accumulateSelection(accumulator, node, range, createEmptyValue());
+      mergePair(accumulator, {
+        formats: [,],
+        replacements: [{
+          ...format,
+          innerHTML: node.innerHTML
+        }],
+        text: OBJECT_REPLACEMENT_CHARACTER
       });
-      accumulateSelection(accumulator, node, range, value);
-      mergePair(accumulator, value);
       continue;
     }
-
+    if (format) {
+      delete format.formatType;
+    }
     const value = createFromElement({
       element: node,
       range,
-      multilineTag,
-      multilineWrapperTags,
-      isEditableTree,
-      preserveWhiteSpace
+      isEditableTree
     });
     accumulateSelection(accumulator, node, range, value);
 
-    if (!format) {
+    // Ignore any placeholders, but keep their content since the browser
+    // might insert text inside them when the editable element is flex.
+    if (!format || node.getAttribute('data-rich-text-placeholder')) {
       mergePair(accumulator, value);
     } else if (value.text.length === 0) {
       if (format.attributes) {
@@ -1264,94 +1635,24 @@
         if (mergeFormats.formats === formats) {
           return mergeFormats.newFormats;
         }
-
         const newFormats = formats ? [format, ...formats] : [format];
         mergeFormats.formats = formats;
         mergeFormats.newFormats = newFormats;
         return newFormats;
-      } // Since the formats parameter can be `undefined`, preset
+      }
+
+      // Since the formats parameter can be `undefined`, preset
       // `mergeFormats` with a new reference.
-
-
       mergeFormats.newFormats = [format];
-      mergePair(accumulator, { ...value,
+      mergePair(accumulator, {
+        ...value,
         formats: Array.from(value.formats, mergeFormats)
       });
     }
   }
-
   return accumulator;
 }
-/**
- * Creates a rich text value from a DOM element and range that should be
- * multiline.
- *
- * @param {Object}  $1                        Named argements.
- * @param {Element} [$1.element]              Element to create value from.
- * @param {Range}   [$1.range]                Range to create value from.
- * @param {string}  [$1.multilineTag]         Multiline tag if the structure is
- *                                            multiline.
- * @param {Array}   [$1.multilineWrapperTags] Tags where lines can be found if
- *                                            nesting is possible.
- * @param {Array}   [$1.currentWrapperTags]   Whether to prepend a line
- *                                            separator.
- * @param {boolean} [$1.preserveWhiteSpace]   Whether or not to collapse white
- *                                            space characters.
- * @param {boolean} [$1.isEditableTree]
- *
- * @return {RichTextValue} A rich text value.
- */
-
-
-function createFromMultilineElement(_ref3) {
-  let {
-    element,
-    range,
-    multilineTag,
-    multilineWrapperTags,
-    currentWrapperTags = [],
-    isEditableTree,
-    preserveWhiteSpace
-  } = _ref3;
-  const accumulator = createEmptyValue();
-
-  if (!element || !element.hasChildNodes()) {
-    return accumulator;
-  }
-
-  const length = element.children.length; // Optimise for speed.
-
-  for (let index = 0; index < length; index++) {
-    const node = element.children[index];
-
-    if (node.nodeName.toLowerCase() !== multilineTag) {
-      continue;
-    }
-
-    const value = createFromElement({
-      element: node,
-      range,
-      multilineTag,
-      multilineWrapperTags,
-      currentWrapperTags,
-      isEditableTree,
-      preserveWhiteSpace
-    }); // Multiline value text should be separated by a line separator.
-
-    if (index !== 0 || currentWrapperTags.length > 0) {
-      mergePair(accumulator, {
-        formats: [,],
-        replacements: currentWrapperTags.length > 0 ? [currentWrapperTags] : [,],
-        text: LINE_SEPARATOR
-      });
-    }
-
-    accumulateSelection(accumulator, node, range, value);
-    mergePair(accumulator, value);
-  }
-
-  return accumulator;
-}
+
 /**
  * Gets the attributes of an element in object shape.
  *
@@ -1361,35 +1662,28 @@
  * @return {Object|void} Attribute object or `undefined` if the element has no
  *                       attributes.
  */
-
-
-function getAttributes(_ref4) {
-  let {
-    element
-  } = _ref4;
-
+function getAttributes({
+  element
+}) {
   if (!element.hasAttributes()) {
     return;
   }
-
   const length = element.attributes.length;
-  let accumulator; // Optimise for speed.
-
+  let accumulator;
+
+  // Optimise for speed.
   for (let i = 0; i < length; i++) {
     const {
       name,
       value
     } = element.attributes[i];
-
     if (name.indexOf('data-rich-text-') === 0) {
       continue;
     }
-
     const safeName = /^on/i.test(name) ? 'data-disable-rich-text-' + name : name;
     accumulator = accumulator || {};
     accumulator[safeName] = value;
   }
-
   return accumulator;
 }
 
@@ -1399,7 +1693,9 @@
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Concats a pair of rich text values. Not that this mutates `a` and does NOT
@@ -1410,13 +1706,13 @@
  *
  * @return {Object} `a`, mutated.
  */
-
 function mergePair(a, b) {
   a.formats = a.formats.concat(b.formats);
   a.replacements = a.replacements.concat(b.replacements);
   a.text += b.text;
   return a;
 }
+
 /**
  * Combine all Rich Text values into one. This is similar to
  * `String.prototype.concat`.
@@ -1425,76 +1721,18 @@
  *
  * @return {RichTextValue} A new value combining all given records.
  */
-
-function concat() {
-  for (var _len = arguments.length, values = new Array(_len), _key = 0; _key < _len; _key++) {
-    values[_key] = arguments[_key];
-  }
-
+function concat(...values) {
   return normaliseFormats(values.reduce(mergePair, create()));
 }
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-active-formats.js
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormatList} RichTextFormatList */
-
-/**
- * Gets the all format objects at the start of the selection.
- *
- * @param {RichTextValue} value                Value to inspect.
- * @param {Array}         EMPTY_ACTIVE_FORMATS Array to return if there are no
- *                                             active formats.
- *
- * @return {RichTextFormatList} Active format objects.
- */
-function getActiveFormats(_ref) {
-  let {
-    formats,
-    start,
-    end,
-    activeFormats
-  } = _ref;
-  let EMPTY_ACTIVE_FORMATS = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
-
-  if (start === undefined) {
-    return EMPTY_ACTIVE_FORMATS;
-  }
-
-  if (start === end) {
-    // For a collapsed caret, it is possible to override the active formats.
-    if (activeFormats) {
-      return activeFormats;
-    }
-
-    const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS;
-    const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS; // By default, select the lowest amount of formats possible (which means
-    // the caret is positioned outside the format boundary). The user can
-    // then use arrow keys to define `activeFormats`.
-
-    if (formatsBefore.length < formatsAfter.length) {
-      return formatsBefore;
-    }
-
-    return formatsAfter;
-  }
-
-  return formats[start] || EMPTY_ACTIVE_FORMATS;
-}
-
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-active-format.js
 /**
- * External dependencies
- */
-
-/**
  * Internal dependencies
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextFormat} RichTextFormat */
 
 /**
  * Gets the format object by type at the start of the selection. This can be
@@ -1508,11 +1746,10 @@
  * @return {RichTextFormat|undefined} Active format object of the specified
  *                                    type, or undefined.
  */
-
 function getActiveFormat(value, formatType) {
-  return (0,external_lodash_namespaceObject.find)(getActiveFormats(value), {
-    type: formatType
-  });
+  return getActiveFormats(value).find(({
+    type
+  }) => type === formatType);
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-active-object.js
@@ -1520,9 +1757,10 @@
  * Internal dependencies
  */
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextFormat} RichTextFormat */
 
 /**
  * Gets the active object, if there is any.
@@ -1531,172 +1769,46 @@
  *
  * @return {RichTextFormat|void} Active object, or undefined.
  */
-
-function getActiveObject(_ref) {
-  let {
-    start,
-    end,
-    replacements,
-    text
-  } = _ref;
-
+function getActiveObject({
+  start,
+  end,
+  replacements,
+  text
+}) {
   if (start + 1 !== end || text[start] !== OBJECT_REPLACEMENT_CHARACTER) {
     return;
   }
-
   return replacements[start];
 }
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-text-content.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Get the textual content of a Rich Text value. This is similar to
- * `Element.textContent`.
- *
- * @param {RichTextValue} value Value to use.
- *
- * @return {string} The text content.
- */
-
-function getTextContent(_ref) {
-  let {
-    text
-  } = _ref;
-  return text.replace(new RegExp(OBJECT_REPLACEMENT_CHARACTER, 'g'), '').replace(new RegExp(LINE_SEPARATOR, 'g'), '\n');
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-line-index.js
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-collapsed.js
 /**
  * Internal dependencies
  */
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Gets the currently selected line index, or the first line index if the
- * selection spans over multiple items.
- *
- * @param {RichTextValue} value      Value to get the line index from.
- * @param {boolean}       startIndex Optional index that should be contained by
- *                                   the line. Defaults to the selection start
- *                                   of the value.
- *
- * @return {number|void} The line index. Undefined if not found.
- */
-
-function getLineIndex(_ref) {
-  let {
-    start,
-    text
-  } = _ref;
-  let startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : start;
-  let index = startIndex;
-
-  while (index--) {
-    if (text[index] === LINE_SEPARATOR) {
-      return index;
-    }
-  }
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-list-root-selected.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Whether or not the root list is selected.
- *
- * @param {RichTextValue} value The value to check.
- *
- * @return {boolean} True if the root list or nothing is selected, false if an
- *                   inner list is selected.
- */
-
-function isListRootSelected(value) {
-  const {
-    replacements,
-    start
-  } = value;
-  const lineIndex = getLineIndex(value, start);
-  const replacement = replacements[lineIndex];
-  return !replacement || replacement.length < 1;
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-active-list-type.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Whether or not the selected list has the given tag name.
- *
- * @param {RichTextValue} value    The value to check.
- * @param {string}        type     The tag name the list should have.
- * @param {string}        rootType The current root tag name, to compare with in
- *                                 case nothing is selected.
- *
- * @return {boolean} True if the current list type matches `type`, false if not.
- */
-
-function isActiveListType(value, type, rootType) {
-  const {
-    replacements,
-    start
-  } = value;
-  const lineIndex = getLineIndex(value, start);
-  const replacement = replacements[lineIndex];
-
-  if (!replacement || replacement.length === 0) {
-    return type === rootType;
-  }
-
-  const lastFormat = replacement[replacement.length - 1];
-  return lastFormat.type === type;
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-collapsed.js
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
 /**
  * Check if the selection of a Rich Text value is collapsed or not. Collapsed
  * means that no characters are selected, but there is a caret present. If there
  * is no selection, `undefined` will be returned. This is similar to
  * `window.getSelection().isCollapsed()`.
  *
- * @param {RichTextValue} value The rich text value to check.
- *
- * @return {boolean|undefined} True if the selection is collapsed, false if not,
- *                             undefined if there is no selection.
+ * @param props       The rich text value to check.
+ * @param props.start
+ * @param props.end
+ * @return True if the selection is collapsed, false if not, undefined if there is no selection.
  */
-function isCollapsed(_ref) {
-  let {
-    start,
-    end
-  } = _ref;
-
+function isCollapsed({
+  start,
+  end
+}) {
   if (start === undefined || end === undefined) {
     return;
   }
-
   return start === end;
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-empty.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Check if a Rich Text value is Empty, meaning it contains no text or any
@@ -1706,47 +1818,11 @@
  *
  * @return {boolean} True if the value is empty, false if not.
  */
-
-function isEmpty(_ref) {
-  let {
-    text
-  } = _ref;
+function isEmpty({
+  text
+}) {
   return text.length === 0;
 }
-/**
- * Check if the current collapsed selection is on an empty line in case of a
- * multiline value.
- *
- * @param {RichTextValue} value Value te check.
- *
- * @return {boolean} True if the line is empty, false if not.
- */
-
-function isEmptyLine(_ref2) {
-  let {
-    text,
-    start,
-    end
-  } = _ref2;
-
-  if (start !== end) {
-    return false;
-  }
-
-  if (text.length === 0) {
-    return true;
-  }
-
-  if (start === 0 && text.slice(0, 1) === LINE_SEPARATOR) {
-    return true;
-  }
-
-  if (start === text.length && text.slice(-1) === LINE_SEPARATOR) {
-    return true;
-  }
-
-  return text.slice(start - 1, end + 1) === `${LINE_SEPARATOR}${LINE_SEPARATOR}`;
-}
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/join.js
 /**
@@ -1754,7 +1830,9 @@
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Combine an array of Rich Text values into one, optionally separated by
@@ -1766,28 +1844,21 @@
  *
  * @return {RichTextValue} A new combined value.
  */
-
-function join(values) {
-  let separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
-
+function join(values, separator = '') {
   if (typeof separator === 'string') {
     separator = create({
       text: separator
     });
   }
-
-  return normaliseFormats(values.reduce((accumlator, _ref) => {
-    let {
-      formats,
-      replacements,
-      text
-    } = _ref;
-    return {
-      formats: accumlator.formats.concat(separator.formats, formats),
-      replacements: accumlator.replacements.concat(separator.replacements, replacements),
-      text: accumlator.text + separator.text + text
-    };
-  }));
+  return normaliseFormats(values.reduce((accumlator, {
+    formats,
+    replacements,
+    text
+  }) => ({
+    formats: accumlator.formats.concat(separator.formats, formats),
+    replacements: accumlator.replacements.concat(separator.replacements, replacements),
+    text: accumlator.text + separator.text + text
+  })));
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/register-format-type.js
@@ -1799,18 +1870,18 @@
  * Internal dependencies
  */
 
-
 /**
  * @typedef {Object} WPFormat
  *
- * @property {string}   name        A string identifying the format. Must be
- *                                  unique across all registered formats.
- * @property {string}   tagName     The HTML tag this format will wrap the
- *                                  selection with.
- * @property {string}   [className] A class to match the format.
- * @property {string}   title       Name of the format.
- * @property {Function} edit        Should return a component for the user to
- *                                  interact with the new registered format.
+ * @property {string}        name        A string identifying the format. Must be
+ *                                       unique across all registered formats.
+ * @property {string}        tagName     The HTML tag this format will wrap the
+ *                                       selection with.
+ * @property {boolean}       interactive Whether format makes content interactive or not.
+ * @property {string | null} [className] A class to match the format.
+ * @property {string}        title       Name of the format.
+ * @property {Function}      edit        Should return a component for the user to
+ *                                       interact with the new registered format.
  */
 
 /**
@@ -1823,89 +1894,72 @@
  * @return {WPFormat|undefined} The format, if it has been successfully
  *                              registered; otherwise `undefined`.
  */
-
 function registerFormatType(name, settings) {
   settings = {
     name,
     ...settings
   };
-
   if (typeof settings.name !== 'string') {
     window.console.error('Format names must be strings.');
     return;
   }
-
   if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(settings.name)) {
     window.console.error('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');
     return;
   }
-
   if ((0,external_wp_data_namespaceObject.select)(store).getFormatType(settings.name)) {
     window.console.error('Format "' + settings.name + '" is already registered.');
     return;
   }
-
   if (typeof settings.tagName !== 'string' || settings.tagName === '') {
     window.console.error('Format tag names must be a string.');
     return;
   }
-
   if ((typeof settings.className !== 'string' || settings.className === '') && settings.className !== null) {
     window.console.error('Format class names must be a string, or null to handle bare elements.');
     return;
   }
-
-  if (!/^[_a-zA-Z]+[a-zA-Z0-9-]*$/.test(settings.className)) {
-    window.console.error('A class name must begin with a letter, followed by any number of hyphens, letters, or numbers.');
+  if (!/^[_a-zA-Z]+[a-zA-Z0-9_-]*$/.test(settings.className)) {
+    window.console.error('A class name must begin with a letter, followed by any number of hyphens, underscores, letters, or numbers.');
     return;
   }
-
   if (settings.className === null) {
     const formatTypeForBareElement = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForBareElement(settings.tagName);
-
-    if (formatTypeForBareElement) {
+    if (formatTypeForBareElement && formatTypeForBareElement.name !== 'core/unknown') {
       window.console.error(`Format "${formatTypeForBareElement.name}" is already registered to handle bare tag name "${settings.tagName}".`);
       return;
     }
   } else {
     const formatTypeForClassName = (0,external_wp_data_namespaceObject.select)(store).getFormatTypeForClassName(settings.className);
-
     if (formatTypeForClassName) {
       window.console.error(`Format "${formatTypeForClassName.name}" is already registered to handle class name "${settings.className}".`);
       return;
     }
   }
-
   if (!('title' in settings) || settings.title === '') {
     window.console.error('The format "' + settings.name + '" must have a title.');
     return;
   }
-
   if ('keywords' in settings && settings.keywords.length > 3) {
     window.console.error('The format "' + settings.name + '" can have a maximum of 3 keywords.');
     return;
   }
-
   if (typeof settings.title !== 'string') {
     window.console.error('Format titles must be strings.');
     return;
   }
-
   (0,external_wp_data_namespaceObject.dispatch)(store).addFormatTypes(settings);
   return settings;
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/remove-format.js
 /**
- * External dependencies
- */
-
-/**
  * Internal dependencies
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Remove any format object from a Rich Text value by type from the given
@@ -1919,31 +1973,26 @@
  *
  * @return {RichTextValue} A new value with the format applied.
  */
-
-function removeFormat(value, formatType) {
-  let startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : value.start;
-  let endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : value.end;
+function removeFormat(value, formatType, startIndex = value.start, endIndex = value.end) {
   const {
     formats,
     activeFormats
   } = value;
-  const newFormats = formats.slice(); // If the selection is collapsed, expand start and end to the edges of the
+  const newFormats = formats.slice();
+
+  // If the selection is collapsed, expand start and end to the edges of the
   // format.
-
   if (startIndex === endIndex) {
-    const format = (0,external_lodash_namespaceObject.find)(newFormats[startIndex], {
-      type: formatType
-    });
-
+    const format = newFormats[startIndex]?.find(({
+      type
+    }) => type === formatType);
     if (format) {
-      while ((0,external_lodash_namespaceObject.find)(newFormats[startIndex], format)) {
+      while (newFormats[startIndex]?.find(newFormat => newFormat === format)) {
         filterFormats(newFormats, startIndex, formatType);
         startIndex--;
       }
-
       endIndex++;
-
-      while ((0,external_lodash_namespaceObject.find)(newFormats[endIndex], format)) {
+      while (newFormats[endIndex]?.find(newFormat => newFormat === format)) {
         filterFormats(newFormats, endIndex, formatType);
         endIndex++;
       }
@@ -1955,23 +2004,18 @@
       }
     }
   }
-
-  return normaliseFormats({ ...value,
+  return normaliseFormats({
+    ...value,
     formats: newFormats,
-    activeFormats: (0,external_lodash_namespaceObject.reject)(activeFormats, {
-      type: formatType
-    })
+    activeFormats: activeFormats?.filter(({
+      type
+    }) => type !== formatType) || []
   });
 }
-
 function filterFormats(formats, index, formatType) {
-  const newFormats = formats[index].filter(_ref => {
-    let {
-      type
-    } = _ref;
-    return type !== formatType;
-  });
-
+  const newFormats = formats[index].filter(({
+    type
+  }) => type !== formatType);
   if (newFormats.length) {
     formats[index] = newFormats;
   } else {
@@ -1985,7 +2029,9 @@
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Insert a Rich Text value, an HTML string, or a plain text string, into a
@@ -2000,22 +2046,17 @@
  *
  * @return {RichTextValue} A new value with the value inserted.
  */
-
-function insert(value, valueToInsert) {
-  let startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : value.start;
-  let endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : value.end;
+function insert(value, valueToInsert, startIndex = value.start, endIndex = value.end) {
   const {
     formats,
     replacements,
     text
   } = value;
-
   if (typeof valueToInsert === 'string') {
     valueToInsert = create({
       text: valueToInsert
     });
   }
-
   const index = startIndex + valueToInsert.text.length;
   return normaliseFormats({
     formats: formats.slice(0, startIndex).concat(valueToInsert.formats, formats.slice(endIndex)),
@@ -2032,7 +2073,9 @@
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Remove content from a Rich Text value between the given `startIndex` and
@@ -2044,8 +2087,7 @@
  *
  * @return {RichTextValue} A new value with the content removed.
  */
-
-function remove(value, startIndex, endIndex) {
+function remove_remove(value, startIndex, endIndex) {
   return insert(value, create(), startIndex, endIndex);
 }
 
@@ -2054,7 +2096,9 @@
  * Internal dependencies
  */
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Search a Rich Text value and replace the match(es) with `replacement`. This
@@ -2072,29 +2116,21 @@
  *
  * @return {RichTextValue} A new value with replacements applied.
  */
-
-function replace_replace(_ref, pattern, replacement) {
-  let {
-    formats,
-    replacements,
-    text,
-    start,
-    end
-  } = _ref;
-  text = text.replace(pattern, function (match) {
-    for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
-      rest[_key - 1] = arguments[_key];
-    }
-
+function replace_replace({
+  formats,
+  replacements,
+  text,
+  start,
+  end
+}, pattern, replacement) {
+  text = text.replace(pattern, (match, ...rest) => {
     const offset = rest[rest.length - 2];
     let newText = replacement;
     let newFormats;
     let newReplacements;
-
     if (typeof newText === 'function') {
       newText = replacement(match, ...rest);
     }
-
     if (typeof newText === 'object') {
       newFormats = newText.formats;
       newReplacements = newText.replacements;
@@ -2102,19 +2138,15 @@
     } else {
       newFormats = Array(newText.length);
       newReplacements = Array(newText.length);
-
       if (formats[offset]) {
         newFormats = newFormats.fill(formats[offset]);
       }
     }
-
     formats = formats.slice(0, offset).concat(newFormats, formats.slice(offset + match.length));
     replacements = replacements.slice(0, offset).concat(newReplacements, replacements.slice(offset + match.length));
-
     if (start) {
       start = end = offset + newText.length;
     }
-
     return newText;
   });
   return normaliseFormats({
@@ -2126,117 +2158,16 @@
   });
 }
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/insert-line-separator.js
-/**
- * Internal dependencies
- */
-
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Insert a line break character into a Rich Text value at the given
- * `startIndex`. Any content between `startIndex` and `endIndex` will be
- * removed. Indices are retrieved from the selection if none are provided.
- *
- * @param {RichTextValue} value        Value to modify.
- * @param {number}        [startIndex] Start index.
- * @param {number}        [endIndex]   End index.
- *
- * @return {RichTextValue} A new value with the value inserted.
- */
-
-function insertLineSeparator(value) {
-  let startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : value.start;
-  let endIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : value.end;
-  const beforeText = value.text.slice(0, startIndex);
-  const previousLineSeparatorIndex = beforeText.lastIndexOf(LINE_SEPARATOR);
-  const previousLineSeparatorFormats = value.replacements[previousLineSeparatorIndex];
-  let replacements = [,];
-
-  if (previousLineSeparatorFormats) {
-    replacements = [previousLineSeparatorFormats];
-  }
-
-  const valueToInsert = {
-    formats: [,],
-    replacements,
-    text: LINE_SEPARATOR
-  };
-  return insert(value, valueToInsert, startIndex, endIndex);
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/remove-line-separator.js
-/**
- * Internal dependencies
- */
-
-
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Removes a line separator character, if existing, from a Rich Text value at
- * the current indices. If no line separator exists on the indices it will
- * return undefined.
- *
- * @param {RichTextValue} value    Value to modify.
- * @param {boolean}       backward Indicates if are removing from the start
- *                                 index or the end index.
- *
- * @return {RichTextValue|undefined} A new value with the line separator
- *                                   removed. Or undefined if no line separator
- *                                   is found on the position.
- */
-
-function removeLineSeparator(value) {
-  let backward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
-  const {
-    replacements,
-    text,
-    start,
-    end
-  } = value;
-  const collapsed = isCollapsed(value);
-  let index = start - 1;
-  let removeStart = collapsed ? start - 1 : start;
-  let removeEnd = end;
-
-  if (!backward) {
-    index = end;
-    removeStart = start;
-    removeEnd = collapsed ? end + 1 : end;
-  }
-
-  if (text[index] !== LINE_SEPARATOR) {
-    return;
-  }
-
-  let newValue; // If the line separator that is about te be removed
-  // contains wrappers, remove the wrappers first.
-
-  if (collapsed && replacements[index] && replacements[index].length) {
-    const newReplacements = replacements.slice();
-    newReplacements[index] = replacements[index].slice(0, -1);
-    newValue = { ...value,
-      replacements: newReplacements
-    };
-  } else {
-    newValue = remove(value, removeStart, removeEnd);
-  }
-
-  return newValue;
-}
-
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/insert-object.js
 /**
  * Internal dependencies
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextFormat} RichTextFormat */
 
 /**
  * Insert a format as an object into a Rich Text value at the given
@@ -2250,7 +2181,6 @@
  *
  * @return {RichTextValue} A new value with the object inserted.
  */
-
 function insertObject(value, formatToInsert, startIndex, endIndex) {
   const valueToInsert = {
     formats: [,],
@@ -2261,7 +2191,7 @@
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/slice.js
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Slice a Rich Text value from `startIndex` to `endIndex`. Indices are
@@ -2274,20 +2204,17 @@
  *
  * @return {RichTextValue} A new extracted value.
  */
-function slice(value) {
-  let startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : value.start;
-  let endIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : value.end;
+function slice(value, startIndex = value.start, endIndex = value.end) {
   const {
     formats,
     replacements,
     text
   } = value;
-
   if (startIndex === undefined || endIndex === undefined) {
-    return { ...value
+    return {
+      ...value
     };
   }
-
   return {
     formats: formats.slice(startIndex, endIndex),
     replacements: replacements.slice(startIndex, endIndex),
@@ -2300,7 +2227,7 @@
  * Internal dependencies
  */
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Split a Rich Text value in two at the given `startIndex` and `endIndex`, or
@@ -2312,20 +2239,16 @@
  *
  * @return {Array<RichTextValue>|undefined} An array of new values.
  */
-
-function split(_ref, string) {
-  let {
-    formats,
-    replacements,
-    text,
-    start,
-    end
-  } = _ref;
-
+function split({
+  formats,
+  replacements,
+  text,
+  start,
+  end
+}, string) {
   if (typeof string !== 'string') {
     return splitAtSelection(...arguments);
   }
-
   let nextStart = 0;
   return text.split(string).map(substring => {
     const startIndex = nextStart;
@@ -2335,40 +2258,31 @@
       text: substring
     };
     nextStart += string.length + substring.length;
-
     if (start !== undefined && end !== undefined) {
       if (start >= startIndex && start < nextStart) {
         value.start = start - startIndex;
       } else if (start < startIndex && end > startIndex) {
         value.start = 0;
       }
-
       if (end >= startIndex && end < nextStart) {
         value.end = end - startIndex;
       } else if (start < nextStart && end > nextStart) {
         value.end = substring.length;
       }
     }
-
     return value;
   });
 }
-
-function splitAtSelection(_ref2) {
-  let {
-    formats,
-    replacements,
-    text,
-    start,
-    end
-  } = _ref2;
-  let startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : start;
-  let endIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : end;
-
+function splitAtSelection({
+  formats,
+  replacements,
+  text,
+  start,
+  end
+}, startIndex = start, endIndex = end) {
   if (start === undefined || end === undefined) {
     return;
   }
-
   const before = {
     formats: formats.slice(0, startIndex),
     replacements: replacements.slice(0, startIndex),
@@ -2381,368 +2295,22 @@
     start: 0,
     end: 0
   };
-  return [// Ensure newlines are trimmed.
-  replace_replace(before, /\u2028+$/, ''), replace_replace(after, /^\u2028+/, '')];
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-format-type.js
-/**
- * WordPress dependencies
- */
-
-/**
- * Internal dependencies
- */
-
-
-/** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */
-
-/**
- * Returns a registered format type.
- *
- * @param {string} name Format name.
- *
- * @return {RichTextFormatType|undefined} Format type.
- */
-
-function get_format_type_getFormatType(name) {
-  return (0,external_wp_data_namespaceObject.select)(store).getFormatType(name);
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-tree.js
-/**
- * Internal dependencies
- */
-
-
-
-
-function restoreOnAttributes(attributes, isEditableTree) {
-  if (isEditableTree) {
-    return attributes;
-  }
-
-  const newAttributes = {};
-
-  for (const key in attributes) {
-    let newKey = key;
-
-    if (key.startsWith('data-disable-rich-text-')) {
-      newKey = key.slice('data-disable-rich-text-'.length);
-    }
-
-    newAttributes[newKey] = attributes[key];
-  }
-
-  return newAttributes;
-}
-/**
- * Converts a format object to information that can be used to create an element
- * from (type, attributes and object).
- *
- * @param {Object}  $1                        Named parameters.
- * @param {string}  $1.type                   The format type.
- * @param {Object}  $1.attributes             The format attributes.
- * @param {Object}  $1.unregisteredAttributes The unregistered format
- *                                            attributes.
- * @param {boolean} $1.object                 Whether or not it is an object
- *                                            format.
- * @param {boolean} $1.boundaryClass          Whether or not to apply a boundary
- *                                            class.
- * @param {boolean} $1.isEditableTree
- *
- * @return {Object} Information to be used for element creation.
- */
-
-
-function fromFormat(_ref) {
-  let {
-    type,
-    attributes,
-    unregisteredAttributes,
-    object,
-    boundaryClass,
-    isEditableTree
-  } = _ref;
-  const formatType = get_format_type_getFormatType(type);
-  let elementAttributes = {};
-
-  if (boundaryClass) {
-    elementAttributes['data-rich-text-format-boundary'] = 'true';
-  }
-
-  if (!formatType) {
-    if (attributes) {
-      elementAttributes = { ...attributes,
-        ...elementAttributes
-      };
-    }
-
-    return {
-      type,
-      attributes: restoreOnAttributes(elementAttributes, isEditableTree),
-      object
-    };
-  }
-
-  elementAttributes = { ...unregisteredAttributes,
-    ...elementAttributes
-  };
-
-  for (const name in attributes) {
-    const key = formatType.attributes ? formatType.attributes[name] : false;
-
-    if (key) {
-      elementAttributes[key] = attributes[name];
-    } else {
-      elementAttributes[name] = attributes[name];
-    }
-  }
-
-  if (formatType.className) {
-    if (elementAttributes.class) {
-      elementAttributes.class = `${formatType.className} ${elementAttributes.class}`;
-    } else {
-      elementAttributes.class = formatType.className;
-    }
-  }
-
-  return {
-    type: formatType.tagName,
-    object: formatType.object,
-    attributes: restoreOnAttributes(elementAttributes, isEditableTree)
-  };
-}
-/**
- * Checks if both arrays of formats up until a certain index are equal.
- *
- * @param {Array}  a     Array of formats to compare.
- * @param {Array}  b     Array of formats to compare.
- * @param {number} index Index to check until.
- */
-
-
-function isEqualUntil(a, b, index) {
-  do {
-    if (a[index] !== b[index]) {
-      return false;
-    }
-  } while (index--);
-
-  return true;
+  return [before, after];
 }
 
-function toTree(_ref2) {
-  let {
-    value,
-    multilineTag,
-    preserveWhiteSpace,
-    createEmpty,
-    append,
-    getLastChild,
-    getParent,
-    isText,
-    getText,
-    remove,
-    appendText,
-    onStartIndex,
-    onEndIndex,
-    isEditableTree,
-    placeholder
-  } = _ref2;
-  const {
-    formats,
-    replacements,
-    text,
-    start,
-    end
-  } = value;
-  const formatsLength = formats.length + 1;
-  const tree = createEmpty();
-  const multilineFormat = {
-    type: multilineTag
-  };
-  const activeFormats = getActiveFormats(value);
-  const deepestActiveFormat = activeFormats[activeFormats.length - 1];
-  let lastSeparatorFormats;
-  let lastCharacterFormats;
-  let lastCharacter; // If we're building a multiline tree, start off with a multiline element.
-
-  if (multilineTag) {
-    append(append(tree, {
-      type: multilineTag
-    }), '');
-    lastCharacterFormats = lastSeparatorFormats = [multilineFormat];
-  } else {
-    append(tree, '');
-  }
-
-  for (let i = 0; i < formatsLength; i++) {
-    const character = text.charAt(i);
-    const shouldInsertPadding = isEditableTree && ( // Pad the line if the line is empty.
-    !lastCharacter || lastCharacter === LINE_SEPARATOR || // Pad the line if the previous character is a line break, otherwise
-    // the line break won't be visible.
-    lastCharacter === '\n');
-    let characterFormats = formats[i]; // Set multiline tags in queue for building the tree.
-
-    if (multilineTag) {
-      if (character === LINE_SEPARATOR) {
-        characterFormats = lastSeparatorFormats = (replacements[i] || []).reduce((accumulator, format) => {
-          accumulator.push(format, multilineFormat);
-          return accumulator;
-        }, [multilineFormat]);
-      } else {
-        characterFormats = [...lastSeparatorFormats, ...(characterFormats || [])];
-      }
-    }
-
-    let pointer = getLastChild(tree);
-
-    if (shouldInsertPadding && character === LINE_SEPARATOR) {
-      let node = pointer;
-
-      while (!isText(node)) {
-        node = getLastChild(node);
-      }
-
-      append(getParent(node), ZWNBSP);
-    } // Set selection for the start of line.
-
-
-    if (lastCharacter === LINE_SEPARATOR) {
-      let node = pointer;
-
-      while (!isText(node)) {
-        node = getLastChild(node);
-      }
-
-      if (onStartIndex && start === i) {
-        onStartIndex(tree, node);
-      }
-
-      if (onEndIndex && end === i) {
-        onEndIndex(tree, node);
-      }
-    }
-
-    if (characterFormats) {
-      characterFormats.forEach((format, formatIndex) => {
-        if (pointer && lastCharacterFormats && // Reuse the last element if all formats remain the same.
-        isEqualUntil(characterFormats, lastCharacterFormats, formatIndex) && ( // Do not reuse the last element if the character is a
-        // line separator.
-        character !== LINE_SEPARATOR || characterFormats.length - 1 !== formatIndex)) {
-          pointer = getLastChild(pointer);
-          return;
-        }
-
-        const {
-          type,
-          attributes,
-          unregisteredAttributes
-        } = format;
-        const boundaryClass = isEditableTree && character !== LINE_SEPARATOR && format === deepestActiveFormat;
-        const parent = getParent(pointer);
-        const newNode = append(parent, fromFormat({
-          type,
-          attributes,
-          unregisteredAttributes,
-          boundaryClass,
-          isEditableTree
-        }));
-
-        if (isText(pointer) && getText(pointer).length === 0) {
-          remove(pointer);
-        }
-
-        pointer = append(newNode, '');
-      });
-    } // No need for further processing if the character is a line separator.
-
-
-    if (character === LINE_SEPARATOR) {
-      lastCharacterFormats = characterFormats;
-      lastCharacter = character;
-      continue;
-    } // If there is selection at 0, handle it before characters are inserted.
-
-
-    if (i === 0) {
-      if (onStartIndex && start === 0) {
-        onStartIndex(tree, pointer);
-      }
-
-      if (onEndIndex && end === 0) {
-        onEndIndex(tree, pointer);
-      }
-    }
-
-    if (character === OBJECT_REPLACEMENT_CHARACTER) {
-      var _replacements$i;
-
-      if (!isEditableTree && ((_replacements$i = replacements[i]) === null || _replacements$i === void 0 ? void 0 : _replacements$i.type) === 'script') {
-        pointer = append(getParent(pointer), fromFormat({
-          type: 'script',
-          isEditableTree
-        }));
-        append(pointer, {
-          html: decodeURIComponent(replacements[i].attributes['data-rich-text-script'])
-        });
-      } else {
-        pointer = append(getParent(pointer), fromFormat({ ...replacements[i],
-          object: true,
-          isEditableTree
-        }));
-      } // Ensure pointer is text node.
-
-
-      pointer = append(getParent(pointer), '');
-    } else if (!preserveWhiteSpace && character === '\n') {
-      pointer = append(getParent(pointer), {
-        type: 'br',
-        attributes: isEditableTree ? {
-          'data-rich-text-line-break': 'true'
-        } : undefined,
-        object: true
-      }); // Ensure pointer is text node.
-
-      pointer = append(getParent(pointer), '');
-    } else if (!isText(pointer)) {
-      pointer = append(getParent(pointer), character);
-    } else {
-      appendText(pointer, character);
-    }
-
-    if (onStartIndex && start === i + 1) {
-      onStartIndex(tree, pointer);
-    }
-
-    if (onEndIndex && end === i + 1) {
-      onEndIndex(tree, pointer);
-    }
-
-    if (shouldInsertPadding && i === text.length) {
-      append(getParent(pointer), ZWNBSP);
-
-      if (placeholder && text.length === 0) {
-        append(getParent(pointer), {
-          type: 'span',
-          attributes: {
-            'data-rich-text-placeholder': placeholder,
-            // Necessary to prevent the placeholder from catching
-            // selection. The placeholder is also not editable after
-            // all.
-            contenteditable: 'false',
-            style: 'pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;'
-          }
-        });
-      }
-    }
-
-    lastCharacterFormats = characterFormats;
-    lastCharacter = character;
-  }
-
-  return tree;
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/is-range-equal.js
+/**
+ * Returns true if two ranges are equal, or false otherwise. Ranges are
+ * considered equal if their start and end occur in the same container and
+ * offset.
+ *
+ * @param {Range|null} a First range object to test.
+ * @param {Range|null} b First range object to test.
+ *
+ * @return {boolean} Whether the two ranges are equal.
+ */
+function isRangeEqual(a, b) {
+  return a === b || a && b && a.startContainer === b.startContainer && a.startOffset === b.startOffset && a.endContainer === b.endContainer && a.endOffset === b.endOffset;
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-dom.js
@@ -2751,7 +2319,10 @@
  */
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Creates a path as an array of indices from the given root node to the given
@@ -2763,23 +2334,19 @@
  *
  * @return {Array} The path from the root node to the node.
  */
-
 function createPathToNode(node, rootNode, path) {
   const parentNode = node.parentNode;
   let i = 0;
-
   while (node = node.previousSibling) {
     i++;
   }
-
   path = [i, ...path];
-
   if (parentNode !== rootNode) {
     path = createPathToNode(parentNode, rootNode, path);
   }
-
   return path;
 }
+
 /**
  * Gets a node given a path (array of indices) from the given node.
  *
@@ -2788,92 +2355,75 @@
  *
  * @return {Object} Object with the found node and the remaining offset (if any).
  */
-
-
 function getNodeByPath(node, path) {
   path = [...path];
-
   while (node && path.length > 1) {
     node = node.childNodes[path.shift()];
   }
-
   return {
     node,
     offset: path[0]
   };
 }
-
-function append(element, child) {
+function to_dom_append(element, child) {
+  if (child.html !== undefined) {
+    return element.innerHTML += child.html;
+  }
   if (typeof child === 'string') {
     child = element.ownerDocument.createTextNode(child);
   }
-
   const {
     type,
     attributes
   } = child;
-
   if (type) {
     child = element.ownerDocument.createElement(type);
-
     for (const key in attributes) {
       child.setAttribute(key, attributes[key]);
     }
   }
-
   return element.appendChild(child);
 }
-
-function appendText(node, text) {
+function to_dom_appendText(node, text) {
   node.appendData(text);
 }
-
-function getLastChild(_ref) {
-  let {
-    lastChild
-  } = _ref;
+function to_dom_getLastChild({
+  lastChild
+}) {
   return lastChild;
 }
-
-function getParent(_ref2) {
-  let {
-    parentNode
-  } = _ref2;
+function to_dom_getParent({
+  parentNode
+}) {
   return parentNode;
 }
-
-function isText(node) {
+function to_dom_isText(node) {
   return node.nodeType === node.TEXT_NODE;
 }
-
-function getText(_ref3) {
-  let {
-    nodeValue
-  } = _ref3;
+function to_dom_getText({
+  nodeValue
+}) {
   return nodeValue;
 }
-
 function to_dom_remove(node) {
   return node.parentNode.removeChild(node);
 }
-
-function toDom(_ref4) {
-  let {
-    value,
-    multilineTag,
-    prepareEditableTree,
-    isEditableTree = true,
-    placeholder,
-    doc = document
-  } = _ref4;
+function toDom({
+  value,
+  prepareEditableTree,
+  isEditableTree = true,
+  placeholder,
+  doc = document
+}) {
   let startPath = [];
   let endPath = [];
-
   if (prepareEditableTree) {
-    value = { ...value,
+    value = {
+      ...value,
       formats: prepareEditableTree(value)
     };
   }
+
   /**
    * Returns a new instance of a DOM tree upon which RichText operations can be
    * applied.
@@ -2884,30 +2434,23 @@
    *
    * @return {Object} RichText tree.
    */
-
-
   const createEmpty = () => createElement(doc, '');
-
   const tree = toTree({
     value,
-    multilineTag,
     createEmpty,
-    append,
-    getLastChild,
-    getParent,
-    isText,
-    getText,
+    append: to_dom_append,
+    getLastChild: to_dom_getLastChild,
+    getParent: to_dom_getParent,
+    isText: to_dom_isText,
+    getText: to_dom_getText,
     remove: to_dom_remove,
-    appendText,
-
+    appendText: to_dom_appendText,
     onStartIndex(body, pointer) {
       startPath = createPathToNode(pointer, body, [pointer.nodeValue.length]);
     },
-
     onEndIndex(body, pointer) {
       endPath = createPathToNode(pointer, body, [pointer.nodeValue.length]);
     },
-
     isEditableTree,
     placeholder
   });
@@ -2919,42 +2462,36 @@
     }
   };
 }
+
 /**
  * Create an `Element` tree from a Rich Text value and applies the difference to
- * the `Element` tree contained by `current`. If a `multilineTag` is provided,
- * text separated by two new lines will be wrapped in an `Element` of that type.
+ * the `Element` tree contained by `current`.
  *
  * @param {Object}        $1                       Named arguments.
  * @param {RichTextValue} $1.value                 Value to apply.
  * @param {HTMLElement}   $1.current               The live root node to apply the element tree to.
- * @param {string}        [$1.multilineTag]        Multiline tag.
  * @param {Function}      [$1.prepareEditableTree] Function to filter editorable formats.
  * @param {boolean}       [$1.__unstableDomOnly]   Only apply elements, no selection.
  * @param {string}        [$1.placeholder]         Placeholder text.
  */
-
-function apply(_ref5) {
-  let {
-    value,
-    current,
-    multilineTag,
-    prepareEditableTree,
-    __unstableDomOnly,
-    placeholder
-  } = _ref5;
+function apply({
+  value,
+  current,
+  prepareEditableTree,
+  __unstableDomOnly,
+  placeholder
+}) {
   // Construct a new element tree in memory.
   const {
     body,
     selection
   } = toDom({
     value,
-    multilineTag,
     prepareEditableTree,
     placeholder,
     doc: current.ownerDocument
   });
   applyValue(body, current);
-
   if (value.start !== undefined && !__unstableDomOnly) {
     applySelection(selection, current);
   }
@@ -2962,10 +2499,8 @@
 function applyValue(future, current) {
   let i = 0;
   let futureChild;
-
   while (futureChild = future.firstChild) {
     const currentChild = current.childNodes[i];
-
     if (!currentChild) {
       current.appendChild(futureChild);
     } else if (!currentChild.isEqualNode(futureChild)) {
@@ -2974,69 +2509,47 @@
       } else {
         const currentAttributes = currentChild.attributes;
         const futureAttributes = futureChild.attributes;
-
         if (currentAttributes) {
-          let ii = currentAttributes.length; // Reverse loop because `removeAttribute` on `currentChild`
+          let ii = currentAttributes.length;
+
+          // Reverse loop because `removeAttribute` on `currentChild`
           // changes `currentAttributes`.
-
           while (ii--) {
             const {
               name
             } = currentAttributes[ii];
-
             if (!futureChild.getAttribute(name)) {
               currentChild.removeAttribute(name);
             }
           }
         }
-
         if (futureAttributes) {
           for (let ii = 0; ii < futureAttributes.length; ii++) {
             const {
               name,
               value
             } = futureAttributes[ii];
-
             if (currentChild.getAttribute(name) !== value) {
               currentChild.setAttribute(name, value);
             }
           }
         }
-
         applyValue(futureChild, currentChild);
         future.removeChild(futureChild);
       }
     } else {
       future.removeChild(futureChild);
     }
-
     i++;
   }
-
   while (current.childNodes[i]) {
     current.removeChild(current.childNodes[i]);
   }
 }
-/**
- * Returns true if two ranges are equal, or false otherwise. Ranges are
- * considered equal if their start and end occur in the same container and
- * offset.
- *
- * @param {Range} a First range object to test.
- * @param {Range} b First range object to test.
- *
- * @return {boolean} Whether the two ranges are equal.
- */
-
-function isRangeEqual(a, b) {
-  return a.startContainer === b.startContainer && a.startOffset === b.startOffset && a.endContainer === b.endContainer && a.endOffset === b.endOffset;
-}
-
-function applySelection(_ref6, current) {
-  let {
-    startPath,
-    endPath
-  } = _ref6;
+function applySelection({
+  startPath,
+  endPath
+}, current) {
   const {
     node: startContainer,
     offset: startOffset
@@ -3058,21 +2571,19 @@
   const {
     activeElement
   } = ownerDocument;
-
   if (selection.rangeCount > 0) {
     // If the to be added range and the live range are the same, there's no
     // need to remove the live range and add the equivalent range.
     if (isRangeEqual(range, selection.getRangeAt(0))) {
       return;
     }
-
     selection.removeAllRanges();
   }
-
-  selection.addRange(range); // This function is not intended to cause a shift in focus. Since the above
+  selection.addRange(range);
+
+  // This function is not intended to cause a shift in focus. Since the above
   // selection manipulations may shift focus, ensure that focus is restored to
   // its previous state.
-
   if (activeElement !== ownerDocument.activeElement) {
     // The `instanceof` checks protect against edge cases where the focused
     // element is not of the interface HTMLElement (does not have a `focus`
@@ -3085,159 +2596,18 @@
   }
 }
 
-;// CONCATENATED MODULE: external ["wp","escapeHtml"]
-var external_wp_escapeHtml_namespaceObject = window["wp"]["escapeHtml"];
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/to-html-string.js
-/**
- * WordPress dependencies
- */
-
-/**
- * Internal dependencies
- */
-
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Create an HTML string from a Rich Text value. If a `multilineTag` is
- * provided, text separated by a line separator will be wrapped in it.
- *
- * @param {Object}        $1                      Named argements.
- * @param {RichTextValue} $1.value                Rich text value.
- * @param {string}        [$1.multilineTag]       Multiline tag.
- * @param {boolean}       [$1.preserveWhiteSpace] Whether or not to use newline
- *                                                characters for line breaks.
- *
- * @return {string} HTML string.
- */
-
-function toHTMLString(_ref) {
-  let {
-    value,
-    multilineTag,
-    preserveWhiteSpace
-  } = _ref;
-  const tree = toTree({
-    value,
-    multilineTag,
-    preserveWhiteSpace,
-    createEmpty,
-    append: to_html_string_append,
-    getLastChild: to_html_string_getLastChild,
-    getParent: to_html_string_getParent,
-    isText: to_html_string_isText,
-    getText: to_html_string_getText,
-    remove: to_html_string_remove,
-    appendText: to_html_string_appendText
-  });
-  return createChildrenHTML(tree.children);
-}
-
-function createEmpty() {
-  return {};
-}
-
-function to_html_string_getLastChild(_ref2) {
-  let {
-    children
-  } = _ref2;
-  return children && children[children.length - 1];
-}
-
-function to_html_string_append(parent, object) {
-  if (typeof object === 'string') {
-    object = {
-      text: object
-    };
-  }
-
-  object.parent = parent;
-  parent.children = parent.children || [];
-  parent.children.push(object);
-  return object;
-}
-
-function to_html_string_appendText(object, text) {
-  object.text += text;
-}
-
-function to_html_string_getParent(_ref3) {
-  let {
-    parent
-  } = _ref3;
-  return parent;
-}
-
-function to_html_string_isText(_ref4) {
-  let {
-    text
-  } = _ref4;
-  return typeof text === 'string';
-}
-
-function to_html_string_getText(_ref5) {
-  let {
-    text
-  } = _ref5;
-  return text;
-}
-
-function to_html_string_remove(object) {
-  const index = object.parent.children.indexOf(object);
-
-  if (index !== -1) {
-    object.parent.children.splice(index, 1);
-  }
-
-  return object;
-}
-
-function createElementHTML(_ref6) {
-  let {
-    type,
-    attributes,
-    object,
-    children
-  } = _ref6;
-  let attributeString = '';
-
-  for (const key in attributes) {
-    if (!(0,external_wp_escapeHtml_namespaceObject.isValidAttributeName)(key)) {
-      continue;
-    }
-
-    attributeString += ` ${key}="${(0,external_wp_escapeHtml_namespaceObject.escapeAttribute)(attributes[key])}"`;
-  }
-
-  if (object) {
-    return `<${type}${attributeString}>`;
-  }
-
-  return `<${type}${attributeString}>${createChildrenHTML(children)}</${type}>`;
-}
-
-function createChildrenHTML() {
-  let children = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
-  return children.map(child => {
-    if (child.html !== undefined) {
-      return child.html;
-    }
-
-    return child.text === undefined ? createElementHTML(child) : (0,external_wp_escapeHtml_namespaceObject.escapeEditableHTML)(child.text);
-  }).join('');
-}
-
 ;// CONCATENATED MODULE: external ["wp","a11y"]
-var external_wp_a11y_namespaceObject = window["wp"]["a11y"];
+const external_wp_a11y_namespaceObject = window["wp"]["a11y"];
 ;// CONCATENATED MODULE: external ["wp","i18n"]
-var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
+const external_wp_i18n_namespaceObject = window["wp"]["i18n"];
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/toggle-format.js
 /**
  * WordPress dependencies
  */
 
 
+
+
 /**
  * Internal dependencies
  */
@@ -3245,9 +2615,9 @@
 
 
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
+/** @typedef {import('./types').RichTextFormat} RichTextFormat */
 
 /**
  * Toggles a format object to a Rich Text value at the current selection.
@@ -3257,7 +2627,6 @@
  *
  * @return {RichTextValue} A new value with the format applied or removed.
  */
-
 function toggleFormat(value, format) {
   if (getActiveFormat(value, format.type)) {
     // For screen readers, will announce if formatting control is disabled.
@@ -3265,16 +2634,13 @@
       // translators: %s: title of the formatting control
       (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('%s removed.'), format.title), 'assertive');
     }
-
     return removeFormat(value, format.type);
-  } // For screen readers, will announce if formatting control is enabled.
-
-
+  }
+  // For screen readers, will announce if formatting control is enabled.
   if (format.title) {
     // translators: %s: title of the formatting control
     (0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('%s applied.'), format.title), 'assertive');
   }
-
   return applyFormat(value, format);
 }
 
@@ -3283,411 +2649,56 @@
  * WordPress dependencies
  */
 
+
 /**
  * Internal dependencies
  */
 
 
-/** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */
+/** @typedef {import('./register-format-type').WPFormat} WPFormat */
 
 /**
  * Unregisters a format.
  *
  * @param {string} name Format name.
  *
- * @return {RichTextFormatType|undefined} The previous format value, if it has
+ * @return {WPFormat|undefined} The previous format value, if it has
  *                                        been successfully unregistered;
  *                                        otherwise `undefined`.
  */
-
 function unregisterFormatType(name) {
   const oldFormat = (0,external_wp_data_namespaceObject.select)(store).getFormatType(name);
-
   if (!oldFormat) {
     window.console.error(`Format ${name} is not registered.`);
     return;
   }
-
   (0,external_wp_data_namespaceObject.dispatch)(store).removeFormatTypes(name);
   return oldFormat;
 }
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/can-indent-list-items.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Checks if the selected list item can be indented.
- *
- * @param {RichTextValue} value Value to check.
- *
- * @return {boolean} Whether or not the selected list item can be indented.
- */
-
-function canIndentListItems(value) {
-  const lineIndex = getLineIndex(value); // There is only one line, so the line cannot be indented.
-
-  if (lineIndex === undefined) {
-    return false;
-  }
-
-  const {
-    replacements
-  } = value;
-  const previousLineIndex = getLineIndex(value, lineIndex);
-  const formatsAtLineIndex = replacements[lineIndex] || [];
-  const formatsAtPreviousLineIndex = replacements[previousLineIndex] || []; // If the indentation of the current line is greater than previous line,
-  // then the line cannot be furter indented.
-
-  return formatsAtLineIndex.length <= formatsAtPreviousLineIndex.length;
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/can-outdent-list-items.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Checks if the selected list item can be outdented.
- *
- * @param {RichTextValue} value Value to check.
- *
- * @return {boolean} Whether or not the selected list item can be outdented.
- */
-
-function canOutdentListItems(value) {
-  const {
-    replacements,
-    start
-  } = value;
-  const startingLineIndex = getLineIndex(value, start);
-  return replacements[startingLineIndex] !== undefined;
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/indent-list-items.js
-/**
- * Internal dependencies
- */
-
-
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
-
-/**
- * Gets the line index of the first previous list item with higher indentation.
- *
- * @param {RichTextValue} value     Value to search.
- * @param {number}        lineIndex Line index of the list item to compare
- *                                  with.
- *
- * @return {number|void} The line index.
- */
-
-function getTargetLevelLineIndex(_ref, lineIndex) {
-  let {
-    text,
-    replacements
-  } = _ref;
-  const startFormats = replacements[lineIndex] || [];
-  let index = lineIndex;
-
-  while (index-- >= 0) {
-    if (text[index] !== LINE_SEPARATOR) {
-      continue;
-    }
-
-    const formatsAtIndex = replacements[index] || []; // Return the first line index that is one level higher. If the level is
-    // lower or equal, there is no result.
-
-    if (formatsAtIndex.length === startFormats.length + 1) {
-      return index;
-    } else if (formatsAtIndex.length <= startFormats.length) {
-      return;
-    }
-  }
-}
-/**
- * Indents any selected list items if possible.
- *
- * @param {RichTextValue}  value      Value to change.
- * @param {RichTextFormat} rootFormat Root format.
- *
- * @return {RichTextValue} The changed value.
- */
-
-
-function indentListItems(value, rootFormat) {
-  if (!canIndentListItems(value)) {
-    return value;
-  }
-
-  const lineIndex = getLineIndex(value);
-  const previousLineIndex = getLineIndex(value, lineIndex);
-  const {
-    text,
-    replacements,
-    end
-  } = value;
-  const newFormats = replacements.slice();
-  const targetLevelLineIndex = getTargetLevelLineIndex(value, lineIndex);
-
-  for (let index = lineIndex; index < end; index++) {
-    if (text[index] !== LINE_SEPARATOR) {
-      continue;
-    } // Get the previous list, and if there's a child list, take over the
-    // formats. If not, duplicate the last level and create a new level.
-
-
-    if (targetLevelLineIndex) {
-      const targetFormats = replacements[targetLevelLineIndex] || [];
-      newFormats[index] = targetFormats.concat((newFormats[index] || []).slice(targetFormats.length - 1));
-    } else {
-      const targetFormats = replacements[previousLineIndex] || [];
-      const lastformat = targetFormats[targetFormats.length - 1] || rootFormat;
-      newFormats[index] = targetFormats.concat([lastformat], (newFormats[index] || []).slice(targetFormats.length));
-    }
-  }
-
-  return { ...value,
-    replacements: newFormats
-  };
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-parent-line-index.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Gets the index of the first parent list. To get the parent list formats, we
- * go through every list item until we find one with exactly one format type
- * less.
- *
- * @param {RichTextValue} value     Value to search.
- * @param {number}        lineIndex Line index of a child list item.
- *
- * @return {number|void} The parent list line index.
- */
-
-function getParentLineIndex(_ref, lineIndex) {
-  let {
-    text,
-    replacements
-  } = _ref;
-  const startFormats = replacements[lineIndex] || [];
-  let index = lineIndex;
-
-  while (index-- >= 0) {
-    if (text[index] !== LINE_SEPARATOR) {
-      continue;
-    }
-
-    const formatsAtIndex = replacements[index] || [];
-
-    if (formatsAtIndex.length === startFormats.length - 1) {
-      return index;
-    }
-  }
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/get-last-child-index.js
-/**
- * Internal dependencies
- */
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Gets the line index of the last child in the list.
- *
- * @param {RichTextValue} value     Value to search.
- * @param {number}        lineIndex Line index of a list item in the list.
- *
- * @return {number} The index of the last child.
- */
-
-function getLastChildIndex(_ref, lineIndex) {
-  let {
-    text,
-    replacements
-  } = _ref;
-  const lineFormats = replacements[lineIndex] || []; // Use the given line index in case there are no next children.
-
-  let childIndex = lineIndex; // `lineIndex` could be `undefined` if it's the first line.
-
-  for (let index = lineIndex || 0; index < text.length; index++) {
-    // We're only interested in line indices.
-    if (text[index] !== LINE_SEPARATOR) {
-      continue;
-    }
-
-    const formatsAtIndex = replacements[index] || []; // If the amout of formats is equal or more, store it, then return the
-    // last one if the amount of formats is less.
-
-    if (formatsAtIndex.length >= lineFormats.length) {
-      childIndex = index;
-    } else {
-      return childIndex;
-    }
-  } // If the end of the text is reached, return the last child index.
-
-
-  return childIndex;
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/outdent-list-items.js
-/**
- * Internal dependencies
- */
-
-
-
-
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/**
- * Outdents any selected list items if possible.
- *
- * @param {RichTextValue} value Value to change.
- *
- * @return {RichTextValue} The changed value.
- */
-
-function outdentListItems(value) {
-  if (!canOutdentListItems(value)) {
-    return value;
-  }
-
-  const {
-    text,
-    replacements,
-    start,
-    end
-  } = value;
-  const startingLineIndex = getLineIndex(value, start);
-  const newFormats = replacements.slice(0);
-  const parentFormats = replacements[getParentLineIndex(value, startingLineIndex)] || [];
-  const endingLineIndex = getLineIndex(value, end);
-  const lastChildIndex = getLastChildIndex(value, endingLineIndex); // Outdent all list items from the starting line index until the last child
-  // index of the ending list. All children of the ending list need to be
-  // outdented, otherwise they'll be orphaned.
-
-  for (let index = startingLineIndex; index <= lastChildIndex; index++) {
-    // Skip indices that are not line separators.
-    if (text[index] !== LINE_SEPARATOR) {
-      continue;
-    } // In the case of level 0, the formats at the index are undefined.
-
-
-    const currentFormats = newFormats[index] || []; // Omit the indentation level where the selection starts.
-
-    newFormats[index] = parentFormats.concat(currentFormats.slice(parentFormats.length + 1));
-
-    if (newFormats[index].length === 0) {
-      delete newFormats[index];
-    }
-  }
-
-  return { ...value,
-    replacements: newFormats
-  };
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/change-list-type.js
-/**
- * Internal dependencies
- */
-
-
-
-/** @typedef {import('./create').RichTextValue} RichTextValue */
-
-/** @typedef {import('./create').RichTextFormat} RichTextFormat */
-
-/**
- * Changes the list type of the selected indented list, if any. Looks at the
- * currently selected list item and takes the parent list, then changes the list
- * type of this list. When multiple lines are selected, the parent lists are
- * takes and changed.
- *
- * @param {RichTextValue}  value     Value to change.
- * @param {RichTextFormat} newFormat The new list format object. Choose between
- *                                   `{ type: 'ol' }` and `{ type: 'ul' }`.
- *
- * @return {RichTextValue} The changed value.
- */
-
-function changeListType(value, newFormat) {
-  const {
-    text,
-    replacements,
-    start,
-    end
-  } = value;
-  const startingLineIndex = getLineIndex(value, start);
-  const startLineFormats = replacements[startingLineIndex] || [];
-  const endLineFormats = replacements[getLineIndex(value, end)] || [];
-  const startIndex = getParentLineIndex(value, startingLineIndex);
-  const newReplacements = replacements.slice();
-  const startCount = startLineFormats.length - 1;
-  const endCount = endLineFormats.length - 1;
-  let changed;
-
-  for (let index = startIndex + 1 || 0; index < text.length; index++) {
-    if (text[index] !== LINE_SEPARATOR) {
-      continue;
-    }
-
-    if ((newReplacements[index] || []).length <= startCount) {
-      break;
-    }
-
-    if (!newReplacements[index]) {
-      continue;
-    }
-
-    changed = true;
-    newReplacements[index] = newReplacements[index].map((format, i) => {
-      return i < startCount || i > endCount ? format : newFormat;
-    });
-  }
-
-  if (!changed) {
-    return value;
-  }
-
-  return { ...value,
-    replacements: newReplacements
-  };
-}
-
 ;// CONCATENATED MODULE: external ["wp","element"]
-var external_wp_element_namespaceObject = window["wp"]["element"];
+const external_wp_element_namespaceObject = window["wp"]["element"];
+;// CONCATENATED MODULE: external ["wp","deprecated"]
+const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
+var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-anchor-ref.js
 /**
  * WordPress dependencies
  */
 
+
+
 /**
  * Internal dependencies
  */
 
 
-/** @typedef {import('@wordpress/element').RefObject} RefObject */
-
-/** @typedef {import('../register-format-type').RichTextFormatType} RichTextFormatType */
-
-/** @typedef {import('../create').RichTextValue} RichTextValue */
+/**
+ * @template T
+ * @typedef {import('@wordpress/element').RefObject<T>} RefObject<T>
+ */
+/** @typedef {import('../register-format-type').WPFormat} WPFormat */
+/** @typedef {import('../types').RichTextValue} RichTextValue */
 
 /**
  * This hook, to be used in a format type's Edit component, returns the active
@@ -3699,17 +2710,19 @@
  * @param {RefObject<HTMLElement>} $1.ref      React ref of the element
  *                                             containing  the editable content.
  * @param {RichTextValue}          $1.value    Value to check for selection.
- * @param {RichTextFormatType}     $1.settings The format type's settings.
+ * @param {WPFormat}               $1.settings The format type's settings.
  *
  * @return {Element|Range} The active element or selection range.
  */
-
-function useAnchorRef(_ref) {
-  let {
-    ref,
-    value,
-    settings = {}
-  } = _ref;
+function useAnchorRef({
+  ref,
+  value,
+  settings = {}
+}) {
+  external_wp_deprecated_default()('`useAnchorRef` hook', {
+    since: '6.1',
+    alternative: '`useAnchor` hook'
+  });
   const {
     tagName,
     className,
@@ -3717,43 +2730,226 @@
   } = settings;
   const activeFormat = name ? getActiveFormat(value, name) : undefined;
   return (0,external_wp_element_namespaceObject.useMemo)(() => {
-    if (!ref.current) return;
+    if (!ref.current) {
+      return;
+    }
     const {
       ownerDocument: {
         defaultView
       }
     } = ref.current;
     const selection = defaultView.getSelection();
-
     if (!selection.rangeCount) {
       return;
     }
-
     const range = selection.getRangeAt(0);
-
     if (!activeFormat) {
       return range;
     }
-
-    let element = range.startContainer; // If the caret is right before the element, select the next element.
-
+    let element = range.startContainer;
+
+    // If the caret is right before the element, select the next element.
     element = element.nextElementSibling || element;
-
     while (element.nodeType !== element.ELEMENT_NODE) {
       element = element.parentNode;
     }
-
     return element.closest(tagName + (className ? '.' + className : ''));
   }, [activeFormat, value.start, value.end, tagName, className]);
 }
 
 ;// CONCATENATED MODULE: external ["wp","compose"]
-var external_wp_compose_namespaceObject = window["wp"]["compose"];
+const external_wp_compose_namespaceObject = window["wp"]["compose"];
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-anchor.js
+/**
+ * WordPress dependencies
+ */
+
+
+
+/** @typedef {import('../register-format-type').WPFormat} WPFormat */
+/** @typedef {import('../types').RichTextValue} RichTextValue */
+
+/**
+ * Given a range and a format tag name and class name, returns the closest
+ * format element.
+ *
+ * @param {Range}       range                  The Range to check.
+ * @param {HTMLElement} editableContentElement The editable wrapper.
+ * @param {string}      tagName                The tag name of the format element.
+ * @param {string}      className              The class name of the format element.
+ *
+ * @return {HTMLElement|undefined} The format element, if found.
+ */
+function getFormatElement(range, editableContentElement, tagName, className) {
+  let element = range.startContainer;
+
+  // Even if the active format is defined, the actualy DOM range's start
+  // container may be outside of the format's DOM element:
+  // `a‸<strong>b</strong>` (DOM) while visually it's `a<strong>‸b</strong>`.
+  // So at a given selection index, start with the deepest format DOM element.
+  if (element.nodeType === element.TEXT_NODE && range.startOffset === element.length && element.nextSibling) {
+    element = element.nextSibling;
+    while (element.firstChild) {
+      element = element.firstChild;
+    }
+  }
+  if (element.nodeType !== element.ELEMENT_NODE) {
+    element = element.parentElement;
+  }
+  if (!element) {
+    return;
+  }
+  if (element === editableContentElement) {
+    return;
+  }
+  if (!editableContentElement.contains(element)) {
+    return;
+  }
+  const selector = tagName + (className ? '.' + className : '');
+
+  // .closest( selector ), but with a boundary. Check if the element matches
+  // the selector. If it doesn't match, try the parent element if it's not the
+  // editable wrapper. We don't want to try to match ancestors of the editable
+  // wrapper, which is what .closest( selector ) would do. When the element is
+  // the editable wrapper (which is most likely the case because most text is
+  // unformatted), this never runs.
+  while (element !== editableContentElement) {
+    if (element.matches(selector)) {
+      return element;
+    }
+    element = element.parentElement;
+  }
+}
+
+/**
+ * @typedef {Object} VirtualAnchorElement
+ * @property {() => DOMRect} getBoundingClientRect A function returning a DOMRect
+ * @property {HTMLElement}   contextElement        The actual DOM element
+ */
+
+/**
+ * Creates a virtual anchor element for a range.
+ *
+ * @param {Range}       range                  The range to create a virtual anchor element for.
+ * @param {HTMLElement} editableContentElement The editable wrapper.
+ *
+ * @return {VirtualAnchorElement} The virtual anchor element.
+ */
+function createVirtualAnchorElement(range, editableContentElement) {
+  return {
+    contextElement: editableContentElement,
+    getBoundingClientRect() {
+      return editableContentElement.contains(range.startContainer) ? range.getBoundingClientRect() : editableContentElement.getBoundingClientRect();
+    }
+  };
+}
+
+/**
+ * Get the anchor: a format element if there is a matching one based on the
+ * tagName and className or a range otherwise.
+ *
+ * @param {HTMLElement} editableContentElement The editable wrapper.
+ * @param {string}      tagName                The tag name of the format
+ *                                             element.
+ * @param {string}      className              The class name of the format
+ *                                             element.
+ *
+ * @return {HTMLElement|VirtualAnchorElement|undefined} The anchor.
+ */
+function getAnchor(editableContentElement, tagName, className) {
+  if (!editableContentElement) {
+    return;
+  }
+  const {
+    ownerDocument
+  } = editableContentElement;
+  const {
+    defaultView
+  } = ownerDocument;
+  const selection = defaultView.getSelection();
+  if (!selection) {
+    return;
+  }
+  if (!selection.rangeCount) {
+    return;
+  }
+  const range = selection.getRangeAt(0);
+  if (!range || !range.startContainer) {
+    return;
+  }
+  const formatElement = getFormatElement(range, editableContentElement, tagName, className);
+  if (formatElement) {
+    return formatElement;
+  }
+  return createVirtualAnchorElement(range, editableContentElement);
+}
+
+/**
+ * This hook, to be used in a format type's Edit component, returns the active
+ * element that is formatted, or a virtual element for the selection range if
+ * no format is active. The returned value is meant to be used for positioning
+ * UI, e.g. by passing it to the `Popover` component via the `anchor` prop.
+ *
+ * @param {Object}           $1                        Named parameters.
+ * @param {HTMLElement|null} $1.editableContentElement The element containing
+ *                                                     the editable content.
+ * @param {WPFormat=}        $1.settings               The format type's settings.
+ * @return {Element|VirtualAnchorElement|undefined|null} The active element or selection range.
+ */
+function useAnchor({
+  editableContentElement,
+  settings = {}
+}) {
+  const {
+    tagName,
+    className,
+    isActive
+  } = settings;
+  const [anchor, setAnchor] = (0,external_wp_element_namespaceObject.useState)(() => getAnchor(editableContentElement, tagName, className));
+  const wasActive = (0,external_wp_compose_namespaceObject.usePrevious)(isActive);
+  (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
+    if (!editableContentElement) {
+      return;
+    }
+    function callback() {
+      setAnchor(getAnchor(editableContentElement, tagName, className));
+    }
+    function attach() {
+      ownerDocument.addEventListener('selectionchange', callback);
+    }
+    function detach() {
+      ownerDocument.removeEventListener('selectionchange', callback);
+    }
+    const {
+      ownerDocument
+    } = editableContentElement;
+    if (editableContentElement === ownerDocument.activeElement ||
+    // When a link is created, we need to attach the popover to the newly created anchor.
+    !wasActive && isActive ||
+    // Sometimes we're _removing_ an active anchor, such as the inline color popover.
+    // When we add the color, it switches from a virtual anchor to a `<mark>` element.
+    // When we _remove_ the color, it switches from a `<mark>` element to a virtual anchor.
+    wasActive && !isActive) {
+      setAnchor(getAnchor(editableContentElement, tagName, className));
+      attach();
+    }
+    editableContentElement.addEventListener('focusin', attach);
+    editableContentElement.addEventListener('focusout', detach);
+    return () => {
+      detach();
+      editableContentElement.removeEventListener('focusin', attach);
+      editableContentElement.removeEventListener('focusout', detach);
+    };
+  }, [editableContentElement, tagName, className, isActive, wasActive]);
+  return anchor;
+}
+
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-default-style.js
 /**
  * WordPress dependencies
  */
 
+
 /**
  * In HTML, leading and trailing spaces are not visible, and multiple spaces
  * elsewhere are visually reduced to one space. This rule prevents spaces from
@@ -3774,17 +2970,18 @@
  *
  * @type {string}
  */
-
 const whiteSpace = 'pre-wrap';
+
 /**
  * A minimum width of 1px will prevent the rich text container from collapsing
  * to 0 width and hiding the caret. This is useful for inline containers.
  */
-
 const minWidth = '1px';
 function useDefaultStyle() {
   return (0,external_wp_element_namespaceObject.useCallback)(element => {
-    if (!element) return;
+    if (!element) {
+      return;
+    }
     element.style.whiteSpace = whiteSpace;
     element.style.minWidth = minWidth;
   }, []);
@@ -3795,33 +2992,32 @@
  * WordPress dependencies
  */
 
+
 /*
  * Calculates and renders the format boundary style when the active formats
  * change.
  */
-
-function useBoundaryStyle(_ref) {
-  let {
-    record
-  } = _ref;
+function useBoundaryStyle({
+  record
+}) {
   const ref = (0,external_wp_element_namespaceObject.useRef)();
   const {
-    activeFormats = []
+    activeFormats = [],
+    replacements,
+    start
   } = record.current;
+  const activeReplacement = replacements[start];
   (0,external_wp_element_namespaceObject.useEffect)(() => {
     // There's no need to recalculate the boundary styles if no formats are
     // active, because no boundary styles will be visible.
-    if (!activeFormats || !activeFormats.length) {
+    if ((!activeFormats || !activeFormats.length) && !activeReplacement) {
       return;
     }
-
     const boundarySelector = '*[data-rich-text-format-boundary]';
     const element = ref.current.querySelector(boundarySelector);
-
     if (!element) {
       return;
     }
-
     const {
       ownerDocument
     } = element;
@@ -3835,21 +3031,111 @@
     const style = `${selector} {${rule}}`;
     const globalStyleId = 'rich-text-boundary-style';
     let globalStyle = ownerDocument.getElementById(globalStyleId);
-
     if (!globalStyle) {
       globalStyle = ownerDocument.createElement('style');
       globalStyle.id = globalStyleId;
       ownerDocument.head.appendChild(globalStyle);
     }
-
     if (globalStyle.innerHTML !== style) {
       globalStyle.innerHTML = style;
     }
-  }, [activeFormats]);
+  }, [activeFormats, activeReplacement]);
   return ref;
 }
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-copy-handler.js
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/copy-handler.js
+/**
+ * Internal dependencies
+ */
+
+
+
+
+/* harmony default export */ const copy_handler = (props => element => {
+  function onCopy(event) {
+    const {
+      record
+    } = props.current;
+    const {
+      ownerDocument
+    } = element;
+    if (isCollapsed(record.current) || !element.contains(ownerDocument.activeElement)) {
+      return;
+    }
+    const selectedRecord = slice(record.current);
+    const plainText = getTextContent(selectedRecord);
+    const html = toHTMLString({
+      value: selectedRecord
+    });
+    event.clipboardData.setData('text/plain', plainText);
+    event.clipboardData.setData('text/html', html);
+    event.clipboardData.setData('rich-text', 'true');
+    event.preventDefault();
+    if (event.type === 'cut') {
+      ownerDocument.execCommand('delete');
+    }
+  }
+  const {
+    defaultView
+  } = element.ownerDocument;
+  defaultView.addEventListener('copy', onCopy);
+  defaultView.addEventListener('cut', onCopy);
+  return () => {
+    defaultView.removeEventListener('copy', onCopy);
+    defaultView.removeEventListener('cut', onCopy);
+  };
+});
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/select-object.js
+/* harmony default export */ const select_object = (() => element => {
+  function onClick(event) {
+    const {
+      target
+    } = event;
+
+    // If the child element has no text content, it must be an object.
+    if (target === element || target.textContent && target.isContentEditable) {
+      return;
+    }
+    const {
+      ownerDocument
+    } = target;
+    const {
+      defaultView
+    } = ownerDocument;
+    const selection = defaultView.getSelection();
+
+    // If it's already selected, do nothing and let default behavior happen.
+    // This means it's "click-through".
+    if (selection.containsNode(target)) {
+      return;
+    }
+    const range = ownerDocument.createRange();
+    // If the target is within a non editable element, select the non
+    // editable element.
+    const nodeToSelect = target.isContentEditable ? target : target.closest('[contenteditable]');
+    range.selectNode(nodeToSelect);
+    selection.removeAllRanges();
+    selection.addRange(range);
+    event.preventDefault();
+  }
+  function onFocusIn(event) {
+    // When there is incoming focus from a link, select the object.
+    if (event.relatedTarget && !element.contains(event.relatedTarget) && event.relatedTarget.tagName === 'A') {
+      onClick(event);
+    }
+  }
+  element.addEventListener('click', onClick);
+  element.addEventListener('focusin', onFocusIn);
+  return () => {
+    element.removeEventListener('click', onClick);
+    element.removeEventListener('focusin', onFocusIn);
+  };
+});
+
+;// CONCATENATED MODULE: external ["wp","keycodes"]
+const external_wp_keycodes_namespaceObject = window["wp"]["keycodes"];
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/format-boundaries.js
 /**
  * WordPress dependencies
  */
@@ -3859,269 +3145,150 @@
  * Internal dependencies
  */
 
-
-
-
-
-function useCopyHandler(props) {
-  const propsRef = (0,external_wp_element_namespaceObject.useRef)(props);
-  propsRef.current = props;
-  return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
-    function onCopy(event) {
-      const {
-        record,
-        multilineTag,
-        preserveWhiteSpace
-      } = propsRef.current;
-
-      if (isCollapsed(record.current) || !element.contains(element.ownerDocument.activeElement)) {
+const EMPTY_ACTIVE_FORMATS = [];
+/* harmony default export */ const format_boundaries = (props => element => {
+  function onKeyDown(event) {
+    const {
+      keyCode,
+      shiftKey,
+      altKey,
+      metaKey,
+      ctrlKey
+    } = event;
+    if (
+    // Only override left and right keys without modifiers pressed.
+    shiftKey || altKey || metaKey || ctrlKey || keyCode !== external_wp_keycodes_namespaceObject.LEFT && keyCode !== external_wp_keycodes_namespaceObject.RIGHT) {
+      return;
+    }
+    const {
+      record,
+      applyRecord,
+      forceRender
+    } = props.current;
+    const {
+      text,
+      formats,
+      start,
+      end,
+      activeFormats: currentActiveFormats = []
+    } = record.current;
+    const collapsed = isCollapsed(record.current);
+    const {
+      ownerDocument
+    } = element;
+    const {
+      defaultView
+    } = ownerDocument;
+    // To do: ideally, we should look at visual position instead.
+    const {
+      direction
+    } = defaultView.getComputedStyle(element);
+    const reverseKey = direction === 'rtl' ? external_wp_keycodes_namespaceObject.RIGHT : external_wp_keycodes_namespaceObject.LEFT;
+    const isReverse = event.keyCode === reverseKey;
+
+    // If the selection is collapsed and at the very start, do nothing if
+    // navigating backward.
+    // If the selection is collapsed and at the very end, do nothing if
+    // navigating forward.
+    if (collapsed && currentActiveFormats.length === 0) {
+      if (start === 0 && isReverse) {
         return;
       }
-
-      const selectedRecord = slice(record.current);
-      const plainText = getTextContent(selectedRecord);
-      const html = toHTMLString({
-        value: selectedRecord,
-        multilineTag,
-        preserveWhiteSpace
-      });
-      event.clipboardData.setData('text/plain', plainText);
-      event.clipboardData.setData('text/html', html);
-      event.clipboardData.setData('rich-text', 'true');
-      event.clipboardData.setData('rich-text-multi-line-tag', multilineTag || '');
-      event.preventDefault();
+      if (end === text.length && !isReverse) {
+        return;
+      }
+    }
+
+    // If the selection is not collapsed, let the browser handle collapsing
+    // the selection for now. Later we could expand this logic to set
+    // boundary positions if needed.
+    if (!collapsed) {
+      return;
+    }
+    const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS;
+    const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS;
+    const destination = isReverse ? formatsBefore : formatsAfter;
+    const isIncreasing = currentActiveFormats.every((format, index) => format === destination[index]);
+    let newActiveFormatsLength = currentActiveFormats.length;
+    if (!isIncreasing) {
+      newActiveFormatsLength--;
+    } else if (newActiveFormatsLength < destination.length) {
+      newActiveFormatsLength++;
     }
-
-    element.addEventListener('copy', onCopy);
-    return () => {
-      element.removeEventListener('copy', onCopy);
+    if (newActiveFormatsLength === currentActiveFormats.length) {
+      record.current._newActiveFormats = destination;
+      return;
+    }
+    event.preventDefault();
+    const origin = isReverse ? formatsAfter : formatsBefore;
+    const source = isIncreasing ? destination : origin;
+    const newActiveFormats = source.slice(0, newActiveFormatsLength);
+    const newValue = {
+      ...record.current,
+      activeFormats: newActiveFormats
     };
-  }, []);
-}
-
-;// CONCATENATED MODULE: external ["wp","keycodes"]
-var external_wp_keycodes_namespaceObject = window["wp"]["keycodes"];
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-format-boundaries.js
+    record.current = newValue;
+    applyRecord(newValue);
+    forceRender();
+  }
+  element.addEventListener('keydown', onKeyDown);
+  return () => {
+    element.removeEventListener('keydown', onKeyDown);
+  };
+});
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/delete.js
 /**
  * WordPress dependencies
  */
 
 
-
 /**
  * Internal dependencies
  */
 
-
-const EMPTY_ACTIVE_FORMATS = [];
-function useFormatBoundaries(props) {
-  const [, forceRender] = (0,external_wp_element_namespaceObject.useReducer)(() => ({}));
-  const propsRef = (0,external_wp_element_namespaceObject.useRef)(props);
-  propsRef.current = props;
-  return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
-    function onKeyDown(event) {
-      const {
-        keyCode,
-        shiftKey,
-        altKey,
-        metaKey,
-        ctrlKey
-      } = event;
-
-      if ( // Only override left and right keys without modifiers pressed.
-      shiftKey || altKey || metaKey || ctrlKey || keyCode !== external_wp_keycodes_namespaceObject.LEFT && keyCode !== external_wp_keycodes_namespaceObject.RIGHT) {
-        return;
-      }
-
-      const {
-        record,
-        applyRecord
-      } = propsRef.current;
-      const {
-        text,
-        formats,
-        start,
-        end,
-        activeFormats: currentActiveFormats = []
-      } = record.current;
-      const collapsed = isCollapsed(record.current);
-      const {
-        ownerDocument
-      } = element;
-      const {
-        defaultView
-      } = ownerDocument; // To do: ideally, we should look at visual position instead.
-
-      const {
-        direction
-      } = defaultView.getComputedStyle(element);
-      const reverseKey = direction === 'rtl' ? external_wp_keycodes_namespaceObject.RIGHT : external_wp_keycodes_namespaceObject.LEFT;
-      const isReverse = event.keyCode === reverseKey; // If the selection is collapsed and at the very start, do nothing if
-      // navigating backward.
-      // If the selection is collapsed and at the very end, do nothing if
-      // navigating forward.
-
-      if (collapsed && currentActiveFormats.length === 0) {
-        if (start === 0 && isReverse) {
-          return;
-        }
-
-        if (end === text.length && !isReverse) {
-          return;
-        }
-      } // If the selection is not collapsed, let the browser handle collapsing
-      // the selection for now. Later we could expand this logic to set
-      // boundary positions if needed.
-
-
-      if (!collapsed) {
-        return;
-      }
-
-      const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS;
-      const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS;
-      const destination = isReverse ? formatsBefore : formatsAfter;
-      const isIncreasing = currentActiveFormats.every((format, index) => format === destination[index]);
-      let newActiveFormatsLength = currentActiveFormats.length;
-
-      if (!isIncreasing) {
-        newActiveFormatsLength--;
-      } else if (newActiveFormatsLength < destination.length) {
-        newActiveFormatsLength++;
-      }
-
-      if (newActiveFormatsLength === currentActiveFormats.length) {
-        record.current._newActiveFormats = destination;
-        return;
-      }
-
-      event.preventDefault();
-      const origin = isReverse ? formatsAfter : formatsBefore;
-      const source = isIncreasing ? destination : origin;
-      const newActiveFormats = source.slice(0, newActiveFormatsLength);
-      const newValue = { ...record.current,
-        activeFormats: newActiveFormats
-      };
-      record.current = newValue;
-      applyRecord(newValue);
-      forceRender();
+/* harmony default export */ const event_listeners_delete = (props => element => {
+  function onKeyDown(event) {
+    const {
+      keyCode
+    } = event;
+    const {
+      createRecord,
+      handleChange
+    } = props.current;
+    if (event.defaultPrevented) {
+      return;
     }
-
-    element.addEventListener('keydown', onKeyDown);
-    return () => {
-      element.removeEventListener('keydown', onKeyDown);
-    };
-  }, []);
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-select-object.js
-/**
- * WordPress dependencies
- */
-
-function useSelectObject() {
-  return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
-    function onClick(event) {
-      const {
-        target
-      } = event; // If the child element has no text content, it must be an object.
-
-      if (target === element || target.textContent) {
-        return;
-      }
-
-      const {
-        ownerDocument
-      } = target;
-      const {
-        defaultView
-      } = ownerDocument;
-      const range = ownerDocument.createRange();
-      const selection = defaultView.getSelection();
-      range.selectNode(target);
-      selection.removeAllRanges();
-      selection.addRange(range);
+    if (keyCode !== external_wp_keycodes_namespaceObject.DELETE && keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE) {
+      return;
     }
-
-    element.addEventListener('click', onClick);
-    return () => {
-      element.removeEventListener('click', onClick);
-    };
-  }, []);
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-indent-list-item-on-space.js
-/**
- * WordPress dependencies
- */
-
-
-
-/**
- * Internal dependencies
- */
-
-
-
-
-function useIndentListItemOnSpace(props) {
-  const propsRef = (0,external_wp_element_namespaceObject.useRef)(props);
-  propsRef.current = props;
-  return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
-    function onKeyDown(event) {
-      const {
-        keyCode,
-        shiftKey,
-        altKey,
-        metaKey,
-        ctrlKey
-      } = event;
-      const {
-        multilineTag,
-        createRecord,
-        handleChange
-      } = propsRef.current;
-
-      if ( // Only override when no modifiers are pressed.
-      shiftKey || altKey || metaKey || ctrlKey || keyCode !== external_wp_keycodes_namespaceObject.SPACE || multilineTag !== 'li') {
-        return;
-      }
-
-      const currentValue = createRecord();
-
-      if (!isCollapsed(currentValue)) {
-        return;
-      }
-
-      const {
-        text,
-        start
-      } = currentValue;
-      const characterBefore = text[start - 1]; // The caret must be at the start of a line.
-
-      if (characterBefore && characterBefore !== LINE_SEPARATOR) {
-        return;
-      }
-
-      handleChange(indentListItems(currentValue, {
-        type: element.tagName.toLowerCase()
-      }));
+    const currentValue = createRecord();
+    const {
+      start,
+      end,
+      text
+    } = currentValue;
+
+    // Always handle full content deletion ourselves.
+    if (start === 0 && end !== 0 && end === text.length) {
+      handleChange(remove_remove(currentValue));
       event.preventDefault();
     }
-
-    element.addEventListener('keydown', onKeyDown);
-    return () => {
-      element.removeEventListener('keydown', onKeyDown);
-    };
-  }, []);
-}
+  }
+  element.addEventListener('keydown', onKeyDown);
+  return () => {
+    element.removeEventListener('keydown', onKeyDown);
+  };
+});
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/update-formats.js
 /**
  * Internal dependencies
  */
 
-/** @typedef {import('./create').RichTextValue} RichTextValue */
+
+
+/** @typedef {import('./types').RichTextValue} RichTextValue */
 
 /**
  * Efficiently updates all the formats from `start` (including) until `end`
@@ -4135,21 +3302,20 @@
  *
  * @return {RichTextValue} Mutated value.
  */
-
-function updateFormats(_ref) {
-  let {
-    value,
-    start,
-    end,
-    formats
-  } = _ref;
+function updateFormats({
+  value,
+  start,
+  end,
+  formats
+}) {
   // Start and end may be switched in case of delete.
   const min = Math.min(start, end);
   const max = Math.max(start, end);
   const formatsBefore = value.formats[min - 1] || [];
-  const formatsAfter = value.formats[max] || []; // First, fix the references. If any format right before or after are
+  const formatsAfter = value.formats[max] || [];
+
+  // First, fix the references. If any format right before or after are
   // equal, the replacement format should use the same reference.
-
   value.activeFormats = formats.map((format, index) => {
     if (formatsBefore[index]) {
       if (isFormatEqual(format, formatsBefore[index])) {
@@ -4160,10 +3326,8 @@
         return formatsAfter[index];
       }
     }
-
     return format;
   });
-
   while (--end >= start) {
     if (value.activeFormats.length > 0) {
       value.formats[end] = value.activeFormats;
@@ -4171,16 +3335,10 @@
       delete value.formats[end];
     }
   }
-
   return value;
 }
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-input-and-selection.js
-/**
- * WordPress dependencies
- */
-
-
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/input-and-selection.js
 /**
  * Internal dependencies
  */
@@ -4194,295 +3352,280 @@
  *
  * @type {Set}
  */
-
 const INSERTION_INPUT_TYPES_TO_IGNORE = new Set(['insertParagraph', 'insertOrderedList', 'insertUnorderedList', 'insertHorizontalRule', 'insertLink']);
-const use_input_and_selection_EMPTY_ACTIVE_FORMATS = [];
+const input_and_selection_EMPTY_ACTIVE_FORMATS = [];
+const PLACEHOLDER_ATTR_NAME = 'data-rich-text-placeholder';
+
 /**
  * If the selection is set on the placeholder element, collapse the selection to
  * the start (before the placeholder).
  *
  * @param {Window} defaultView
  */
-
 function fixPlaceholderSelection(defaultView) {
   const selection = defaultView.getSelection();
   const {
     anchorNode,
     anchorOffset
   } = selection;
-
   if (anchorNode.nodeType !== anchorNode.ELEMENT_NODE) {
     return;
   }
-
   const targetNode = anchorNode.childNodes[anchorOffset];
-
-  if (!targetNode || targetNode.nodeType !== targetNode.ELEMENT_NODE || !targetNode.getAttribute('data-rich-text-placeholder')) {
+  if (!targetNode || targetNode.nodeType !== targetNode.ELEMENT_NODE || !targetNode.hasAttribute(PLACEHOLDER_ATTR_NAME)) {
     return;
   }
-
   selection.collapseToStart();
 }
-
-function useInputAndSelection(props) {
-  const propsRef = (0,external_wp_element_namespaceObject.useRef)(props);
-  propsRef.current = props;
-  return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
+/* harmony default export */ const input_and_selection = (props => element => {
+  const {
+    ownerDocument
+  } = element;
+  const {
+    defaultView
+  } = ownerDocument;
+  let isComposing = false;
+  function onInput(event) {
+    // Do not trigger a change if characters are being composed. Browsers
+    // will usually emit a final `input` event when the characters are
+    // composed. As of December 2019, Safari doesn't support
+    // nativeEvent.isComposing.
+    if (isComposing) {
+      return;
+    }
+    let inputType;
+    if (event) {
+      inputType = event.inputType;
+    }
     const {
-      ownerDocument
-    } = element;
+      record,
+      applyRecord,
+      createRecord,
+      handleChange
+    } = props.current;
+
+    // The browser formatted something or tried to insert HTML. Overwrite
+    // it. It will be handled later by the format library if needed.
+    if (inputType && (inputType.indexOf('format') === 0 || INSERTION_INPUT_TYPES_TO_IGNORE.has(inputType))) {
+      applyRecord(record.current);
+      return;
+    }
+    const currentValue = createRecord();
     const {
-      defaultView
-    } = ownerDocument;
-    let isComposing = false;
-    let rafId;
-
-    function onInput(event) {
-      // Do not trigger a change if characters are being composed.
-      // Browsers  will usually emit a final `input` event when the
-      // characters are composed.
-      // As of December 2019, Safari doesn't support
-      // nativeEvent.isComposing.
-      if (isComposing) {
-        return;
-      }
-
-      let inputType;
-
-      if (event) {
-        inputType = event.inputType;
+      start,
+      activeFormats: oldActiveFormats = []
+    } = record.current;
+
+    // Update the formats between the last and new caret position.
+    const change = updateFormats({
+      value: currentValue,
+      start,
+      end: currentValue.start,
+      formats: oldActiveFormats
+    });
+    handleChange(change);
+  }
+
+  /**
+   * Syncs the selection to local state. A callback for the `selectionchange`
+   * event.
+   */
+  function handleSelectionChange() {
+    const {
+      record,
+      applyRecord,
+      createRecord,
+      onSelectionChange
+    } = props.current;
+
+    // Check if the implementor disabled editing. `contentEditable` does
+    // disable input, but not text selection, so we must ignore selection
+    // changes.
+    if (element.contentEditable !== 'true') {
+      return;
+    }
+
+    // Ensure the active element is the rich text element.
+    if (ownerDocument.activeElement !== element) {
+      // If it is not, we can stop listening for selection changes. We
+      // resume listening when the element is focused.
+      ownerDocument.removeEventListener('selectionchange', handleSelectionChange);
+      return;
+    }
+
+    // In case of a keyboard event, ignore selection changes during
+    // composition.
+    if (isComposing) {
+      return;
+    }
+    const {
+      start,
+      end,
+      text
+    } = createRecord();
+    const oldRecord = record.current;
+
+    // Fallback mechanism for IE11, which doesn't support the input event.
+    // Any input results in a selection change.
+    if (text !== oldRecord.text) {
+      onInput();
+      return;
+    }
+    if (start === oldRecord.start && end === oldRecord.end) {
+      // Sometimes the browser may set the selection on the placeholder
+      // element, in which case the caret is not visible. We need to set
+      // the caret before the placeholder if that's the case.
+      if (oldRecord.text.length === 0 && start === 0) {
+        fixPlaceholderSelection(defaultView);
       }
-
-      const {
-        record,
-        applyRecord,
-        createRecord,
-        handleChange
-      } = propsRef.current; // The browser formatted something or tried to insert HTML.
-      // Overwrite it. It will be handled later by the format library if
-      // needed.
-
-      if (inputType && (inputType.indexOf('format') === 0 || INSERTION_INPUT_TYPES_TO_IGNORE.has(inputType))) {
-        applyRecord(record.current);
-        return;
-      }
-
-      const currentValue = createRecord();
-      const {
-        start,
-        activeFormats: oldActiveFormats = []
-      } = record.current; // Update the formats between the last and new caret position.
-
-      const change = updateFormats({
-        value: currentValue,
-        start,
-        end: currentValue.start,
-        formats: oldActiveFormats
-      });
-      handleChange(change);
+      return;
     }
-    /**
-     * Syncs the selection to local state. A callback for the `selectionchange`
-     * native events, `keyup`, `mouseup` and `touchend` synthetic events, and
-     * animation frames after the `focus` event.
-     *
-     * @param {Event|DOMHighResTimeStamp} event
-     */
-
-
-    function handleSelectionChange(event) {
-      const {
-        record,
-        applyRecord,
-        createRecord,
-        isSelected,
-        onSelectionChange
-      } = propsRef.current; // Check if the implementor disabled editing. `contentEditable`
-      // does disable input, but not text selection, so we must ignore
-      // selection changes.
-
-      if (element.contentEditable !== 'true') {
-        return;
-      } // If the selection changes where the active element is a parent of
-      // the rich text instance (writing flow), call `onSelectionChange`
-      // for the rich text instance that contains the start or end of the
-      // selection.
-
-
-      if (ownerDocument.activeElement !== element) {
-        if (!ownerDocument.activeElement.contains(element)) {
-          return;
-        }
-
-        const selection = defaultView.getSelection();
-        const {
-          anchorNode,
-          focusNode
-        } = selection;
-
-        if (element.contains(anchorNode) && element !== anchorNode && element.contains(focusNode) && element !== focusNode) {
-          const {
-            start,
-            end
-          } = createRecord();
-          record.current.activeFormats = use_input_and_selection_EMPTY_ACTIVE_FORMATS;
-          onSelectionChange(start, end);
-        } else if (element.contains(anchorNode) && element !== anchorNode) {
-          const {
-            start,
-            end: offset = start
-          } = createRecord();
-          record.current.activeFormats = use_input_and_selection_EMPTY_ACTIVE_FORMATS;
-          onSelectionChange(offset);
-        } else if (element.contains(focusNode) && element !== focusNode) {
-          const {
-            start,
-            end: offset = start
-          } = createRecord();
-          record.current.activeFormats = use_input_and_selection_EMPTY_ACTIVE_FORMATS;
-          onSelectionChange(undefined, offset);
-        }
-
+    const newValue = {
+      ...oldRecord,
+      start,
+      end,
+      // _newActiveFormats may be set on arrow key navigation to control
+      // the right boundary position. If undefined, getActiveFormats will
+      // give the active formats according to the browser.
+      activeFormats: oldRecord._newActiveFormats,
+      _newActiveFormats: undefined
+    };
+    const newActiveFormats = getActiveFormats(newValue, input_and_selection_EMPTY_ACTIVE_FORMATS);
+
+    // Update the value with the new active formats.
+    newValue.activeFormats = newActiveFormats;
+
+    // It is important that the internal value is updated first,
+    // otherwise the value will be wrong on render!
+    record.current = newValue;
+    applyRecord(newValue, {
+      domOnly: true
+    });
+    onSelectionChange(start, end);
+  }
+  function onCompositionStart() {
+    isComposing = true;
+    // Do not update the selection when characters are being composed as
+    // this rerenders the component and might destroy internal browser
+    // editing state.
+    ownerDocument.removeEventListener('selectionchange', handleSelectionChange);
+    // Remove the placeholder. Since the rich text value doesn't update
+    // during composition, the placeholder doesn't get removed. There's no
+    // need to re-add it, when the value is updated on compositionend it
+    // will be re-added when the value is empty.
+    element.querySelector(`[${PLACEHOLDER_ATTR_NAME}]`)?.remove();
+  }
+  function onCompositionEnd() {
+    isComposing = false;
+    // Ensure the value is up-to-date for browsers that don't emit a final
+    // input event after composition.
+    onInput({
+      inputType: 'insertText'
+    });
+    // Tracking selection changes can be resumed.
+    ownerDocument.addEventListener('selectionchange', handleSelectionChange);
+  }
+  function onFocus() {
+    const {
+      record,
+      isSelected,
+      onSelectionChange,
+      applyRecord
+    } = props.current;
+
+    // When the whole editor is editable, let writing flow handle
+    // selection.
+    if (element.parentElement.closest('[contenteditable="true"]')) {
+      return;
+    }
+    if (!isSelected) {
+      // We know for certain that on focus, the old selection is invalid.
+      // It will be recalculated on the next mouseup, keyup, or touchend
+      // event.
+      const index = undefined;
+      record.current = {
+        ...record.current,
+        start: index,
+        end: index,
+        activeFormats: input_and_selection_EMPTY_ACTIVE_FORMATS
+      };
+    } else {
+      applyRecord(record.current, {
+        domOnly: true
+      });
+    }
+    onSelectionChange(record.current.start, record.current.end);
+
+    // There is no selection change event when the element is focused, so
+    // we need to manually trigger it. The selection is also not available
+    // yet in this call stack.
+    window.queueMicrotask(handleSelectionChange);
+    ownerDocument.addEventListener('selectionchange', handleSelectionChange);
+  }
+  element.addEventListener('input', onInput);
+  element.addEventListener('compositionstart', onCompositionStart);
+  element.addEventListener('compositionend', onCompositionEnd);
+  element.addEventListener('focus', onFocus);
+  return () => {
+    element.removeEventListener('input', onInput);
+    element.removeEventListener('compositionstart', onCompositionStart);
+    element.removeEventListener('compositionend', onCompositionEnd);
+    element.removeEventListener('focus', onFocus);
+  };
+});
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/selection-change-compat.js
+/**
+ * Internal dependencies
+ */
+
+
+/**
+ * Sometimes some browsers are not firing a `selectionchange` event when
+ * changing the selection by mouse or keyboard. This hook makes sure that, if we
+ * detect no `selectionchange` or `input` event between the up and down events,
+ * we fire a `selectionchange` event.
+ */
+/* harmony default export */ const selection_change_compat = (() => element => {
+  const {
+    ownerDocument
+  } = element;
+  const {
+    defaultView
+  } = ownerDocument;
+  const selection = defaultView?.getSelection();
+  let range;
+  function getRange() {
+    return selection.rangeCount ? selection.getRangeAt(0) : null;
+  }
+  function onDown(event) {
+    const type = event.type === 'keydown' ? 'keyup' : 'pointerup';
+    function onCancel() {
+      ownerDocument.removeEventListener(type, onUp);
+      ownerDocument.removeEventListener('selectionchange', onCancel);
+      ownerDocument.removeEventListener('input', onCancel);
+    }
+    function onUp() {
+      onCancel();
+      if (isRangeEqual(range, getRange())) {
         return;
       }
-
-      if (event.type !== 'selectionchange' && !isSelected) {
-        return;
-      } // In case of a keyboard event, ignore selection changes during
-      // composition.
-
-
-      if (isComposing) {
-        return;
-      }
-
-      const {
-        start,
-        end,
-        text
-      } = createRecord();
-      const oldRecord = record.current; // Fallback mechanism for IE11, which doesn't support the input event.
-      // Any input results in a selection change.
-
-      if (text !== oldRecord.text) {
-        onInput();
-        return;
-      }
-
-      if (start === oldRecord.start && end === oldRecord.end) {
-        // Sometimes the browser may set the selection on the placeholder
-        // element, in which case the caret is not visible. We need to set
-        // the caret before the placeholder if that's the case.
-        if (oldRecord.text.length === 0 && start === 0) {
-          fixPlaceholderSelection(defaultView);
-        }
-
-        return;
-      }
-
-      const newValue = { ...oldRecord,
-        start,
-        end,
-        // _newActiveFormats may be set on arrow key navigation to control
-        // the right boundary position. If undefined, getActiveFormats will
-        // give the active formats according to the browser.
-        activeFormats: oldRecord._newActiveFormats,
-        _newActiveFormats: undefined
-      };
-      const newActiveFormats = getActiveFormats(newValue, use_input_and_selection_EMPTY_ACTIVE_FORMATS); // Update the value with the new active formats.
-
-      newValue.activeFormats = newActiveFormats; // It is important that the internal value is updated first,
-      // otherwise the value will be wrong on render!
-
-      record.current = newValue;
-      applyRecord(newValue, {
-        domOnly: true
-      });
-      onSelectionChange(start, end);
-    }
-
-    function onCompositionStart() {
-      isComposing = true; // Do not update the selection when characters are being composed as
-      // this rerenders the component and might destroy internal browser
-      // editing state.
-
-      ownerDocument.removeEventListener('selectionchange', handleSelectionChange);
+      ownerDocument.dispatchEvent(new Event('selectionchange'));
     }
-
-    function onCompositionEnd() {
-      isComposing = false; // Ensure the value is up-to-date for browsers that don't emit a final
-      // input event after composition.
-
-      onInput({
-        inputType: 'insertText'
-      }); // Tracking selection changes can be resumed.
-
-      ownerDocument.addEventListener('selectionchange', handleSelectionChange);
-    }
-
-    function onFocus() {
-      const {
-        record,
-        isSelected,
-        onSelectionChange,
-        applyRecord
-      } = propsRef.current; // When the whole editor is editable, let writing flow handle
-      // selection.
-
-      if (element.parentElement.closest('[contenteditable="true"]')) {
-        return;
-      }
-
-      if (!isSelected) {
-        // We know for certain that on focus, the old selection is invalid.
-        // It will be recalculated on the next mouseup, keyup, or touchend
-        // event.
-        const index = undefined;
-        record.current = { ...record.current,
-          start: index,
-          end: index,
-          activeFormats: use_input_and_selection_EMPTY_ACTIVE_FORMATS
-        };
-        onSelectionChange(index, index);
-      } else {
-        applyRecord(record.current);
-        onSelectionChange(record.current.start, record.current.end);
-      } // Update selection as soon as possible, which is at the next animation
-      // frame. The event listener for selection changes may be added too late
-      // at this point, but this focus event is still too early to calculate
-      // the selection.
-
-
-      rafId = defaultView.requestAnimationFrame(handleSelectionChange);
-    }
-
-    element.addEventListener('input', onInput);
-    element.addEventListener('compositionstart', onCompositionStart);
-    element.addEventListener('compositionend', onCompositionEnd);
-    element.addEventListener('focus', onFocus); // Selection updates must be done at these events as they
-    // happen before the `selectionchange` event. In some cases,
-    // the `selectionchange` event may not even fire, for
-    // example when the window receives focus again on click.
-
-    element.addEventListener('keyup', handleSelectionChange);
-    element.addEventListener('mouseup', handleSelectionChange);
-    element.addEventListener('touchend', handleSelectionChange);
-    ownerDocument.addEventListener('selectionchange', handleSelectionChange);
-    return () => {
-      element.removeEventListener('input', onInput);
-      element.removeEventListener('compositionstart', onCompositionStart);
-      element.removeEventListener('compositionend', onCompositionEnd);
-      element.removeEventListener('focus', onFocus);
-      element.removeEventListener('keyup', handleSelectionChange);
-      element.removeEventListener('mouseup', handleSelectionChange);
-      element.removeEventListener('touchend', handleSelectionChange);
-      ownerDocument.removeEventListener('selectionchange', handleSelectionChange);
-      defaultView.cancelAnimationFrame(rafId);
-    };
-  }, []);
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-delete.js
+    ownerDocument.addEventListener(type, onUp);
+    ownerDocument.addEventListener('selectionchange', onCancel);
+    ownerDocument.addEventListener('input', onCancel);
+    range = getRange();
+  }
+  element.addEventListener('pointerdown', onDown);
+  element.addEventListener('keydown', onDown);
+  return () => {
+    element.removeEventListener('pointerdown', onDown);
+    element.removeEventListener('keydown', onDown);
+  };
+});
+
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/event-listeners/index.js
 /**
  * WordPress dependencies
  */
@@ -4496,135 +3639,19 @@
 
 
 
-function useDelete(props) {
+
+
+const allEventListeners = [copy_handler, select_object, format_boundaries, event_listeners_delete, input_and_selection, selection_change_compat];
+function useEventListeners(props) {
   const propsRef = (0,external_wp_element_namespaceObject.useRef)(props);
   propsRef.current = props;
+  const refEffects = (0,external_wp_element_namespaceObject.useMemo)(() => allEventListeners.map(refEffect => refEffect(propsRef)), [propsRef]);
   return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
-    function onKeyDown(event) {
-      const {
-        keyCode
-      } = event;
-      const {
-        createRecord,
-        handleChange,
-        multilineTag
-      } = propsRef.current;
-
-      if (event.defaultPrevented) {
-        return;
-      }
-
-      if (keyCode !== external_wp_keycodes_namespaceObject.DELETE && keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE) {
-        return;
-      }
-
-      const currentValue = createRecord();
-      const {
-        start,
-        end,
-        text
-      } = currentValue;
-      const isReverse = keyCode === external_wp_keycodes_namespaceObject.BACKSPACE; // Always handle full content deletion ourselves.
-
-      if (start === 0 && end !== 0 && end === text.length) {
-        handleChange(remove(currentValue));
-        event.preventDefault();
-        return;
-      }
-
-      if (multilineTag) {
-        let newValue; // Check to see if we should remove the first item if empty.
-
-        if (isReverse && currentValue.start === 0 && currentValue.end === 0 && isEmptyLine(currentValue)) {
-          newValue = removeLineSeparator(currentValue, !isReverse);
-        } else {
-          newValue = removeLineSeparator(currentValue, isReverse);
-        }
-
-        if (newValue) {
-          handleChange(newValue);
-          event.preventDefault();
-        }
-      }
-    }
-
-    element.addEventListener('keydown', onKeyDown);
+    const cleanups = refEffects.map(effect => effect(element));
     return () => {
-      element.removeEventListener('keydown', onKeyDown);
+      cleanups.forEach(cleanup => cleanup());
     };
-  }, []);
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/use-space.js
-/**
- * WordPress dependencies
- */
-
-
-/**
- * For some elements like BUTTON and SUMMARY, the space key doesn't insert a
- * space character in some browsers even though the element is editable. We have
- * to manually insert a space and prevent default behaviour.
- *
- * DO NOT limit this behaviour to specific tag names! It would mean that this
- * behaviour is not widely tested. If there's ever any problems, we should find
- * a different solution entirely or remove it entirely.
- */
-
-function useSpace() {
-  return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
-    function onKeyDown(event) {
-      // Don't insert a space if default behaviour is prevented.
-      if (event.defaultPrevented) {
-        return;
-      }
-
-      const {
-        keyCode,
-        altKey,
-        metaKey,
-        ctrlKey,
-        key
-      } = event; // Only consider the space key without modifiers pressed.
-
-      if (keyCode !== external_wp_keycodes_namespaceObject.SPACE || altKey || metaKey || ctrlKey) {
-        return;
-      } // Disregard character composition that involves the Space key.
-      //
-      // @see https://github.com/WordPress/gutenberg/issues/35086
-      //
-      // For example, to input a standalone diacritic (like ´ or `) using a
-      // keyboard with dead keys, one must first press the dead key and then
-      // press the Space key.
-      //
-      // Many operating systems handle this in such a way that the second
-      // KeyboardEvent contains the property `keyCode: 229`. According to the
-      // spec, 229 allows the system to indicate that an Input Method Editor
-      // (IDE) is processing some key input.
-      //
-      // However, Windows doesn't use `keyCode: 229` for dead key composition,
-      // instead emitting an event with values `keyCode: SPACE` and `key: '´'`.
-      // That is why checking the `key` property for values other than `SPACE`
-      // is important.
-      //
-      // This should serve as a reminder that the `KeyboardEvent.keyCode`
-      // attribute is officially deprecated and that we should consider more
-      // consistent interfaces.
-
-
-      if (key !== ' ') {
-        return;
-      }
-
-      event.target.ownerDocument.execCommand('insertText', false, ' ');
-      event.preventDefault();
-    }
-
-    element.addEventListener('keydown', onKeyDown);
-    return () => {
-      element.removeEventListener('keydown', onKeyDown);
-    };
-  }, []);
+  }, [refEffects]);
 }
 
 ;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/index.js
@@ -4634,6 +3661,7 @@
 
 
 
+
 /**
  * Internal dependencies
  */
@@ -4643,34 +3671,24 @@
 
 
 
-
-
-
-
-
-
-
-function useRichText(_ref) {
-  let {
-    value = '',
-    selectionStart,
-    selectionEnd,
-    placeholder,
-    preserveWhiteSpace,
-    onSelectionChange,
-    onChange,
-    __unstableMultilineTag: multilineTag,
-    __unstableDisableFormats: disableFormats,
-    __unstableIsSelected: isSelected,
-    __unstableDependencies = [],
-    __unstableAfterParse,
-    __unstableBeforeSerialize,
-    __unstableAddInvisibleFormats
-  } = _ref;
+function useRichText({
+  value = '',
+  selectionStart,
+  selectionEnd,
+  placeholder,
+  onSelectionChange,
+  preserveWhiteSpace,
+  onChange,
+  __unstableDisableFormats: disableFormats,
+  __unstableIsSelected: isSelected,
+  __unstableDependencies = [],
+  __unstableAfterParse,
+  __unstableBeforeSerialize,
+  __unstableAddInvisibleFormats
+}) {
   const registry = (0,external_wp_data_namespaceObject.useRegistry)();
   const [, forceRender] = (0,external_wp_element_namespaceObject.useReducer)(() => ({}));
   const ref = (0,external_wp_element_namespaceObject.useRef)();
-
   function createRecord() {
     const {
       ownerDocument: {
@@ -4682,114 +3700,98 @@
     return create({
       element: ref.current,
       range,
-      multilineTag,
-      multilineWrapperTags: multilineTag === 'li' ? ['ul', 'ol'] : undefined,
-      __unstableIsEditableTree: true,
-      preserveWhiteSpace
+      __unstableIsEditableTree: true
     });
   }
-
-  function applyRecord(newRecord) {
-    let {
-      domOnly
-    } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+  function applyRecord(newRecord, {
+    domOnly
+  } = {}) {
     apply({
       value: newRecord,
       current: ref.current,
-      multilineTag,
-      multilineWrapperTags: multilineTag === 'li' ? ['ul', 'ol'] : undefined,
       prepareEditableTree: __unstableAddInvisibleFormats,
       __unstableDomOnly: domOnly,
       placeholder
     });
-  } // Internal values are updated synchronously, unlike props and state.
-
-
+  }
+
+  // Internal values are updated synchronously, unlike props and state.
   const _value = (0,external_wp_element_namespaceObject.useRef)(value);
-
   const record = (0,external_wp_element_namespaceObject.useRef)();
-
   function setRecordFromProps() {
     _value.current = value;
-    record.current = create({
-      html: value,
-      multilineTag,
-      multilineWrapperTags: multilineTag === 'li' ? ['ul', 'ol'] : undefined,
-      preserveWhiteSpace
-    });
-
+    record.current = value;
+    if (!(value instanceof RichTextData)) {
+      record.current = value ? RichTextData.fromHTMLString(value, {
+        preserveWhiteSpace
+      }) : RichTextData.empty();
+    }
+    // To do: make rich text internally work with RichTextData.
+    record.current = {
+      text: record.current.text,
+      formats: record.current.formats,
+      replacements: record.current.replacements
+    };
     if (disableFormats) {
       record.current.formats = Array(value.length);
       record.current.replacements = Array(value.length);
     }
-
     if (__unstableAfterParse) {
       record.current.formats = __unstableAfterParse(record.current);
     }
-
     record.current.start = selectionStart;
     record.current.end = selectionEnd;
   }
-
   const hadSelectionUpdate = (0,external_wp_element_namespaceObject.useRef)(false);
-
   if (!record.current) {
-    var _record$current, _record$current$forma, _record$current$forma2;
-
-    setRecordFromProps(); // Sometimes formats are added programmatically and we need to make
-    // sure it's persisted to the block store / markup. If these formats
-    // are not applied, they could cause inconsistencies between the data
-    // in the visual editor and the frontend. Right now, it's only relevant
-    // to the `core/text-color` format, which is applied at runtime in
-    // certain circunstances. See the `__unstableFilterAttributeValue`
-    // function in `packages/format-library/src/text-color/index.js`.
-    // @todo find a less-hacky way of solving this.
-
-    const hasRelevantInitFormat = ((_record$current = record.current) === null || _record$current === void 0 ? void 0 : (_record$current$forma = _record$current.formats[0]) === null || _record$current$forma === void 0 ? void 0 : (_record$current$forma2 = _record$current$forma[0]) === null || _record$current$forma2 === void 0 ? void 0 : _record$current$forma2.type) === 'core/text-color';
-
-    if (hasRelevantInitFormat) {
-      handleChangesUponInit(record.current);
-    }
+    hadSelectionUpdate.current = isSelected;
+    setRecordFromProps();
   } else if (selectionStart !== record.current.start || selectionEnd !== record.current.end) {
     hadSelectionUpdate.current = isSelected;
-    record.current = { ...record.current,
+    record.current = {
+      ...record.current,
       start: selectionStart,
-      end: selectionEnd
+      end: selectionEnd,
+      activeFormats: undefined
     };
   }
+
   /**
    * Sync the value to global state. The node tree and selection will also be
    * updated if differences are found.
    *
    * @param {Object} newRecord The record to sync and apply.
    */
-
-
   function handleChange(newRecord) {
     record.current = newRecord;
     applyRecord(newRecord);
-
     if (disableFormats) {
       _value.current = newRecord.text;
     } else {
-      _value.current = toHTMLString({
-        value: __unstableBeforeSerialize ? { ...newRecord,
-          formats: __unstableBeforeSerialize(newRecord)
-        } : newRecord,
-        multilineTag,
-        preserveWhiteSpace
-      });
+      const newFormats = __unstableBeforeSerialize ? __unstableBeforeSerialize(newRecord) : newRecord.formats;
+      newRecord = {
+        ...newRecord,
+        formats: newFormats
+      };
+      if (typeof value === 'string') {
+        _value.current = toHTMLString({
+          value: newRecord,
+          preserveWhiteSpace
+        });
+      } else {
+        _value.current = new RichTextData(newRecord);
+      }
     }
-
     const {
       start,
       end,
       formats,
       text
-    } = newRecord; // Selection must be updated first, so it is recorded in history when
+    } = record.current;
+
+    // Selection must be updated first, so it is recorded in history when
     // the content change happens.
     // We batch both calls to only attempt to rerender once.
-
     registry.batch(() => {
       onSelectionChange(start, end);
       onChange(_value.current, {
@@ -4799,173 +3801,93 @@
     });
     forceRender();
   }
-
-  function handleChangesUponInit(newRecord) {
-    record.current = newRecord;
-    _value.current = toHTMLString({
-      value: __unstableBeforeSerialize ? { ...newRecord,
-        formats: __unstableBeforeSerialize(newRecord)
-      } : newRecord,
-      multilineTag,
-      preserveWhiteSpace
-    });
-    const {
-      formats,
-      text
-    } = newRecord;
-    registry.batch(() => {
-      onChange(_value.current, {
-        __unstableFormats: formats,
-        __unstableText: text
-      });
-    });
-    forceRender();
-  }
-
   function applyFromProps() {
     setRecordFromProps();
     applyRecord(record.current);
   }
-
-  const didMount = (0,external_wp_element_namespaceObject.useRef)(false); // Value updates must happen synchonously to avoid overwriting newer values.
-
+  const didMount = (0,external_wp_element_namespaceObject.useRef)(false);
+
+  // Value updates must happen synchonously to avoid overwriting newer values.
   (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
     if (didMount.current && value !== _value.current) {
       applyFromProps();
       forceRender();
     }
-  }, [value]); // Value updates must happen synchonously to avoid overwriting newer values.
-
+  }, [value]);
+
+  // Value updates must happen synchonously to avoid overwriting newer values.
   (0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
     if (!hadSelectionUpdate.current) {
       return;
     }
-
     if (ref.current.ownerDocument.activeElement !== ref.current) {
       ref.current.focus();
     }
-
-    applyFromProps();
+    applyRecord(record.current);
     hadSelectionUpdate.current = false;
   }, [hadSelectionUpdate.current]);
   const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, useDefaultStyle(), useBoundaryStyle({
     record
-  }), useCopyHandler({
-    record,
-    multilineTag,
-    preserveWhiteSpace
-  }), useSelectObject(), useFormatBoundaries({
+  }), useEventListeners({
     record,
-    applyRecord
-  }), useDelete({
-    createRecord,
     handleChange,
-    multilineTag
-  }), useIndentListItemOnSpace({
-    multilineTag,
-    createRecord,
-    handleChange
-  }), useInputAndSelection({
-    record,
     applyRecord,
     createRecord,
-    handleChange,
     isSelected,
-    onSelectionChange
-  }), useSpace(), (0,external_wp_compose_namespaceObject.useRefEffect)(() => {
+    onSelectionChange,
+    forceRender
+  }), (0,external_wp_compose_namespaceObject.useRefEffect)(() => {
     applyFromProps();
     didMount.current = true;
   }, [placeholder, ...__unstableDependencies])]);
   return {
     value: record.current,
+    // A function to get the most recent value so event handlers in
+    // useRichText implementations have access to it. For example when
+    // listening to input events, we internally update the state, but this
+    // state is not yet available to the input event handler because React
+    // may re-render asynchronously.
+    getValue: () => record.current,
     onChange: handleChange,
     ref: mergedRefs
   };
 }
 function __experimentalRichText() {}
 
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/component/format-edit.js
+;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/index.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 /**
- * Internal dependencies
+ * An object which represents a formatted string. See main `@wordpress/rich-text`
+ * documentation for more information.
  */
 
-
-function FormatEdit(_ref) {
-  let {
-    formatTypes,
-    onChange,
-    onFocus,
-    value,
-    forwardedRef
-  } = _ref;
-  return formatTypes.map(settings => {
-    const {
-      name,
-      edit: Edit
-    } = settings;
-
-    if (!Edit) {
-      return null;
-    }
-
-    const activeFormat = getActiveFormat(value, name);
-    const isActive = activeFormat !== undefined;
-    const activeObject = getActiveObject(value);
-    const isObjectActive = activeObject !== undefined && activeObject.type === name;
-    return (0,external_wp_element_namespaceObject.createElement)(Edit, {
-      key: name,
-      isActive: isActive,
-      activeAttributes: isActive ? activeFormat.attributes || {} : {},
-      isObjectActive: isObjectActive,
-      activeObjectAttributes: isObjectActive ? activeObject.attributes || {} : {},
-      value: value,
-      onChange: onChange,
-      onFocus: onFocus,
-      contentRef: forwardedRef
-    });
-  });
-}
-
-;// CONCATENATED MODULE: ./node_modules/@wordpress/rich-text/build-module/index.js
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 (window.wp = window.wp || {}).richText = __webpack_exports__;
 /******/ })()
 ;
\ No newline at end of file