@pega/cosmos-react-rte 10.0.0-build.4.2 → 10.0.0-build.4.21
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/lib/components/Editor/Editor.d.ts.map +1 -1
- package/lib/components/Editor/Editor.js +5 -2
- package/lib/components/Editor/Editor.js.map +1 -1
- package/lib/components/Editor/Editor.styles.d.ts.map +1 -1
- package/lib/components/Editor/IframeTiptapEditor.d.ts +2 -1
- package/lib/components/Editor/IframeTiptapEditor.d.ts.map +1 -1
- package/lib/components/Editor/IframeTiptapEditor.js +5 -5
- package/lib/components/Editor/IframeTiptapEditor.js.map +1 -1
- package/lib/components/Editor/ImageActionButtons.d.ts +4 -2
- package/lib/components/Editor/ImageActionButtons.d.ts.map +1 -1
- package/lib/components/Editor/ImageActionButtons.js +2 -2
- package/lib/components/Editor/ImageActionButtons.js.map +1 -1
- package/lib/components/Editor/hooks/useIframeSetup.d.ts +2 -1
- package/lib/components/Editor/hooks/useIframeSetup.d.ts.map +1 -1
- package/lib/components/Editor/hooks/useIframeSetup.js +2 -2
- package/lib/components/Editor/hooks/useIframeSetup.js.map +1 -1
- package/lib/components/RichTextEditor/RichTextViewer.d.ts.map +1 -1
- package/lib/components/RichTextEditor/RichTextViewer.js +3 -3
- package/lib/components/RichTextEditor/RichTextViewer.js.map +1 -1
- package/lib/components/RichTextEditor/RichTextViewer.types.d.ts +2 -0
- package/lib/components/RichTextEditor/RichTextViewer.types.d.ts.map +1 -1
- package/lib/components/RichTextEditor/RichTextViewer.types.js.map +1 -1
- package/lib/components/RichTextEditor/utils/markdownConverter.d.ts +2 -2
- package/lib/components/RichTextEditor/utils/markdownConverter.d.ts.map +1 -1
- package/lib/components/RichTextEditor/utils/markdownConverter.js +307 -24
- package/lib/components/RichTextEditor/utils/markdownConverter.js.map +1 -1
- package/lib/components/RichTextEditor/utils/renderers.d.ts +3 -0
- package/lib/components/RichTextEditor/utils/renderers.d.ts.map +1 -1
- package/lib/components/RichTextEditor/utils/renderers.js +42 -0
- package/lib/components/RichTextEditor/utils/renderers.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { marked } from 'marked';
|
|
3
|
+
import { parseFragment, serialize } from 'parse5';
|
|
3
4
|
import { hasProp } from '@pega/cosmos-react-core';
|
|
4
5
|
import parseTextToCustomSlateNodes from './interactionRenderer';
|
|
5
6
|
const getTableColumnAlignment = (alignment) => {
|
|
@@ -8,6 +9,9 @@ const getTableColumnAlignment = (alignment) => {
|
|
|
8
9
|
}
|
|
9
10
|
return undefined;
|
|
10
11
|
};
|
|
12
|
+
const flattenInlineNodes = (nodes) => nodes.flatMap(node => 'type' in node && node.type === 'text' && 'children' in node
|
|
13
|
+
? flattenInlineNodes(node.children)
|
|
14
|
+
: [node]);
|
|
11
15
|
const applyFormatting = (children, token, formatKey) => {
|
|
12
16
|
if (children.length === 1 && 'type' in children[0] && children[0].type === 'custom') {
|
|
13
17
|
return {
|
|
@@ -16,12 +20,13 @@ const applyFormatting = (children, token, formatKey) => {
|
|
|
16
20
|
};
|
|
17
21
|
}
|
|
18
22
|
if (children.length > 1) {
|
|
23
|
+
const formattedChildren = flattenInlineNodes(children).map(child => ({
|
|
24
|
+
...child,
|
|
25
|
+
[formatKey]: true
|
|
26
|
+
}));
|
|
19
27
|
return {
|
|
20
28
|
type: 'text',
|
|
21
|
-
children:
|
|
22
|
-
...child,
|
|
23
|
-
[formatKey]: true
|
|
24
|
-
}))
|
|
29
|
+
children: formattedChildren
|
|
25
30
|
};
|
|
26
31
|
}
|
|
27
32
|
const baseNode = children.length > 0 && !('type' in children[0])
|
|
@@ -32,6 +37,112 @@ const applyFormatting = (children, token, formatKey) => {
|
|
|
32
37
|
[formatKey]: true
|
|
33
38
|
};
|
|
34
39
|
};
|
|
40
|
+
// Limited set of inline HTML tags supported within markdown content.
|
|
41
|
+
const INLINE_HTML_TAG_FORMATS = {
|
|
42
|
+
em: 'italic',
|
|
43
|
+
i: 'italic',
|
|
44
|
+
strong: 'bold',
|
|
45
|
+
b: 'bold',
|
|
46
|
+
del: 'line-through',
|
|
47
|
+
u: 'underline',
|
|
48
|
+
sup: 'superscript',
|
|
49
|
+
sub: 'subscript'
|
|
50
|
+
};
|
|
51
|
+
const isParse5Element = (node) => !!node && node.nodeName !== '#text' && node.nodeName !== '#comment';
|
|
52
|
+
const isParse5Text = (node) => node.nodeName === '#text';
|
|
53
|
+
const getParse5Attribute = (element, name) => element.attrs.find(attr => attr.name === name)?.value;
|
|
54
|
+
// Concatenates the text of a parse5 node and all of its descendants.
|
|
55
|
+
const getParse5TextContent = (node) => {
|
|
56
|
+
if (isParse5Text(node))
|
|
57
|
+
return node.value;
|
|
58
|
+
if (isParse5Element(node))
|
|
59
|
+
return node.childNodes.map(getParse5TextContent).join('');
|
|
60
|
+
return '';
|
|
61
|
+
};
|
|
62
|
+
// Wraps text in a fenced markdown code block, using a fence long enough to not collide with any
|
|
63
|
+
// backtick run inside the content.
|
|
64
|
+
const toFencedCodeBlock = (code) => {
|
|
65
|
+
const longestBacktickRun = Math.max(0, ...(code.match(/`+/g) ?? []).map(run => run.length));
|
|
66
|
+
const fence = '`'.repeat(Math.max(3, longestBacktickRun + 1));
|
|
67
|
+
return `${fence}\n${code}\n${fence}`;
|
|
68
|
+
};
|
|
69
|
+
// Block-level HTML tags that are unwrapped and treated like markdown paragraphs.
|
|
70
|
+
const PARAGRAPH_LIKE_TAGS = new Set(['div', 'p']);
|
|
71
|
+
// Heading HTML tags mapped to the markdown heading prefix they are treated as.
|
|
72
|
+
const HEADING_TAG_PREFIXES = {
|
|
73
|
+
h1: '#',
|
|
74
|
+
h2: '##',
|
|
75
|
+
h3: '###',
|
|
76
|
+
h4: '####',
|
|
77
|
+
h5: '#####',
|
|
78
|
+
h6: '######'
|
|
79
|
+
};
|
|
80
|
+
// List container HTML tags.
|
|
81
|
+
const LIST_TAGS = new Set(['ul', 'ol']);
|
|
82
|
+
const isListElement = (node) => isParse5Element(node) && LIST_TAGS.has(node.nodeName);
|
|
83
|
+
// Converts an HTML list (<ul>/<ol>) to the equivalent markdown list, recursing into nested lists
|
|
84
|
+
// with increased indentation so the structure matches a hand-written markdown list.
|
|
85
|
+
const convertListToMarkdown = (list, indent = '') => {
|
|
86
|
+
const ordered = list.nodeName === 'ol';
|
|
87
|
+
const start = ordered ? Number.parseInt(getParse5Attribute(list, 'start') ?? '', 10) : Number.NaN;
|
|
88
|
+
let index = Number.isNaN(start) ? 1 : start;
|
|
89
|
+
const lines = [];
|
|
90
|
+
list.childNodes
|
|
91
|
+
.filter((node) => isParse5Element(node) && node.nodeName === 'li')
|
|
92
|
+
.forEach(item => {
|
|
93
|
+
const marker = ordered ? `${index}.` : '-';
|
|
94
|
+
const inlineChildren = item.childNodes.filter(child => !isListElement(child));
|
|
95
|
+
const inline = serialize({ ...item, childNodes: inlineChildren }).trim();
|
|
96
|
+
lines.push(`${indent}${marker} ${inline}`);
|
|
97
|
+
item.childNodes.filter(isListElement).forEach(nested => {
|
|
98
|
+
lines.push(convertListToMarkdown(nested, `${indent}${' '.repeat(marker.length + 1)}`));
|
|
99
|
+
});
|
|
100
|
+
index += 1;
|
|
101
|
+
});
|
|
102
|
+
return lines.join('\n');
|
|
103
|
+
};
|
|
104
|
+
// A <pre> is only treated as a code block when its single element child is a <code>.
|
|
105
|
+
const isPreCodeBlock = (el) => {
|
|
106
|
+
if (el.nodeName !== 'pre')
|
|
107
|
+
return false;
|
|
108
|
+
const elementChildren = el.childNodes.filter(isParse5Element);
|
|
109
|
+
return elementChildren.length === 1 && elementChildren[0].nodeName === 'code';
|
|
110
|
+
};
|
|
111
|
+
const isSupportedBlockElement = (el) => PARAGRAPH_LIKE_TAGS.has(el.nodeName) ||
|
|
112
|
+
el.nodeName in HEADING_TAG_PREFIXES ||
|
|
113
|
+
el.nodeName === 'a' ||
|
|
114
|
+
el.nodeName === 'img' ||
|
|
115
|
+
LIST_TAGS.has(el.nodeName) ||
|
|
116
|
+
isPreCodeBlock(el);
|
|
117
|
+
// Returns the markdown representation of each top-level block (<div>/<p> as paragraphs, <h1>-<h6>
|
|
118
|
+
// as `#`-prefixed headings, <a>/<img> as links/images, <ul>/<ol> as lists, <pre> as a code block)
|
|
119
|
+
// when the block consists solely of supported blocks (ignoring whitespace), or undefined otherwise.
|
|
120
|
+
// Used to treat those blocks like their markdown equivalents.
|
|
121
|
+
const getTopLevelBlockMarkdown = (raw) => {
|
|
122
|
+
const { childNodes } = parseFragment(raw.trim());
|
|
123
|
+
const elements = childNodes.filter(isParse5Element);
|
|
124
|
+
const hasStrayText = childNodes.some(node => isParse5Text(node) && node.value.trim() !== '');
|
|
125
|
+
if (hasStrayText || elements.length === 0 || elements.some(el => !isSupportedBlockElement(el))) {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
return elements.map(el => {
|
|
129
|
+
if (LIST_TAGS.has(el.nodeName)) {
|
|
130
|
+
return convertListToMarkdown(el);
|
|
131
|
+
}
|
|
132
|
+
if (el.nodeName === 'pre') {
|
|
133
|
+
return toFencedCodeBlock(getParse5TextContent(el));
|
|
134
|
+
}
|
|
135
|
+
const inner = serialize(el);
|
|
136
|
+
if (el.nodeName === 'a') {
|
|
137
|
+
return `[${inner}](${getParse5Attribute(el, 'href') ?? ''})`;
|
|
138
|
+
}
|
|
139
|
+
if (el.nodeName === 'img') {
|
|
140
|
+
return ` ?? ''})`;
|
|
141
|
+
}
|
|
142
|
+
const headingPrefix = HEADING_TAG_PREFIXES[el.nodeName];
|
|
143
|
+
return headingPrefix ? `${headingPrefix} ${inner}` : inner;
|
|
144
|
+
});
|
|
145
|
+
};
|
|
35
146
|
const MARKED_TOKEN_TYPES = [
|
|
36
147
|
'blockquote',
|
|
37
148
|
'br',
|
|
@@ -56,21 +167,192 @@ const MARKED_TOKEN_TYPES = [
|
|
|
56
167
|
];
|
|
57
168
|
const MARKED_TOKEN_TYPE_SET = new Set(MARKED_TOKEN_TYPES);
|
|
58
169
|
const isMarkedToken = (token) => MARKED_TOKEN_TYPE_SET.has(token.type);
|
|
170
|
+
// Expands top-level blocks (<div>/<p> and <h1> - <h6>) into the token stream they represent as
|
|
171
|
+
// markdown, so a series of them behaves exactly like the equivalent blank-line-separated markdown
|
|
172
|
+
// paragraphs and headings.
|
|
173
|
+
const expandTopLevelBlockTokens = (tokens) => tokens.flatMap(token => {
|
|
174
|
+
if (token.type === 'html' && token.block) {
|
|
175
|
+
const blockMarkdown = getTopLevelBlockMarkdown(token.raw);
|
|
176
|
+
if (blockMarkdown) {
|
|
177
|
+
return expandTopLevelBlockTokens(marked.lexer(blockMarkdown.join('\n\n'), { gfm: true }).filter(isMarkedToken));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return [token];
|
|
181
|
+
});
|
|
182
|
+
// Classifies a single HTML tag token, returning its lowercased tag name and whether it is a
|
|
183
|
+
// closing tag. Opening tags are parsed with a real HTML parser; closing tags carry no attributes,
|
|
184
|
+
// so their name is read directly and anything other than a bare `</name>` is rejected.
|
|
185
|
+
const parseHtmlTagToken = (raw) => {
|
|
186
|
+
const trimmed = raw.trim();
|
|
187
|
+
if (trimmed.startsWith('</')) {
|
|
188
|
+
if (!trimmed.endsWith('>'))
|
|
189
|
+
return undefined;
|
|
190
|
+
const name = trimmed.slice(2, -1).trim().toLowerCase();
|
|
191
|
+
return name && !/[\s>/]/.test(name) ? { name, isClosing: true, attributes: {} } : undefined;
|
|
192
|
+
}
|
|
193
|
+
const [element] = parseFragment(trimmed).childNodes;
|
|
194
|
+
if (!isParse5Element(element))
|
|
195
|
+
return undefined;
|
|
196
|
+
const attributes = Object.fromEntries(element.attrs.map(attr => [attr.name, attr.value]));
|
|
197
|
+
return { name: element.nodeName, isClosing: false, attributes };
|
|
198
|
+
};
|
|
199
|
+
// Inline HTML tags handled beyond text formatting: <span> unwraps to text, <a> becomes a link,
|
|
200
|
+
// <img> becomes an image, and <code> becomes an inline code span.
|
|
201
|
+
const INLINE_HTML_STRUCTURAL_TAGS = new Set(['span', 'a', 'img', 'code']);
|
|
202
|
+
const getSupportedInlineHtmlTag = (raw) => {
|
|
203
|
+
const tag = parseHtmlTagToken(raw);
|
|
204
|
+
if (!tag)
|
|
205
|
+
return undefined;
|
|
206
|
+
return tag.name in INLINE_HTML_TAG_FORMATS || INLINE_HTML_STRUCTURAL_TAGS.has(tag.name)
|
|
207
|
+
? tag
|
|
208
|
+
: undefined;
|
|
209
|
+
};
|
|
210
|
+
const getInlineHtmlFormat = (tagName) => tagName in INLINE_HTML_TAG_FORMATS ? INLINE_HTML_TAG_FORMATS[tagName] : undefined;
|
|
211
|
+
// Finds the index of the matching closing tag, accounting for nested tags of the same name.
|
|
212
|
+
const findInlineHtmlCloseIndex = (tokens, openIndex, tagName) => {
|
|
213
|
+
let depth = 1;
|
|
214
|
+
for (let i = openIndex + 1; i < tokens.length; i += 1) {
|
|
215
|
+
const token = tokens[i];
|
|
216
|
+
if (token.type === 'html') {
|
|
217
|
+
const tag = getSupportedInlineHtmlTag(token.raw);
|
|
218
|
+
if (tag?.name === tagName) {
|
|
219
|
+
depth += tag.isClosing ? -1 : 1;
|
|
220
|
+
if (depth === 0) {
|
|
221
|
+
return i;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return -1;
|
|
227
|
+
};
|
|
228
|
+
// Applies an inline HTML formatting mark to a node and all of its descendant text nodes, matching
|
|
229
|
+
// the leaf-level representation that regular markdown emphasis produces.
|
|
230
|
+
const applyInlineHtmlFormat = (node, formatKey) => {
|
|
231
|
+
if ('type' in node) {
|
|
232
|
+
if (node.type === 'custom') {
|
|
233
|
+
return { ...node, [formatKey]: true };
|
|
234
|
+
}
|
|
235
|
+
if (node.type === 'text') {
|
|
236
|
+
return {
|
|
237
|
+
...node,
|
|
238
|
+
children: node.children.map(child => applyInlineHtmlFormat(child, formatKey))
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
return node;
|
|
242
|
+
}
|
|
243
|
+
return { ...node, [formatKey]: true };
|
|
244
|
+
};
|
|
245
|
+
// Concatenates the text of a node and all of its descendants.
|
|
246
|
+
const getNodeText = (node) => 'children' in node ? node.children.map(getNodeText).join('') : node.text;
|
|
247
|
+
// Builds a link leaf from an <a> tag's attributes and its inner nodes, matching the representation
|
|
248
|
+
// of a markdown link (href plus plain text).
|
|
249
|
+
const createLinkNode = (attributes, innerNodes) => ({
|
|
250
|
+
href: attributes.href ?? '',
|
|
251
|
+
text: innerNodes.map(getNodeText).join('')
|
|
252
|
+
});
|
|
253
|
+
// Builds an image element from an <img> tag's attributes, matching the representation of a markdown
|
|
254
|
+
// image.
|
|
255
|
+
const createImageNode = (attributes) => ({
|
|
256
|
+
type: 'image',
|
|
257
|
+
alt: attributes.alt ?? '',
|
|
258
|
+
src: attributes.src ?? '',
|
|
259
|
+
children: [{ text: '' }]
|
|
260
|
+
});
|
|
261
|
+
const TEXT_MARK_KEYS = [
|
|
262
|
+
'bold',
|
|
263
|
+
'italic',
|
|
264
|
+
'line-through',
|
|
265
|
+
'code',
|
|
266
|
+
'underline',
|
|
267
|
+
'superscript',
|
|
268
|
+
'subscript'
|
|
269
|
+
];
|
|
270
|
+
const isPlainLeaf = (node) => !node.href && !node.searchResult;
|
|
271
|
+
// Returns the single plain text leaf a node represents (either a bare leaf or a `text` element
|
|
272
|
+
// wrapping exactly one plain leaf), or undefined when the node cannot be merged with a neighbor.
|
|
273
|
+
const asSingleLeaf = (node) => {
|
|
274
|
+
if (!('type' in node)) {
|
|
275
|
+
return isPlainLeaf(node) ? node : undefined;
|
|
276
|
+
}
|
|
277
|
+
if (node.type === 'text' && node.children.length === 1) {
|
|
278
|
+
const [child] = node.children;
|
|
279
|
+
if (!('type' in child) && isPlainLeaf(child)) {
|
|
280
|
+
return child;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return undefined;
|
|
284
|
+
};
|
|
285
|
+
const haveSameMarks = (a, b) => TEXT_MARK_KEYS.every(key => !!a[key] === !!b[key]);
|
|
286
|
+
// Merges adjacent plain text runs that share the same marks so that, for example, nested same-tag
|
|
287
|
+
// emphasis collapses into a single formatted run (e.g. <strong><strong>foo</strong> bar</strong>
|
|
288
|
+
// renders identically to **foo bar**).
|
|
289
|
+
const mergeAdjacentTextNodes = (nodes) => {
|
|
290
|
+
const merged = [];
|
|
291
|
+
nodes.forEach(node => {
|
|
292
|
+
const leaf = asSingleLeaf(node);
|
|
293
|
+
const prev = merged[merged.length - 1];
|
|
294
|
+
const prevLeaf = prev ? asSingleLeaf(prev) : undefined;
|
|
295
|
+
if (leaf && prevLeaf && haveSameMarks(prevLeaf, leaf)) {
|
|
296
|
+
merged[merged.length - 1] = { ...prevLeaf, text: prevLeaf.text + leaf.text };
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
merged.push(node);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
return merged;
|
|
303
|
+
};
|
|
59
304
|
const getCustomComponentFromMarkdownMap = (token, markdownMap) => {
|
|
60
305
|
return markdownMap?.[token.type]?.(token);
|
|
61
306
|
};
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
307
|
+
const markDownToSlate = (tokens, interactionRenderers, markdownMap, convertTokenToSlateNode, htmlEnabled) => {
|
|
308
|
+
const nodes = [];
|
|
309
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
310
|
+
const token = tokens[i];
|
|
311
|
+
const openTag = htmlEnabled && token.type === 'html' ? getSupportedInlineHtmlTag(token.raw) : undefined;
|
|
312
|
+
if (openTag && openTag.name === 'img' && !openTag.isClosing) {
|
|
313
|
+
nodes.push(createImageNode(openTag.attributes));
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
const closeIndex = openTag && !openTag.isClosing ? findInlineHtmlCloseIndex(tokens, i, openTag.name) : -1;
|
|
317
|
+
if (openTag && closeIndex !== -1) {
|
|
318
|
+
if (openTag.name === 'code') {
|
|
319
|
+
// <code> is treated like a markdown codespan: its raw content becomes a code-marked leaf.
|
|
320
|
+
const innerRaw = tokens
|
|
321
|
+
.slice(i + 1, closeIndex)
|
|
322
|
+
.map(inner => inner.raw)
|
|
323
|
+
.join('');
|
|
324
|
+
nodes.push({ text: innerRaw, code: true });
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
const innerNodes = markDownToSlate(tokens.slice(i + 1, closeIndex), interactionRenderers, markdownMap, convertTokenToSlateNode, htmlEnabled);
|
|
328
|
+
if (openTag.name === 'a') {
|
|
329
|
+
nodes.push(createLinkNode(openTag.attributes, innerNodes));
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
const formatKey = getInlineHtmlFormat(openTag.name);
|
|
333
|
+
if (formatKey) {
|
|
334
|
+
innerNodes.forEach(innerNode => {
|
|
335
|
+
nodes.push(applyInlineHtmlFormat(innerNode, formatKey));
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
// Unwrapped tags (e.g. <span>) contribute their content as plain inline nodes.
|
|
340
|
+
nodes.push(...innerNodes);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
i = closeIndex;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
nodes.push(convertTokenToSlateNode(token, interactionRenderers, markdownMap, htmlEnabled));
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return htmlEnabled ? mergeAdjacentTextNodes(nodes) : nodes;
|
|
70
352
|
};
|
|
71
|
-
const convertTableCellToSlateNode = (cell, convertTokenToSlateNode, interactionRenderers, markdownMap, align, isHeaderCell) => {
|
|
353
|
+
const convertTableCellToSlateNode = (cell, convertTokenToSlateNode, interactionRenderers, markdownMap, align, isHeaderCell, htmlEnabled = false) => {
|
|
72
354
|
const children = cell.tokens?.length
|
|
73
|
-
? flattenInlineNodes(markDownToSlate(cell.tokens.filter(isMarkedToken), interactionRenderers, markdownMap, convertTokenToSlateNode))
|
|
355
|
+
? flattenInlineNodes(markDownToSlate(cell.tokens.filter(isMarkedToken), interactionRenderers, markdownMap, convertTokenToSlateNode, htmlEnabled))
|
|
74
356
|
: parseTextToCustomSlateNodes(cell.text || '', interactionRenderers);
|
|
75
357
|
const tableCell = {
|
|
76
358
|
type: 'table-cell',
|
|
@@ -80,21 +362,21 @@ const convertTableCellToSlateNode = (cell, convertTokenToSlateNode, interactionR
|
|
|
80
362
|
};
|
|
81
363
|
return tableCell;
|
|
82
364
|
};
|
|
83
|
-
const convertTableRowsToSlateNodes = (rows, convertTokenToSlateNode, interactionRenderers, markdownMap, alignments, isHeaderCell) => {
|
|
365
|
+
const convertTableRowsToSlateNodes = (rows, convertTokenToSlateNode, interactionRenderers, markdownMap, alignments, isHeaderCell, htmlEnabled = false) => {
|
|
84
366
|
return rows.map(row => {
|
|
85
367
|
return {
|
|
86
368
|
type: 'table-row',
|
|
87
369
|
children: row.map((cell, columnIndex) => {
|
|
88
|
-
return convertTableCellToSlateNode(cell, convertTokenToSlateNode, interactionRenderers, markdownMap, getTableColumnAlignment(alignments?.[columnIndex]), isHeaderCell);
|
|
370
|
+
return convertTableCellToSlateNode(cell, convertTokenToSlateNode, interactionRenderers, markdownMap, getTableColumnAlignment(alignments?.[columnIndex]), isHeaderCell, htmlEnabled);
|
|
89
371
|
})
|
|
90
372
|
};
|
|
91
373
|
});
|
|
92
374
|
};
|
|
93
|
-
export const getNode = (token, interactionRenderers, markdownMap) => {
|
|
375
|
+
export const getNode = (token, interactionRenderers, markdownMap, htmlEnabled = false) => {
|
|
94
376
|
if (!hasProp(token, 'type') || token.type === 'def')
|
|
95
377
|
return { type: 'paragraph', children: [{ text: '' }] };
|
|
96
378
|
if (token.type === 'html') {
|
|
97
|
-
if (
|
|
379
|
+
if (parseHtmlTagToken(token.raw)?.name === 'br') {
|
|
98
380
|
return { text: '\n' };
|
|
99
381
|
}
|
|
100
382
|
const parsed = parseTextToCustomSlateNodes(token.raw, interactionRenderers);
|
|
@@ -108,10 +390,10 @@ export const getNode = (token, interactionRenderers, markdownMap) => {
|
|
|
108
390
|
}
|
|
109
391
|
let children;
|
|
110
392
|
if (hasProp(token, 'tokens')) {
|
|
111
|
-
children = markDownToSlate(token.tokens || [], interactionRenderers, markdownMap, getNode);
|
|
393
|
+
children = markDownToSlate(token.tokens || [], interactionRenderers, markdownMap, getNode, htmlEnabled);
|
|
112
394
|
}
|
|
113
395
|
else if (hasProp(token, 'items')) {
|
|
114
|
-
children = markDownToSlate(token.items, interactionRenderers, markdownMap, getNode);
|
|
396
|
+
children = markDownToSlate(token.items, interactionRenderers, markdownMap, getNode, htmlEnabled);
|
|
115
397
|
}
|
|
116
398
|
else {
|
|
117
399
|
let mdText = '';
|
|
@@ -204,8 +486,8 @@ export const getNode = (token, interactionRenderers, markdownMap) => {
|
|
|
204
486
|
case 'table': {
|
|
205
487
|
const headerRows = token.header?.length ? [token.header] : [];
|
|
206
488
|
const bodyRows = token.rows || [];
|
|
207
|
-
const headerSlateRows = convertTableRowsToSlateNodes(headerRows, getNode, interactionRenderers, markdownMap, token.align, true);
|
|
208
|
-
const bodySlateRows = convertTableRowsToSlateNodes(bodyRows, getNode, interactionRenderers, markdownMap, token.align);
|
|
489
|
+
const headerSlateRows = convertTableRowsToSlateNodes(headerRows, getNode, interactionRenderers, markdownMap, token.align, true, htmlEnabled);
|
|
490
|
+
const bodySlateRows = convertTableRowsToSlateNodes(bodyRows, getNode, interactionRenderers, markdownMap, token.align, false, htmlEnabled);
|
|
209
491
|
const tableBody = {
|
|
210
492
|
type: 'table-body',
|
|
211
493
|
children: bodySlateRows
|
|
@@ -253,10 +535,11 @@ export const convertMarkdownForEditor = (md = '', searchRenderers) => {
|
|
|
253
535
|
};
|
|
254
536
|
// Converts markdown into Slate compatible nodes, also takes regex used
|
|
255
537
|
// in Feed Component to pass them down to custom elements
|
|
256
|
-
const convertMarkdown = (md, interactionRenderers, markdownMap) => {
|
|
538
|
+
const convertMarkdown = (md, interactionRenderers, markdownMap, htmlEnabled = false) => {
|
|
257
539
|
const lexer = new marked.Lexer({ gfm: true });
|
|
258
540
|
const output = lexer.lex(md);
|
|
259
|
-
|
|
541
|
+
const tokens = htmlEnabled ? expandTopLevelBlockTokens(output) : output;
|
|
542
|
+
return markDownToSlate(tokens, interactionRenderers, markdownMap, getNode, htmlEnabled);
|
|
260
543
|
};
|
|
261
544
|
export default convertMarkdown;
|
|
262
545
|
//# sourceMappingURL=markdownConverter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdownConverter.js","sourceRoot":"","sources":["../../../../src/components/RichTextEditor/utils/markdownConverter.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAIlD,OAAO,2BAA2B,MAAM,uBAAuB,CAAC;AAUhE,MAAM,uBAAuB,GAAG,CAC9B,SAAoD,EAClB,EAAE;IACpC,IAAI,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QAC5E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CACtB,QAA4B,EAC5B,KAAkB,EAClB,SAAsD,EACtC,EAAE;IAClB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpF,OAAO;YACL,GAAG,QAAQ,CAAC,CAAC,CAAC;YACd,CAAC,SAAS,CAAC,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC/B,GAAG,KAAK;gBACR,CAAC,SAAS,CAAC,EAAE,IAAI;aAClB,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GACZ,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACb,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAExD,OAAO;QACL,GAAG,QAAQ;QACX,CAAC,SAAS,CAAC,EAAE,IAAI;KAClB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG;IACzB,YAAY;IACZ,IAAI;IACJ,MAAM;IACN,UAAU;IACV,KAAK;IACL,KAAK;IACL,IAAI;IACJ,QAAQ;IACR,SAAS;IACT,IAAI;IACJ,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,WAAW;IACX,WAAW;IACX,OAAO;IACP,QAAQ;IACR,OAAO;IACP,MAAM;CAC2C,CAAC;AACpD,MAAM,qBAAqB,GAAwB,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAE/E,MAAM,aAAa,GAAG,CAAC,KAAmC,EAAwB,EAAE,CAClF,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAExC,MAAM,iCAAiC,GAAG,CACxC,KAAkB,EAClB,WAAgD,EACG,EAAE;IACrD,OAAO,WAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,kFAAkF;AAClF,MAAM,kBAAkB,GAAG,CAAC,KAAyB,EAAsB,EAAE,CAC3E,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CACnB,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,UAAU,IAAI,IAAI;IAC1D,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC;IACnC,CAAC,CAAC,CAAC,IAAI,CAAC,CACX,CAAC;AAEJ,MAAM,eAAe,GAAG,CACtB,MAAqB,EACrB,oBAAwD,EACxD,WAA2D,EAC3D,uBAA+C,EAC3B,EAAE;IACtB,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,EAAE,WAAW,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CAClC,IAAsB,EACtB,uBAA+C,EAC/C,oBAA6C,EAC7C,WAAgD,EAChD,KAA4B,EAC5B,YAAsB,EACO,EAAE;IAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM;QAClC,CAAC,CAAC,kBAAkB,CAChB,eAAe,CACb,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EACjC,oBAAoB,EACpB,WAAW,EACX,uBAAuB,CACxB,CACF;QACH,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAEvE,MAAM,SAAS,GAAgC;QAC7C,IAAI,EAAE,YAAY;QAClB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAC1D,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,4BAA4B,GAAG,CACnC,IAA0B,EAC1B,uBAA+C,EAC/C,oBAA6C,EAC7C,WAAgD,EAChD,UAAkC,EAClC,YAAsB,EACQ,EAAE;IAChC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACpB,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;gBACtC,OAAO,2BAA2B,CAChC,IAAI,EACJ,uBAAuB,EACvB,oBAAoB,EACpB,WAAW,EACX,uBAAuB,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC,EAClD,YAAY,CACb,CAAC;YACJ,CAAC,CAAC;SACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,KAAkB,EAClB,oBAA6C,EAC7C,WAAgD,EAChC,EAAE;IAClB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;QACjD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IAEzD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACxB,CAAC;QAED,MAAM,MAAM,GAAG,2BAA2B,CAAC,KAAK,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;QAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,MAAM;SACjB,CAAC;IACJ,CAAC;IAED,IAAI,QAA4B,CAAC;IAEjC,IAAI,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC7B,QAAQ,GAAG,eAAe,CACvB,KAAK,CAAC,MAAwB,IAAI,EAAE,EACrC,oBAAoB,EACpB,WAAW,EACX,OAAO,CACR,CAAC;IACJ,CAAC;SAAM,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QACnC,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACtF,CAAC;SAAM,CAAC;QACN,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC;aACzC,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;YAAE,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;QAErD,QAAQ,GAAG,2BAA2B,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,WAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,eAAe,GAAG,iCAAiC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC9E,IAAI,eAAe;YACjB,OAAO;gBACL,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE,KAAC,eAAe,IAAC,KAAK,EAAE,KAAK,GAAI;gBAC5C,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACzB,CAAC;IACN,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;SAChC,CAAC;IACJ,CAAC;IAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,OAAO;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ;aACT,CAAC;QACJ,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,OAAO;gBACL,IAAI,EACF,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC;oBAC7B,CAAC,CAAE,WAAW,KAAK,CAAC,KAAK,EAAiC;oBAC1D,CAAC,CAAC,WAAW;gBACjB,QAAQ;aACT,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;aACvB,CAAC;QACJ,CAAC;QACD,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,OAAO,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,OAAO,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO;oBACL,IAAI,EAAE,cAAc;oBACpB,KAAK,EAAE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACxD,QAAQ,EAAE,QAAwC;iBACnD,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,QAAwC;aACnD,CAAC;QACJ,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,QAAqB;aAChC,CAAC;QACJ,CAAC;QACD,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,OAAO;gBACL,IAAI,EAAE,aAAa;gBACnB,QAAQ;aACT,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO;gBACL,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,KAAK,CAAC,IAAI;gBACpB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;aACjC,CAAC;QACJ,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;YAElC,MAAM,eAAe,GAAG,4BAA4B,CAClD,UAAU,EACV,OAAO,EACP,oBAAoB,EACpB,WAAW,EACX,KAAK,CAAC,KAAK,EACX,IAAI,CACL,CAAC;YAEF,MAAM,aAAa,GAAG,4BAA4B,CAChD,QAAQ,EACR,OAAO,EACP,oBAAoB,EACpB,WAAW,EACX,KAAK,CAAC,KAAK,CACZ,CAAC;YAEF,MAAM,SAAS,GAAgC;gBAC7C,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,aAAa;aACxB,CAAC;YAEF,MAAM,aAAa,GAGjB,eAAe,CAAC,MAAM,GAAG,CAAC;gBACxB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,EAAE,SAAS,CAAC;gBAChE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAElB,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,aAAa;aACxB,CAAC;QACJ,CAAC;QACD,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACxB,CAAC;QACD,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,OAAO;gBACL,IAAI,EAAE,iBAAiB;gBACvB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACzB,CAAC;QACJ,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,GAAG,EAAE,KAAK,CAAC,IAAI;gBACf,GAAG,EAAE,KAAK,CAAC,IAAI;gBACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACzB,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,OAAO;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ;aACE,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,EAAE,GAAG,EAAE,EACP,eAAwC,EACpB,EAAE;IACtB,OAAO;QACL;YACE,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,2BAA2B,CAAC,EAAE,EAAE,eAAe,CAAC;SAC3D;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,uEAAuE;AACvE,yDAAyD;AACzD,MAAM,eAAe,GAAG,CACtB,EAAU,EACV,oBAA6C,EAC7C,WAAgD,EAC5B,EAAE;IACtB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAkB,CAAC;IAC9C,OAAO,eAAe,CAAC,MAAM,EAAE,oBAAoB,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC","sourcesContent":["import type { PegaCustom, Element, Text } from 'slate';\nimport { marked } from 'marked';\nimport type { MarkedToken, Tokens } from 'marked';\nimport type { ComponentType } from 'react';\n\nimport { hasProp } from '@pega/cosmos-react-core';\n\nimport type { TokenMap, InteractionRenderers, RichTextViewerProps } from '../RichTextViewer.types';\n\nimport parseTextToCustomSlateNodes from './interactionRenderer';\n\ntype TableColumnAlignment = 'left' | 'center' | 'right';\n\ntype MarkedTokenToSlateNode = (\n token: MarkedToken,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap']\n) => Element | Text;\n\nconst getTableColumnAlignment = (\n alignment: Tokens.Table['align'][number] | undefined\n): TableColumnAlignment | undefined => {\n if (alignment === 'left' || alignment === 'center' || alignment === 'right') {\n return alignment;\n }\n\n return undefined;\n};\n\nconst applyFormatting = (\n children: (Element | Text)[],\n token: MarkedToken,\n formatKey: 'italic' | 'bold' | 'code' | 'line-through'\n): Element | Text => {\n if (children.length === 1 && 'type' in children[0] && children[0].type === 'custom') {\n return {\n ...children[0],\n [formatKey]: true\n };\n }\n\n if (children.length > 1) {\n return {\n type: 'text',\n children: children.map(child => ({\n ...child,\n [formatKey]: true\n }))\n };\n }\n\n const baseNode =\n children.length > 0 && !('type' in children[0])\n ? children[0]\n : { text: 'text' in token ? token.text || '' : '' };\n\n return {\n ...baseNode,\n [formatKey]: true\n };\n};\n\nconst MARKED_TOKEN_TYPES = [\n 'blockquote',\n 'br',\n 'code',\n 'codespan',\n 'def',\n 'del',\n 'em',\n 'escape',\n 'heading',\n 'hr',\n 'html',\n 'image',\n 'link',\n 'list',\n 'list_item',\n 'paragraph',\n 'space',\n 'strong',\n 'table',\n 'text'\n] as const satisfies readonly MarkedToken['type'][];\nconst MARKED_TOKEN_TYPE_SET: ReadonlySet<string> = new Set(MARKED_TOKEN_TYPES);\n\nconst isMarkedToken = (token: MarkedToken | Tokens.Generic): token is MarkedToken =>\n MARKED_TOKEN_TYPE_SET.has(token.type);\n\nconst getCustomComponentFromMarkdownMap = <K extends keyof TokenMap>(\n token: TokenMap[K],\n markdownMap?: RichTextViewerProps['markdownMap']\n): ComponentType<{ token: TokenMap[K] }> | undefined => {\n return markdownMap?.[token.type]?.(token);\n};\n\n/** Flattens inline text wrappers so table cells get a flat list of Text nodes. */\nconst flattenInlineNodes = (nodes: (Element | Text)[]): (Element | Text)[] =>\n nodes.flatMap(node =>\n 'type' in node && node.type === 'text' && 'children' in node\n ? flattenInlineNodes(node.children)\n : [node]\n );\n\nconst markDownToSlate = (\n tokens: MarkedToken[],\n interactionRenderers: InteractionRenderers[] | undefined,\n markdownMap: RichTextViewerProps['markdownMap'] | undefined,\n convertTokenToSlateNode: MarkedTokenToSlateNode\n): (Element | Text)[] => {\n return tokens.map(token => {\n return convertTokenToSlateNode(token, interactionRenderers, markdownMap);\n });\n};\n\nconst convertTableCellToSlateNode = (\n cell: Tokens.TableCell,\n convertTokenToSlateNode: MarkedTokenToSlateNode,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n align?: TableColumnAlignment,\n isHeaderCell?: boolean\n): PegaCustom.TableCellElement => {\n const children = cell.tokens?.length\n ? flattenInlineNodes(\n markDownToSlate(\n cell.tokens.filter(isMarkedToken),\n interactionRenderers,\n markdownMap,\n convertTokenToSlateNode\n )\n )\n : parseTextToCustomSlateNodes(cell.text || '', interactionRenderers);\n\n const tableCell: PegaCustom.TableCellElement = {\n type: 'table-cell',\n ...(align ? { align } : {}),\n ...(isHeaderCell ? { isHeaderCell: true } : {}),\n children: children.length > 0 ? children : [{ text: '' }]\n };\n\n return tableCell;\n};\n\nconst convertTableRowsToSlateNodes = (\n rows: Tokens.TableCell[][],\n convertTokenToSlateNode: MarkedTokenToSlateNode,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n alignments?: Tokens.Table['align'],\n isHeaderCell?: boolean\n): PegaCustom.TableRowElement[] => {\n return rows.map(row => {\n return {\n type: 'table-row',\n children: row.map((cell, columnIndex) => {\n return convertTableCellToSlateNode(\n cell,\n convertTokenToSlateNode,\n interactionRenderers,\n markdownMap,\n getTableColumnAlignment(alignments?.[columnIndex]),\n isHeaderCell\n );\n })\n };\n });\n};\n\nexport const getNode = (\n token: MarkedToken,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap']\n): Element | Text => {\n if (!hasProp(token, 'type') || token.type === 'def')\n return { type: 'paragraph', children: [{ text: '' }] };\n\n if (token.type === 'html') {\n if (/^<br\\s*\\/?>$/i.test(token.raw.trim())) {\n return { text: '\\n' };\n }\n\n const parsed = parseTextToCustomSlateNodes(token.raw, interactionRenderers);\n if (parsed.length === 1) {\n return parsed[0];\n }\n return {\n type: 'paragraph',\n children: parsed\n };\n }\n\n let children: (Element | Text)[];\n\n if (hasProp(token, 'tokens')) {\n children = markDownToSlate(\n (token.tokens as MarkedToken[]) || [],\n interactionRenderers,\n markdownMap,\n getNode\n );\n } else if (hasProp(token, 'items')) {\n children = markDownToSlate(token.items, interactionRenderers, markdownMap, getNode);\n } else {\n let mdText = '';\n\n if (token.type === 'text') mdText = token.raw;\n else if (hasProp(token, 'text')) mdText = token.text;\n\n children = parseTextToCustomSlateNodes(mdText, interactionRenderers);\n }\n\n if (markdownMap?.[token.type]) {\n const CustomComponent = getCustomComponentFromMarkdownMap(token, markdownMap);\n if (CustomComponent)\n return {\n type: 'override',\n component: <CustomComponent token={token} />,\n children: [{ text: '' }]\n };\n }\n\n if (!children.length) {\n return {\n type: 'paragraph',\n children: [{ text: token.raw }]\n };\n }\n\n switch (token.type) {\n case 'paragraph': {\n return {\n type: token.type,\n children\n };\n }\n case 'heading': {\n return {\n type:\n token.depth && token.depth <= 4\n ? (`heading-${token.depth}` as `heading-${1 | 2 | 3 | 4}`)\n : 'heading-4',\n children\n };\n }\n case 'link': {\n return {\n href: token.href,\n text: token.text || ''\n };\n }\n case 'em': {\n return applyFormatting(children, token, 'italic');\n }\n case 'strong': {\n return applyFormatting(children, token, 'bold');\n }\n case 'del': {\n return applyFormatting(children, token, 'line-through');\n }\n case 'codespan': {\n return applyFormatting(children, token, 'code');\n }\n case 'list': {\n if (token.ordered) {\n return {\n type: 'ordered-list',\n start: typeof token.start === 'number' ? token.start : 1,\n children: children as PegaCustom.ListItemElement[]\n };\n }\n\n return {\n type: 'unordered-list',\n children: children as PegaCustom.ListItemElement[]\n };\n }\n case 'list_item': {\n return {\n type: 'list-item',\n children: children as Element[]\n };\n }\n case 'blockquote': {\n return {\n type: 'block-quote',\n children\n };\n }\n case 'code': {\n return {\n type: 'code-block',\n language: token.lang,\n children: [{ text: token.text }]\n };\n }\n case 'table': {\n const headerRows = token.header?.length ? [token.header] : [];\n const bodyRows = token.rows || [];\n\n const headerSlateRows = convertTableRowsToSlateNodes(\n headerRows,\n getNode,\n interactionRenderers,\n markdownMap,\n token.align,\n true\n );\n\n const bodySlateRows = convertTableRowsToSlateNodes(\n bodyRows,\n getNode,\n interactionRenderers,\n markdownMap,\n token.align\n );\n\n const tableBody: PegaCustom.TableBodyElement = {\n type: 'table-body',\n children: bodySlateRows\n };\n\n const tableChildren:\n | [PegaCustom.TableHeadElement, PegaCustom.TableBodyElement]\n | [PegaCustom.TableBodyElement] =\n headerSlateRows.length > 0\n ? [{ type: 'table-head', children: headerSlateRows }, tableBody]\n : [tableBody];\n\n return {\n type: 'table',\n children: tableChildren\n };\n }\n case 'br': {\n return { text: '\\n' };\n }\n case 'hr': {\n return {\n type: 'horizontal-rule',\n children: [{ text: '' }]\n };\n }\n case 'image': {\n return {\n type: 'image',\n alt: token.text,\n src: token.href,\n children: [{ text: '' }]\n };\n }\n default: {\n return {\n type: token.type,\n children\n } as Element;\n }\n }\n};\n\nexport const convertMarkdownForEditor = (\n md = '',\n searchRenderers?: InteractionRenderers[]\n): (Element | Text)[] => {\n return [\n {\n type: 'paragraph',\n children: parseTextToCustomSlateNodes(md, searchRenderers)\n }\n ];\n};\n\n// Converts markdown into Slate compatible nodes, also takes regex used\n// in Feed Component to pass them down to custom elements\nconst convertMarkdown = (\n md: string,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap']\n): (Element | Text)[] => {\n const lexer = new marked.Lexer({ gfm: true });\n const output = lexer.lex(md) as MarkedToken[];\n return markDownToSlate(output, interactionRenderers, markdownMap, getNode);\n};\n\nexport default convertMarkdown;\n"]}
|
|
1
|
+
{"version":3,"file":"markdownConverter.js","sourceRoot":"","sources":["../../../../src/components/RichTextEditor/utils/markdownConverter.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { PegaCustom, Element, Text } from 'slate';\nimport { marked } from 'marked';\nimport type { MarkedToken, Tokens } from 'marked';\nimport { parseFragment, serialize } from 'parse5';\nimport type * as parse5 from 'parse5';\nimport type { ComponentType } from 'react';\n\nimport { hasProp } from '@pega/cosmos-react-core';\n\nimport type { TokenMap, InteractionRenderers, RichTextViewerProps } from '../RichTextViewer.types';\n\nimport parseTextToCustomSlateNodes from './interactionRenderer';\n\ntype TableColumnAlignment = 'left' | 'center' | 'right';\n\ntype MarkedTokenToSlateNode = (\n token: MarkedToken,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n htmlEnabled?: boolean\n) => Element | Text;\n\nconst getTableColumnAlignment = (\n alignment: Tokens.Table['align'][number] | undefined\n): TableColumnAlignment | undefined => {\n if (alignment === 'left' || alignment === 'center' || alignment === 'right') {\n return alignment;\n }\n\n return undefined;\n};\n\nconst flattenInlineNodes = (nodes: (Element | Text)[]): (Element | Text)[] =>\n nodes.flatMap(node =>\n 'type' in node && node.type === 'text' && 'children' in node\n ? flattenInlineNodes(node.children)\n : [node]\n );\n\nconst applyFormatting = (\n children: (Element | Text)[],\n token: MarkedToken,\n formatKey: 'italic' | 'bold' | 'code' | 'line-through'\n): Element | Text => {\n if (children.length === 1 && 'type' in children[0] && children[0].type === 'custom') {\n return {\n ...children[0],\n [formatKey]: true\n };\n }\n\n if (children.length > 1) {\n const formattedChildren = flattenInlineNodes(children).map(child => ({\n ...child,\n [formatKey]: true\n }));\n\n return {\n type: 'text',\n children: formattedChildren\n };\n }\n\n const baseNode =\n children.length > 0 && !('type' in children[0])\n ? children[0]\n : { text: 'text' in token ? token.text || '' : '' };\n\n return {\n ...baseNode,\n [formatKey]: true\n };\n};\n\ntype InlineHtmlFormatKey =\n | 'italic'\n | 'bold'\n | 'underline'\n | 'line-through'\n | 'superscript'\n | 'subscript';\n\n// Limited set of inline HTML tags supported within markdown content.\nconst INLINE_HTML_TAG_FORMATS: Record<string, InlineHtmlFormatKey> = {\n em: 'italic',\n i: 'italic',\n strong: 'bold',\n b: 'bold',\n del: 'line-through',\n u: 'underline',\n sup: 'superscript',\n sub: 'subscript'\n};\n\ninterface HtmlTagToken {\n name: string;\n isClosing: boolean;\n attributes: Record<string, string>;\n}\n\nconst isParse5Element = (node: parse5.ChildNode | undefined): node is parse5.Element =>\n !!node && node.nodeName !== '#text' && node.nodeName !== '#comment';\n\nconst isParse5Text = (node: parse5.ChildNode): node is parse5.TextNode => node.nodeName === '#text';\n\nconst getParse5Attribute = (element: parse5.Element, name: string): string | undefined =>\n element.attrs.find(attr => attr.name === name)?.value;\n\n// Concatenates the text of a parse5 node and all of its descendants.\nconst getParse5TextContent = (node: parse5.ChildNode): string => {\n if (isParse5Text(node)) return node.value;\n if (isParse5Element(node)) return node.childNodes.map(getParse5TextContent).join('');\n return '';\n};\n\n// Wraps text in a fenced markdown code block, using a fence long enough to not collide with any\n// backtick run inside the content.\nconst toFencedCodeBlock = (code: string): string => {\n const longestBacktickRun = Math.max(0, ...(code.match(/`+/g) ?? []).map(run => run.length));\n const fence = '`'.repeat(Math.max(3, longestBacktickRun + 1));\n return `${fence}\\n${code}\\n${fence}`;\n};\n\n// Block-level HTML tags that are unwrapped and treated like markdown paragraphs.\nconst PARAGRAPH_LIKE_TAGS: ReadonlySet<string> = new Set(['div', 'p']);\n\n// Heading HTML tags mapped to the markdown heading prefix they are treated as.\nconst HEADING_TAG_PREFIXES: Record<string, string> = {\n h1: '#',\n h2: '##',\n h3: '###',\n h4: '####',\n h5: '#####',\n h6: '######'\n};\n\n// List container HTML tags.\nconst LIST_TAGS: ReadonlySet<string> = new Set(['ul', 'ol']);\n\nconst isListElement = (node: parse5.ChildNode): node is parse5.Element =>\n isParse5Element(node) && LIST_TAGS.has(node.nodeName);\n\n// Converts an HTML list (<ul>/<ol>) to the equivalent markdown list, recursing into nested lists\n// with increased indentation so the structure matches a hand-written markdown list.\nconst convertListToMarkdown = (list: parse5.Element, indent = ''): string => {\n const ordered = list.nodeName === 'ol';\n const start = ordered ? Number.parseInt(getParse5Attribute(list, 'start') ?? '', 10) : Number.NaN;\n let index = Number.isNaN(start) ? 1 : start;\n\n const lines: string[] = [];\n\n list.childNodes\n .filter((node): node is parse5.Element => isParse5Element(node) && node.nodeName === 'li')\n .forEach(item => {\n const marker = ordered ? `${index}.` : '-';\n const inlineChildren = item.childNodes.filter(child => !isListElement(child));\n const inline = serialize({ ...item, childNodes: inlineChildren }).trim();\n\n lines.push(`${indent}${marker} ${inline}`);\n\n item.childNodes.filter(isListElement).forEach(nested => {\n lines.push(convertListToMarkdown(nested, `${indent}${' '.repeat(marker.length + 1)}`));\n });\n\n index += 1;\n });\n\n return lines.join('\\n');\n};\n\n// A <pre> is only treated as a code block when its single element child is a <code>.\nconst isPreCodeBlock = (el: parse5.Element): boolean => {\n if (el.nodeName !== 'pre') return false;\n const elementChildren = el.childNodes.filter(isParse5Element);\n return elementChildren.length === 1 && elementChildren[0].nodeName === 'code';\n};\n\nconst isSupportedBlockElement = (el: parse5.Element): boolean =>\n PARAGRAPH_LIKE_TAGS.has(el.nodeName) ||\n el.nodeName in HEADING_TAG_PREFIXES ||\n el.nodeName === 'a' ||\n el.nodeName === 'img' ||\n LIST_TAGS.has(el.nodeName) ||\n isPreCodeBlock(el);\n\n// Returns the markdown representation of each top-level block (<div>/<p> as paragraphs, <h1>-<h6>\n// as `#`-prefixed headings, <a>/<img> as links/images, <ul>/<ol> as lists, <pre> as a code block)\n// when the block consists solely of supported blocks (ignoring whitespace), or undefined otherwise.\n// Used to treat those blocks like their markdown equivalents.\nconst getTopLevelBlockMarkdown = (raw: string): string[] | undefined => {\n const { childNodes } = parseFragment(raw.trim());\n const elements = childNodes.filter(isParse5Element);\n const hasStrayText = childNodes.some(node => isParse5Text(node) && node.value.trim() !== '');\n\n if (hasStrayText || elements.length === 0 || elements.some(el => !isSupportedBlockElement(el))) {\n return undefined;\n }\n\n return elements.map(el => {\n if (LIST_TAGS.has(el.nodeName)) {\n return convertListToMarkdown(el);\n }\n if (el.nodeName === 'pre') {\n return toFencedCodeBlock(getParse5TextContent(el));\n }\n const inner = serialize(el);\n if (el.nodeName === 'a') {\n return `[${inner}](${getParse5Attribute(el, 'href') ?? ''})`;\n }\n if (el.nodeName === 'img') {\n return ` ?? ''})`;\n }\n const headingPrefix = HEADING_TAG_PREFIXES[el.nodeName];\n return headingPrefix ? `${headingPrefix} ${inner}` : inner;\n });\n};\n\nconst MARKED_TOKEN_TYPES = [\n 'blockquote',\n 'br',\n 'code',\n 'codespan',\n 'def',\n 'del',\n 'em',\n 'escape',\n 'heading',\n 'hr',\n 'html',\n 'image',\n 'link',\n 'list',\n 'list_item',\n 'paragraph',\n 'space',\n 'strong',\n 'table',\n 'text'\n] as const satisfies readonly MarkedToken['type'][];\nconst MARKED_TOKEN_TYPE_SET: ReadonlySet<string> = new Set(MARKED_TOKEN_TYPES);\n\nconst isMarkedToken = (token: MarkedToken | Tokens.Generic): token is MarkedToken =>\n MARKED_TOKEN_TYPE_SET.has(token.type);\n\n// Expands top-level blocks (<div>/<p> and <h1> - <h6>) into the token stream they represent as\n// markdown, so a series of them behaves exactly like the equivalent blank-line-separated markdown\n// paragraphs and headings.\nconst expandTopLevelBlockTokens = (tokens: MarkedToken[]): MarkedToken[] =>\n tokens.flatMap(token => {\n if (token.type === 'html' && token.block) {\n const blockMarkdown = getTopLevelBlockMarkdown(token.raw);\n if (blockMarkdown) {\n return expandTopLevelBlockTokens(\n marked.lexer(blockMarkdown.join('\\n\\n'), { gfm: true }).filter(isMarkedToken)\n );\n }\n }\n return [token];\n });\n\n// Classifies a single HTML tag token, returning its lowercased tag name and whether it is a\n// closing tag. Opening tags are parsed with a real HTML parser; closing tags carry no attributes,\n// so their name is read directly and anything other than a bare `</name>` is rejected.\nconst parseHtmlTagToken = (raw: string): HtmlTagToken | undefined => {\n const trimmed = raw.trim();\n\n if (trimmed.startsWith('</')) {\n if (!trimmed.endsWith('>')) return undefined;\n const name = trimmed.slice(2, -1).trim().toLowerCase();\n return name && !/[\\s>/]/.test(name) ? { name, isClosing: true, attributes: {} } : undefined;\n }\n\n const [element] = parseFragment(trimmed).childNodes;\n if (!isParse5Element(element)) return undefined;\n const attributes = Object.fromEntries(element.attrs.map(attr => [attr.name, attr.value]));\n return { name: element.nodeName, isClosing: false, attributes };\n};\n\n// Inline HTML tags handled beyond text formatting: <span> unwraps to text, <a> becomes a link,\n// <img> becomes an image, and <code> becomes an inline code span.\nconst INLINE_HTML_STRUCTURAL_TAGS: ReadonlySet<string> = new Set(['span', 'a', 'img', 'code']);\n\nconst getSupportedInlineHtmlTag = (raw: string): HtmlTagToken | undefined => {\n const tag = parseHtmlTagToken(raw);\n if (!tag) return undefined;\n return tag.name in INLINE_HTML_TAG_FORMATS || INLINE_HTML_STRUCTURAL_TAGS.has(tag.name)\n ? tag\n : undefined;\n};\n\nconst getInlineHtmlFormat = (tagName: string): InlineHtmlFormatKey | undefined =>\n tagName in INLINE_HTML_TAG_FORMATS ? INLINE_HTML_TAG_FORMATS[tagName] : undefined;\n\n// Finds the index of the matching closing tag, accounting for nested tags of the same name.\nconst findInlineHtmlCloseIndex = (\n tokens: MarkedToken[],\n openIndex: number,\n tagName: string\n): number => {\n let depth = 1;\n\n for (let i = openIndex + 1; i < tokens.length; i += 1) {\n const token = tokens[i];\n if (token.type === 'html') {\n const tag = getSupportedInlineHtmlTag(token.raw);\n\n if (tag?.name === tagName) {\n depth += tag.isClosing ? -1 : 1;\n if (depth === 0) {\n return i;\n }\n }\n }\n }\n\n return -1;\n};\n\n// Applies an inline HTML formatting mark to a node and all of its descendant text nodes, matching\n// the leaf-level representation that regular markdown emphasis produces.\nconst applyInlineHtmlFormat = (\n node: Element | Text,\n formatKey: InlineHtmlFormatKey\n): Element | Text => {\n if ('type' in node) {\n if (node.type === 'custom') {\n return { ...node, [formatKey]: true };\n }\n\n if (node.type === 'text') {\n return {\n ...node,\n children: node.children.map(child => applyInlineHtmlFormat(child, formatKey))\n };\n }\n\n return node;\n }\n\n return { ...node, [formatKey]: true };\n};\n\n// Concatenates the text of a node and all of its descendants.\nconst getNodeText = (node: Element | Text): string =>\n 'children' in node ? node.children.map(getNodeText).join('') : node.text;\n\n// Builds a link leaf from an <a> tag's attributes and its inner nodes, matching the representation\n// of a markdown link (href plus plain text).\nconst createLinkNode = (\n attributes: Record<string, string>,\n innerNodes: (Element | Text)[]\n): Text => ({\n href: attributes.href ?? '',\n text: innerNodes.map(getNodeText).join('')\n});\n\n// Builds an image element from an <img> tag's attributes, matching the representation of a markdown\n// image.\nconst createImageNode = (attributes: Record<string, string>): PegaCustom.ImageElement => ({\n type: 'image',\n alt: attributes.alt ?? '',\n src: attributes.src ?? '',\n children: [{ text: '' }]\n});\n\nconst TEXT_MARK_KEYS = [\n 'bold',\n 'italic',\n 'line-through',\n 'code',\n 'underline',\n 'superscript',\n 'subscript'\n] as const;\n\nconst isPlainLeaf = (node: Text): boolean => !node.href && !node.searchResult;\n\n// Returns the single plain text leaf a node represents (either a bare leaf or a `text` element\n// wrapping exactly one plain leaf), or undefined when the node cannot be merged with a neighbor.\nconst asSingleLeaf = (node: Element | Text): Text | undefined => {\n if (!('type' in node)) {\n return isPlainLeaf(node) ? node : undefined;\n }\n\n if (node.type === 'text' && node.children.length === 1) {\n const [child] = node.children;\n if (!('type' in child) && isPlainLeaf(child)) {\n return child;\n }\n }\n\n return undefined;\n};\n\nconst haveSameMarks = (a: Text, b: Text): boolean =>\n TEXT_MARK_KEYS.every(key => !!a[key] === !!b[key]);\n\n// Merges adjacent plain text runs that share the same marks so that, for example, nested same-tag\n// emphasis collapses into a single formatted run (e.g. <strong><strong>foo</strong> bar</strong>\n// renders identically to **foo bar**).\nconst mergeAdjacentTextNodes = (nodes: (Element | Text)[]): (Element | Text)[] => {\n const merged: (Element | Text)[] = [];\n\n nodes.forEach(node => {\n const leaf = asSingleLeaf(node);\n const prev = merged[merged.length - 1];\n const prevLeaf = prev ? asSingleLeaf(prev) : undefined;\n\n if (leaf && prevLeaf && haveSameMarks(prevLeaf, leaf)) {\n merged[merged.length - 1] = { ...prevLeaf, text: prevLeaf.text + leaf.text };\n } else {\n merged.push(node);\n }\n });\n\n return merged;\n};\n\nconst getCustomComponentFromMarkdownMap = <K extends keyof TokenMap>(\n token: TokenMap[K],\n markdownMap?: RichTextViewerProps['markdownMap']\n): ComponentType<{ token: TokenMap[K] }> | undefined => {\n return markdownMap?.[token.type]?.(token);\n};\n\nconst markDownToSlate = (\n tokens: MarkedToken[],\n interactionRenderers: InteractionRenderers[] | undefined,\n markdownMap: RichTextViewerProps['markdownMap'] | undefined,\n convertTokenToSlateNode: MarkedTokenToSlateNode,\n htmlEnabled: boolean\n): (Element | Text)[] => {\n const nodes: (Element | Text)[] = [];\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n const openTag =\n htmlEnabled && token.type === 'html' ? getSupportedInlineHtmlTag(token.raw) : undefined;\n\n if (openTag && openTag.name === 'img' && !openTag.isClosing) {\n nodes.push(createImageNode(openTag.attributes));\n } else {\n const closeIndex =\n openTag && !openTag.isClosing ? findInlineHtmlCloseIndex(tokens, i, openTag.name) : -1;\n\n if (openTag && closeIndex !== -1) {\n if (openTag.name === 'code') {\n // <code> is treated like a markdown codespan: its raw content becomes a code-marked leaf.\n const innerRaw = tokens\n .slice(i + 1, closeIndex)\n .map(inner => inner.raw)\n .join('');\n nodes.push({ text: innerRaw, code: true });\n } else {\n const innerNodes = markDownToSlate(\n tokens.slice(i + 1, closeIndex),\n interactionRenderers,\n markdownMap,\n convertTokenToSlateNode,\n htmlEnabled\n );\n\n if (openTag.name === 'a') {\n nodes.push(createLinkNode(openTag.attributes, innerNodes));\n } else {\n const formatKey = getInlineHtmlFormat(openTag.name);\n if (formatKey) {\n innerNodes.forEach(innerNode => {\n nodes.push(applyInlineHtmlFormat(innerNode, formatKey));\n });\n } else {\n // Unwrapped tags (e.g. <span>) contribute their content as plain inline nodes.\n nodes.push(...innerNodes);\n }\n }\n }\n\n i = closeIndex;\n } else {\n nodes.push(convertTokenToSlateNode(token, interactionRenderers, markdownMap, htmlEnabled));\n }\n }\n }\n\n return htmlEnabled ? mergeAdjacentTextNodes(nodes) : nodes;\n};\n\nconst convertTableCellToSlateNode = (\n cell: Tokens.TableCell,\n convertTokenToSlateNode: MarkedTokenToSlateNode,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n align?: TableColumnAlignment,\n isHeaderCell?: boolean,\n htmlEnabled = false\n): PegaCustom.TableCellElement => {\n const children = cell.tokens?.length\n ? flattenInlineNodes(\n markDownToSlate(\n cell.tokens.filter(isMarkedToken),\n interactionRenderers,\n markdownMap,\n convertTokenToSlateNode,\n htmlEnabled\n )\n )\n : parseTextToCustomSlateNodes(cell.text || '', interactionRenderers);\n\n const tableCell: PegaCustom.TableCellElement = {\n type: 'table-cell',\n ...(align ? { align } : {}),\n ...(isHeaderCell ? { isHeaderCell: true } : {}),\n children: children.length > 0 ? children : [{ text: '' }]\n };\n\n return tableCell;\n};\n\nconst convertTableRowsToSlateNodes = (\n rows: Tokens.TableCell[][],\n convertTokenToSlateNode: MarkedTokenToSlateNode,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n alignments?: Tokens.Table['align'],\n isHeaderCell?: boolean,\n htmlEnabled = false\n): PegaCustom.TableRowElement[] => {\n return rows.map(row => {\n return {\n type: 'table-row',\n children: row.map((cell, columnIndex) => {\n return convertTableCellToSlateNode(\n cell,\n convertTokenToSlateNode,\n interactionRenderers,\n markdownMap,\n getTableColumnAlignment(alignments?.[columnIndex]),\n isHeaderCell,\n htmlEnabled\n );\n })\n };\n });\n};\n\nexport const getNode = (\n token: MarkedToken,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n htmlEnabled = false\n): Element | Text => {\n if (!hasProp(token, 'type') || token.type === 'def')\n return { type: 'paragraph', children: [{ text: '' }] };\n\n if (token.type === 'html') {\n if (parseHtmlTagToken(token.raw)?.name === 'br') {\n return { text: '\\n' };\n }\n\n const parsed = parseTextToCustomSlateNodes(token.raw, interactionRenderers);\n if (parsed.length === 1) {\n return parsed[0];\n }\n return {\n type: 'paragraph',\n children: parsed\n };\n }\n\n let children: (Element | Text)[];\n\n if (hasProp(token, 'tokens')) {\n children = markDownToSlate(\n (token.tokens as MarkedToken[]) || [],\n interactionRenderers,\n markdownMap,\n getNode,\n htmlEnabled\n );\n } else if (hasProp(token, 'items')) {\n children = markDownToSlate(\n token.items,\n interactionRenderers,\n markdownMap,\n getNode,\n htmlEnabled\n );\n } else {\n let mdText = '';\n\n if (token.type === 'text') mdText = token.raw;\n else if (hasProp(token, 'text')) mdText = token.text;\n\n children = parseTextToCustomSlateNodes(mdText, interactionRenderers);\n }\n\n if (markdownMap?.[token.type]) {\n const CustomComponent = getCustomComponentFromMarkdownMap(token, markdownMap);\n if (CustomComponent)\n return {\n type: 'override',\n component: <CustomComponent token={token} />,\n children: [{ text: '' }]\n };\n }\n\n if (!children.length) {\n return {\n type: 'paragraph',\n children: [{ text: token.raw }]\n };\n }\n\n switch (token.type) {\n case 'paragraph': {\n return {\n type: token.type,\n children\n };\n }\n case 'heading': {\n return {\n type:\n token.depth && token.depth <= 4\n ? (`heading-${token.depth}` as `heading-${1 | 2 | 3 | 4}`)\n : 'heading-4',\n children\n };\n }\n case 'link': {\n return {\n href: token.href,\n text: token.text || ''\n };\n }\n case 'em': {\n return applyFormatting(children, token, 'italic');\n }\n case 'strong': {\n return applyFormatting(children, token, 'bold');\n }\n case 'del': {\n return applyFormatting(children, token, 'line-through');\n }\n case 'codespan': {\n return applyFormatting(children, token, 'code');\n }\n case 'list': {\n if (token.ordered) {\n return {\n type: 'ordered-list',\n start: typeof token.start === 'number' ? token.start : 1,\n children: children as PegaCustom.ListItemElement[]\n };\n }\n\n return {\n type: 'unordered-list',\n children: children as PegaCustom.ListItemElement[]\n };\n }\n case 'list_item': {\n return {\n type: 'list-item',\n children: children as Element[]\n };\n }\n case 'blockquote': {\n return {\n type: 'block-quote',\n children\n };\n }\n case 'code': {\n return {\n type: 'code-block',\n language: token.lang,\n children: [{ text: token.text }]\n };\n }\n case 'table': {\n const headerRows = token.header?.length ? [token.header] : [];\n const bodyRows = token.rows || [];\n\n const headerSlateRows = convertTableRowsToSlateNodes(\n headerRows,\n getNode,\n interactionRenderers,\n markdownMap,\n token.align,\n true,\n htmlEnabled\n );\n\n const bodySlateRows = convertTableRowsToSlateNodes(\n bodyRows,\n getNode,\n interactionRenderers,\n markdownMap,\n token.align,\n false,\n htmlEnabled\n );\n\n const tableBody: PegaCustom.TableBodyElement = {\n type: 'table-body',\n children: bodySlateRows\n };\n\n const tableChildren:\n | [PegaCustom.TableHeadElement, PegaCustom.TableBodyElement]\n | [PegaCustom.TableBodyElement] =\n headerSlateRows.length > 0\n ? [{ type: 'table-head', children: headerSlateRows }, tableBody]\n : [tableBody];\n\n return {\n type: 'table',\n children: tableChildren\n };\n }\n case 'br': {\n return { text: '\\n' };\n }\n case 'hr': {\n return {\n type: 'horizontal-rule',\n children: [{ text: '' }]\n };\n }\n case 'image': {\n return {\n type: 'image',\n alt: token.text,\n src: token.href,\n children: [{ text: '' }]\n };\n }\n default: {\n return {\n type: token.type,\n children\n } as Element;\n }\n }\n};\n\nexport const convertMarkdownForEditor = (\n md = '',\n searchRenderers?: InteractionRenderers[]\n): (Element | Text)[] => {\n return [\n {\n type: 'paragraph',\n children: parseTextToCustomSlateNodes(md, searchRenderers)\n }\n ];\n};\n\n// Converts markdown into Slate compatible nodes, also takes regex used\n// in Feed Component to pass them down to custom elements\nconst convertMarkdown = (\n md: string,\n interactionRenderers?: InteractionRenderers[],\n markdownMap?: RichTextViewerProps['markdownMap'],\n htmlEnabled = false\n): (Element | Text)[] => {\n const lexer = new marked.Lexer({ gfm: true });\n const output = lexer.lex(md) as MarkedToken[];\n const tokens = htmlEnabled ? expandTopLevelBlockTokens(output) : output;\n return markDownToSlate(tokens, interactionRenderers, markdownMap, getNode, htmlEnabled);\n};\n\nexport default convertMarkdown;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../../../src/components/RichTextEditor/utils/renderers.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAa,YAAY,EAAE,MAAM,OAAO,CAAC;AAmBpE,eAAO,MAAM,iBAAiB,GAAI,mCAAmC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../../../src/components/RichTextEditor/utils/renderers.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAa,YAAY,EAAE,MAAM,OAAO,CAAC;AAmBpE,eAAO,MAAM,iBAAiB,GAAI,mCAAmC,kBAAkB,gBAgItF,CAAC;AAEF,KAAK,IAAI,GAAG;IACV,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EACN,GAAG,CAAC,OAAO,GACX,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,YAAY,CAAA;KAAE,CAAC,CAAC;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAGF,eAAO,MAAM,YAAY,GAAI,MAAM,IAAI,gBAsGtC,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,OAAO,eAAe,4CA6CvD,CAAC;AAEF,eAAO,MAAM,UAAU,+NAEtB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,UAAU,CAAC,IAAI,4CA4CjD,CAAC"}
|