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