@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,183 @@
|
|
|
1
|
+
import { INLINES, BLOCKS, VOID_BLOCKS } from '@contentful/rich-text-types';
|
|
2
|
+
import { Text as TextInterface, Element as ElementInterface } from 'slate';
|
|
3
|
+
import { isText } from '../internal';
|
|
4
|
+
const inlineTypes = new Set(Object.values(INLINES));
|
|
5
|
+
const voidTypes = new Set([
|
|
6
|
+
...VOID_BLOCKS,
|
|
7
|
+
INLINES.EMBEDDED_ENTRY,
|
|
8
|
+
INLINES.EMBEDDED_RESOURCE
|
|
9
|
+
]);
|
|
10
|
+
function isEmptyHyperlink(node) {
|
|
11
|
+
if (node.nodeType !== INLINES.HYPERLINK) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const link = node;
|
|
15
|
+
if (!link.content?.length) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
return link.content.length === 1 && link.content.at(0)?.value.length === 0;
|
|
19
|
+
}
|
|
20
|
+
function maybeFixUnevenTableRows(el) {
|
|
21
|
+
const rows = el.children;
|
|
22
|
+
const rowSize = Math.max(...rows.map((row)=>row.children?.length ?? 0));
|
|
23
|
+
const fixedRows = [];
|
|
24
|
+
for (const row of rows){
|
|
25
|
+
const missingCells = rowSize - row.children.length;
|
|
26
|
+
if (missingCells === 0) {
|
|
27
|
+
fixedRows.push(row);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const cellType = row.children.at(-1)?.type === BLOCKS.TABLE_HEADER_CELL ? BLOCKS.TABLE_HEADER_CELL : BLOCKS.TABLE_CELL;
|
|
31
|
+
const paddedRow = {
|
|
32
|
+
...row,
|
|
33
|
+
children: [
|
|
34
|
+
...row.children
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
for(let i = 0; i < missingCells; i++){
|
|
38
|
+
paddedRow.children.push({
|
|
39
|
+
type: cellType,
|
|
40
|
+
data: {},
|
|
41
|
+
children: [
|
|
42
|
+
{
|
|
43
|
+
type: BLOCKS.PARAGRAPH,
|
|
44
|
+
data: {},
|
|
45
|
+
children: [
|
|
46
|
+
{
|
|
47
|
+
text: ''
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
isVoid: false
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
isVoid: false
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
fixedRows.push(paddedRow);
|
|
57
|
+
}
|
|
58
|
+
return fixedRows;
|
|
59
|
+
}
|
|
60
|
+
function transformText(node) {
|
|
61
|
+
const text = {
|
|
62
|
+
text: node.value,
|
|
63
|
+
data: node.data ?? {}
|
|
64
|
+
};
|
|
65
|
+
for (const mark of node.marks){
|
|
66
|
+
text[mark.type] = true;
|
|
67
|
+
}
|
|
68
|
+
return text;
|
|
69
|
+
}
|
|
70
|
+
function transformNode(node) {
|
|
71
|
+
const el = {
|
|
72
|
+
type: node.nodeType,
|
|
73
|
+
children: [],
|
|
74
|
+
data: node.data ?? {},
|
|
75
|
+
isVoid: voidTypes.has(node.nodeType)
|
|
76
|
+
};
|
|
77
|
+
for (const child of node.content){
|
|
78
|
+
const lastChild = el.children.at(-1);
|
|
79
|
+
if (child.nodeType === 'text') {
|
|
80
|
+
const text = transformText(child);
|
|
81
|
+
if (isText(lastChild) && TextInterface.equals(lastChild, text, {
|
|
82
|
+
loose: true
|
|
83
|
+
})) {
|
|
84
|
+
lastChild.text += child.value;
|
|
85
|
+
} else {
|
|
86
|
+
el.children.push(text);
|
|
87
|
+
}
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (isEmptyHyperlink(child)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (inlineTypes.has(child.nodeType) && !isText(lastChild)) {
|
|
94
|
+
el.children.push({
|
|
95
|
+
text: ''
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
el.children.push(transformNode(child));
|
|
99
|
+
}
|
|
100
|
+
if (el.children.length === 0) {
|
|
101
|
+
switch(el.type){
|
|
102
|
+
case BLOCKS.QUOTE:
|
|
103
|
+
case BLOCKS.LIST_ITEM:
|
|
104
|
+
el.children.push({
|
|
105
|
+
type: BLOCKS.PARAGRAPH,
|
|
106
|
+
data: {},
|
|
107
|
+
children: [
|
|
108
|
+
{
|
|
109
|
+
text: ''
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
isVoid: false
|
|
113
|
+
});
|
|
114
|
+
break;
|
|
115
|
+
case BLOCKS.UL_LIST:
|
|
116
|
+
case BLOCKS.OL_LIST:
|
|
117
|
+
el.children.push({
|
|
118
|
+
type: BLOCKS.LIST_ITEM,
|
|
119
|
+
data: {},
|
|
120
|
+
children: [
|
|
121
|
+
{
|
|
122
|
+
type: BLOCKS.PARAGRAPH,
|
|
123
|
+
data: {},
|
|
124
|
+
children: [
|
|
125
|
+
{
|
|
126
|
+
text: ''
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
isVoid: false
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
isVoid: false
|
|
133
|
+
});
|
|
134
|
+
break;
|
|
135
|
+
default:
|
|
136
|
+
el.children.push({
|
|
137
|
+
text: ''
|
|
138
|
+
});
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const lastChildElement = el.children.at(-1);
|
|
143
|
+
if (ElementInterface.isElement(lastChildElement) && inlineTypes.has(lastChildElement.type)) {
|
|
144
|
+
el.children.push({
|
|
145
|
+
text: ''
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (el.type === BLOCKS.TABLE) {
|
|
149
|
+
el.children = maybeFixUnevenTableRows(el);
|
|
150
|
+
}
|
|
151
|
+
return el;
|
|
152
|
+
}
|
|
153
|
+
export function toSlateDoc(doc) {
|
|
154
|
+
if (!doc || !doc?.content?.length) {
|
|
155
|
+
return [
|
|
156
|
+
{
|
|
157
|
+
type: 'paragraph',
|
|
158
|
+
children: [
|
|
159
|
+
{
|
|
160
|
+
text: ''
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
data: {},
|
|
164
|
+
isVoid: false
|
|
165
|
+
}
|
|
166
|
+
];
|
|
167
|
+
}
|
|
168
|
+
const elements = doc.content.map(transformNode);
|
|
169
|
+
const lastElement = elements.at(-1);
|
|
170
|
+
if (lastElement?.type !== BLOCKS.PARAGRAPH) {
|
|
171
|
+
elements.push({
|
|
172
|
+
type: BLOCKS.PARAGRAPH,
|
|
173
|
+
children: [
|
|
174
|
+
{
|
|
175
|
+
text: ''
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
data: {},
|
|
179
|
+
isVoid: false
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return elements;
|
|
183
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-rich-text",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.19.1",
|
|
4
4
|
"source": "./src/index.tsx",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -71,7 +71,8 @@
|
|
|
71
71
|
"slate": "0.94.1",
|
|
72
72
|
"slate-history": "0.100.0",
|
|
73
73
|
"slate-hyperscript": "0.77.0",
|
|
74
|
-
"slate-react": "0.102.0"
|
|
74
|
+
"slate-react": "0.102.0",
|
|
75
|
+
"use-deep-compare": "^1.3.0"
|
|
75
76
|
},
|
|
76
77
|
"peerDependencies": {
|
|
77
78
|
"@lingui/core": "^5.3.0",
|
|
@@ -90,5 +91,5 @@
|
|
|
90
91
|
"publishConfig": {
|
|
91
92
|
"registry": "https://npm.pkg.github.com/"
|
|
92
93
|
},
|
|
93
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "25039e978332b8efc8511a3e2ee2a6398f334a7f"
|
|
94
95
|
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "toSlateValue", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return toSlateValue;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const _contentfulslatejsadapter = require("@contentful/contentful-slatejs-adapter");
|
|
12
|
-
const _richtexttypes = require("@contentful/rich-text-types");
|
|
13
|
-
const _Schema = /*#__PURE__*/ _interop_require_default(require("../constants/Schema"));
|
|
14
|
-
function _interop_require_default(obj) {
|
|
15
|
-
return obj && obj.__esModule ? obj : {
|
|
16
|
-
default: obj
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
const isTextElement = (node)=>'text' in node;
|
|
20
|
-
function sanitizeIncomingSlateDoc(nodes = []) {
|
|
21
|
-
return nodes.map((node)=>{
|
|
22
|
-
if (isTextElement(node)) {
|
|
23
|
-
return node;
|
|
24
|
-
}
|
|
25
|
-
if (node.children?.length === 0) {
|
|
26
|
-
return {
|
|
27
|
-
...node,
|
|
28
|
-
children: [
|
|
29
|
-
{
|
|
30
|
-
text: '',
|
|
31
|
-
data: {}
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
...node,
|
|
38
|
-
children: sanitizeIncomingSlateDoc(node?.children)
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
const toSlateValue = (doc)=>{
|
|
43
|
-
const hasContent = (doc)=>{
|
|
44
|
-
return (doc?.content || []).length > 0;
|
|
45
|
-
};
|
|
46
|
-
const slateDoc = (0, _contentfulslatejsadapter.toSlatejsDocument)({
|
|
47
|
-
document: doc && hasContent(doc) ? doc : _richtexttypes.EMPTY_DOCUMENT,
|
|
48
|
-
schema: _Schema.default
|
|
49
|
-
});
|
|
50
|
-
return sanitizeIncomingSlateDoc(slateDoc);
|
|
51
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { toSlatejsDocument } from '@contentful/contentful-slatejs-adapter';
|
|
2
|
-
import { EMPTY_DOCUMENT } from '@contentful/rich-text-types';
|
|
3
|
-
import schema from '../constants/Schema';
|
|
4
|
-
const isTextElement = (node)=>'text' in node;
|
|
5
|
-
function sanitizeIncomingSlateDoc(nodes = []) {
|
|
6
|
-
return nodes.map((node)=>{
|
|
7
|
-
if (isTextElement(node)) {
|
|
8
|
-
return node;
|
|
9
|
-
}
|
|
10
|
-
if (node.children?.length === 0) {
|
|
11
|
-
return {
|
|
12
|
-
...node,
|
|
13
|
-
children: [
|
|
14
|
-
{
|
|
15
|
-
text: '',
|
|
16
|
-
data: {}
|
|
17
|
-
}
|
|
18
|
-
]
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
...node,
|
|
23
|
-
children: sanitizeIncomingSlateDoc(node?.children)
|
|
24
|
-
};
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
export const toSlateValue = (doc)=>{
|
|
28
|
-
const hasContent = (doc)=>{
|
|
29
|
-
return (doc?.content || []).length > 0;
|
|
30
|
-
};
|
|
31
|
-
const slateDoc = toSlatejsDocument({
|
|
32
|
-
document: doc && hasContent(doc) ? doc : EMPTY_DOCUMENT,
|
|
33
|
-
schema
|
|
34
|
-
});
|
|
35
|
-
return sanitizeIncomingSlateDoc(slateDoc);
|
|
36
|
-
};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Document } from '@contentful/rich-text-types';
|
|
2
|
-
import { Element } from '../internal/types';
|
|
3
|
-
/**
|
|
4
|
-
* Converts a Contentful rich text document to the corresponding slate editor
|
|
5
|
-
* value
|
|
6
|
-
*/
|
|
7
|
-
export declare const toSlateValue: (doc?: Document) => Element[];
|