PluginProbe
Gutenberg / 22.3.0
Gutenberg v22.3.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / rich-text / index.js

index.js in Gutenberg 22.3.0, at build/scripts/rich-text/index.js

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