@contentful/field-editor-rich-text 4.18.0 → 4.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/RichTextEditor.js +5 -9
- package/dist/cjs/helpers/__tests__/toSlateDoc.test.js +611 -0
- package/dist/cjs/helpers/toSlateDoc.js +193 -0
- package/dist/esm/RichTextEditor.js +5 -9
- package/dist/esm/helpers/__tests__/toSlateDoc.test.js +607 -0
- package/dist/esm/helpers/toSlateDoc.js +183 -0
- package/dist/types/helpers/__tests__/toSlateDoc.test.d.ts +1 -0
- package/dist/types/helpers/toSlateDoc.d.ts +3 -0
- package/package.json +4 -3
- package/dist/cjs/helpers/toSlateValue.js +0 -51
- package/dist/esm/helpers/toSlateValue.js +0 -36
- package/dist/types/helpers/toSlateValue.d.ts +0 -7
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "toSlateDoc", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return toSlateDoc;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _richtexttypes = require("@contentful/rich-text-types");
|
|
12
|
+
const _slate = require("slate");
|
|
13
|
+
const _internal = require("../internal");
|
|
14
|
+
const inlineTypes = new Set(Object.values(_richtexttypes.INLINES));
|
|
15
|
+
const voidTypes = new Set([
|
|
16
|
+
..._richtexttypes.VOID_BLOCKS,
|
|
17
|
+
_richtexttypes.INLINES.EMBEDDED_ENTRY,
|
|
18
|
+
_richtexttypes.INLINES.EMBEDDED_RESOURCE
|
|
19
|
+
]);
|
|
20
|
+
function isEmptyHyperlink(node) {
|
|
21
|
+
if (node.nodeType !== _richtexttypes.INLINES.HYPERLINK) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const link = node;
|
|
25
|
+
if (!link.content?.length) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return link.content.length === 1 && link.content.at(0)?.value.length === 0;
|
|
29
|
+
}
|
|
30
|
+
function maybeFixUnevenTableRows(el) {
|
|
31
|
+
const rows = el.children;
|
|
32
|
+
const rowSize = Math.max(...rows.map((row)=>row.children?.length ?? 0));
|
|
33
|
+
const fixedRows = [];
|
|
34
|
+
for (const row of rows){
|
|
35
|
+
const missingCells = rowSize - row.children.length;
|
|
36
|
+
if (missingCells === 0) {
|
|
37
|
+
fixedRows.push(row);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const cellType = row.children.at(-1)?.type === _richtexttypes.BLOCKS.TABLE_HEADER_CELL ? _richtexttypes.BLOCKS.TABLE_HEADER_CELL : _richtexttypes.BLOCKS.TABLE_CELL;
|
|
41
|
+
const paddedRow = {
|
|
42
|
+
...row,
|
|
43
|
+
children: [
|
|
44
|
+
...row.children
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
for(let i = 0; i < missingCells; i++){
|
|
48
|
+
paddedRow.children.push({
|
|
49
|
+
type: cellType,
|
|
50
|
+
data: {},
|
|
51
|
+
children: [
|
|
52
|
+
{
|
|
53
|
+
type: _richtexttypes.BLOCKS.PARAGRAPH,
|
|
54
|
+
data: {},
|
|
55
|
+
children: [
|
|
56
|
+
{
|
|
57
|
+
text: ''
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
isVoid: false
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
isVoid: false
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
fixedRows.push(paddedRow);
|
|
67
|
+
}
|
|
68
|
+
return fixedRows;
|
|
69
|
+
}
|
|
70
|
+
function transformText(node) {
|
|
71
|
+
const text = {
|
|
72
|
+
text: node.value,
|
|
73
|
+
data: node.data ?? {}
|
|
74
|
+
};
|
|
75
|
+
for (const mark of node.marks){
|
|
76
|
+
text[mark.type] = true;
|
|
77
|
+
}
|
|
78
|
+
return text;
|
|
79
|
+
}
|
|
80
|
+
function transformNode(node) {
|
|
81
|
+
const el = {
|
|
82
|
+
type: node.nodeType,
|
|
83
|
+
children: [],
|
|
84
|
+
data: node.data ?? {},
|
|
85
|
+
isVoid: voidTypes.has(node.nodeType)
|
|
86
|
+
};
|
|
87
|
+
for (const child of node.content){
|
|
88
|
+
const lastChild = el.children.at(-1);
|
|
89
|
+
if (child.nodeType === 'text') {
|
|
90
|
+
const text = transformText(child);
|
|
91
|
+
if ((0, _internal.isText)(lastChild) && _slate.Text.equals(lastChild, text, {
|
|
92
|
+
loose: true
|
|
93
|
+
})) {
|
|
94
|
+
lastChild.text += child.value;
|
|
95
|
+
} else {
|
|
96
|
+
el.children.push(text);
|
|
97
|
+
}
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (isEmptyHyperlink(child)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (inlineTypes.has(child.nodeType) && !(0, _internal.isText)(lastChild)) {
|
|
104
|
+
el.children.push({
|
|
105
|
+
text: ''
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
el.children.push(transformNode(child));
|
|
109
|
+
}
|
|
110
|
+
if (el.children.length === 0) {
|
|
111
|
+
switch(el.type){
|
|
112
|
+
case _richtexttypes.BLOCKS.QUOTE:
|
|
113
|
+
case _richtexttypes.BLOCKS.LIST_ITEM:
|
|
114
|
+
el.children.push({
|
|
115
|
+
type: _richtexttypes.BLOCKS.PARAGRAPH,
|
|
116
|
+
data: {},
|
|
117
|
+
children: [
|
|
118
|
+
{
|
|
119
|
+
text: ''
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
isVoid: false
|
|
123
|
+
});
|
|
124
|
+
break;
|
|
125
|
+
case _richtexttypes.BLOCKS.UL_LIST:
|
|
126
|
+
case _richtexttypes.BLOCKS.OL_LIST:
|
|
127
|
+
el.children.push({
|
|
128
|
+
type: _richtexttypes.BLOCKS.LIST_ITEM,
|
|
129
|
+
data: {},
|
|
130
|
+
children: [
|
|
131
|
+
{
|
|
132
|
+
type: _richtexttypes.BLOCKS.PARAGRAPH,
|
|
133
|
+
data: {},
|
|
134
|
+
children: [
|
|
135
|
+
{
|
|
136
|
+
text: ''
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
isVoid: false
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
isVoid: false
|
|
143
|
+
});
|
|
144
|
+
break;
|
|
145
|
+
default:
|
|
146
|
+
el.children.push({
|
|
147
|
+
text: ''
|
|
148
|
+
});
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const lastChildElement = el.children.at(-1);
|
|
153
|
+
if (_slate.Element.isElement(lastChildElement) && inlineTypes.has(lastChildElement.type)) {
|
|
154
|
+
el.children.push({
|
|
155
|
+
text: ''
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (el.type === _richtexttypes.BLOCKS.TABLE) {
|
|
159
|
+
el.children = maybeFixUnevenTableRows(el);
|
|
160
|
+
}
|
|
161
|
+
return el;
|
|
162
|
+
}
|
|
163
|
+
function toSlateDoc(doc) {
|
|
164
|
+
if (!doc || !doc?.content?.length) {
|
|
165
|
+
return [
|
|
166
|
+
{
|
|
167
|
+
type: 'paragraph',
|
|
168
|
+
children: [
|
|
169
|
+
{
|
|
170
|
+
text: ''
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
data: {},
|
|
174
|
+
isVoid: false
|
|
175
|
+
}
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
const elements = doc.content.map(transformNode);
|
|
179
|
+
const lastElement = elements.at(-1);
|
|
180
|
+
if (lastElement?.type !== _richtexttypes.BLOCKS.PARAGRAPH) {
|
|
181
|
+
elements.push({
|
|
182
|
+
type: _richtexttypes.BLOCKS.PARAGRAPH,
|
|
183
|
+
children: [
|
|
184
|
+
{
|
|
185
|
+
text: ''
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
data: {},
|
|
189
|
+
isVoid: false
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return elements;
|
|
193
|
+
}
|
|
@@ -6,11 +6,11 @@ import { PlateContent, Plate } from '@udecode/plate-common';
|
|
|
6
6
|
import { css, cx } from 'emotion';
|
|
7
7
|
import deepEquals from 'fast-deep-equal';
|
|
8
8
|
import noop from 'lodash/noop';
|
|
9
|
+
import { useDeepCompareMemo } from 'use-deep-compare';
|
|
9
10
|
import { CharConstraints } from './CharConstraints';
|
|
10
11
|
import { ContentfulEditorIdProvider, getContentfulEditorId } from './ContentfulEditorProvider';
|
|
11
12
|
import { defaultScrollSelectionIntoView } from './editor-overrides';
|
|
12
|
-
import {
|
|
13
|
-
import { normalizeInitialValue } from './internal/misc';
|
|
13
|
+
import { toSlateDoc } from './helpers/toSlateDoc';
|
|
14
14
|
import { getPlugins, disableCorePlugins } from './plugins';
|
|
15
15
|
import { styles } from './RichTextEditor.styles';
|
|
16
16
|
import { SdkProvider } from './SdkProvider';
|
|
@@ -26,14 +26,10 @@ export const ConnectedRichTextEditor = (props)=>{
|
|
|
26
26
|
restrictedMarks,
|
|
27
27
|
withCharValidation
|
|
28
28
|
]);
|
|
29
|
-
const initialValue =
|
|
30
|
-
return
|
|
31
|
-
plugins,
|
|
32
|
-
disableCorePlugins
|
|
33
|
-
}, toSlateValue(props.value));
|
|
29
|
+
const initialValue = useDeepCompareMemo(()=>{
|
|
30
|
+
return toSlateDoc(props.value);
|
|
34
31
|
}, [
|
|
35
|
-
props.value
|
|
36
|
-
plugins
|
|
32
|
+
props.value
|
|
37
33
|
]);
|
|
38
34
|
const direction = sdk.locales.direction[sdk.field.locale] ?? 'ltr';
|
|
39
35
|
const classNames = cx(styles.editor, props.minHeight !== undefined ? css({
|