@bayonai/rich-text-editor 0.1.2 → 1.0.0
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/BEHAVIOR.md +396 -0
- package/CHANGELOG.md +22 -0
- package/README.md +25 -6
- package/dist/core/blockTree.d.ts +14 -0
- package/dist/core/blockTree.js +126 -0
- package/dist/core/blockTypes.d.ts +6 -0
- package/dist/core/blockTypes.js +5 -0
- package/dist/core/exportImport.d.ts +59 -0
- package/dist/core/exportImport.js +51 -0
- package/dist/core/features.d.ts +59 -0
- package/dist/core/features.js +57 -0
- package/dist/core/imageBlockDiagnostics.d.ts +4 -0
- package/dist/core/imageBlockDiagnostics.js +19 -0
- package/dist/core/proFeatures.d.ts +60 -0
- package/dist/core/proFeatures.js +64 -0
- package/dist/{richText.d.ts → core/richText.d.ts} +2 -0
- package/dist/core/richText.js +566 -0
- package/dist/core/types.d.ts +78 -0
- package/dist/index.d.ts +14 -8
- package/dist/index.js +8 -5
- package/dist/react/editor/RichTextBody.d.ts +28 -0
- package/dist/react/editor/RichTextBody.js +131 -0
- package/dist/react/editor/RichTextEditor.d.ts +138 -0
- package/dist/react/editor/RichTextEditor.js +2925 -0
- package/dist/react/editor/RichTextRenderedBlock.d.ts +20 -0
- package/dist/react/editor/RichTextRenderedBlock.js +162 -0
- package/dist/react/editor/RichTextRenderer.d.ts +13 -0
- package/dist/react/editor/RichTextRenderer.js +16 -0
- package/dist/react/{RichTextTitleInput.d.ts → editor/RichTextTitleInput.d.ts} +11 -1
- package/dist/react/{RichTextTitleInput.js → editor/RichTextTitleInput.js} +17 -2
- package/dist/react/editor/blockActions.d.ts +48 -0
- package/dist/react/editor/blockActions.js +495 -0
- package/dist/react/editor/editorHistory.d.ts +55 -0
- package/dist/react/editor/editorHistory.js +111 -0
- package/dist/react/{editorNavigation.d.ts → editor/editorNavigation.d.ts} +2 -0
- package/dist/react/{editorNavigation.js → editor/editorNavigation.js} +16 -0
- package/dist/react/editor/editorOperations.d.ts +10 -0
- package/dist/react/editor/editorOperations.js +3 -0
- package/dist/react/editor/editorSelection.d.ts +3 -0
- package/dist/react/editor/editorSelection.js +215 -0
- package/dist/react/{editorShortcuts.d.ts → editor/editorShortcuts.d.ts} +10 -0
- package/dist/react/{editorShortcuts.js → editor/editorShortcuts.js} +17 -1
- package/dist/react/{RichTextIcons.d.ts → icons/RichTextIcons.d.ts} +3 -0
- package/dist/react/{RichTextIcons.js → icons/RichTextIcons.js} +9 -0
- package/dist/react/index.d.ts +12 -9
- package/dist/react/index.js +7 -6
- package/dist/react/{EditorSessionProvider.d.ts → session/EditorSessionProvider.d.ts} +2 -2
- package/dist/react/{EditorSessionProvider.js → session/EditorSessionProvider.js} +3 -3
- package/dist/react/{UnsavedChangesDialog.js → session/UnsavedChangesDialog.js} +1 -1
- package/dist/react/styles/RichTextStyles.js +1362 -0
- package/dist/react/{BlockActionTool.d.ts → tools/BlockActionTool.d.ts} +1 -1
- package/dist/react/{BlockActionTool.js → tools/BlockActionTool.js} +6 -2
- package/dist/react/tools/LinkCreationInput.d.ts +9 -0
- package/dist/react/tools/LinkCreationInput.js +38 -0
- package/dist/react/{SelectionFormatToolbar.d.ts → tools/SelectionFormatToolbar.d.ts} +3 -2
- package/dist/react/{SelectionFormatToolbar.js → tools/SelectionFormatToolbar.js} +3 -3
- package/dist/react/tools/SpecialBlockOption.d.ts +9 -0
- package/dist/react/tools/SpecialBlockOption.js +8 -0
- package/dist/react/tools/SpecialBlockTool.d.ts +91 -0
- package/dist/react/tools/SpecialBlockTool.js +125 -0
- package/dist/react/{TranscriptionControl.d.ts → tools/TranscriptionControl.d.ts} +9 -0
- package/dist/react/{TranscriptionControl.js → tools/TranscriptionControl.js} +70 -9
- package/dist/react/tools/blockActionToolState.d.ts +41 -0
- package/dist/react/tools/blockActionToolState.js +177 -0
- package/dist/react/tools/imageBlockDiagnostics.d.ts +2 -0
- package/dist/react/tools/imageBlockDiagnostics.js +12 -0
- package/dist/{session.d.ts → session/session.d.ts} +1 -1
- package/dist-cjs/core/blockTree.js +137 -0
- package/dist-cjs/core/blockTypes.js +9 -0
- package/dist-cjs/core/exportImport.js +56 -0
- package/dist-cjs/core/features.js +62 -0
- package/dist-cjs/core/proFeatures.js +70 -0
- package/dist-cjs/core/richText.js +578 -0
- package/dist-cjs/index.js +22 -6
- package/dist-cjs/react/editor/RichTextBody.js +134 -0
- package/dist-cjs/react/editor/RichTextEditor.js +2956 -0
- package/dist-cjs/react/editor/RichTextRenderedBlock.js +166 -0
- package/dist-cjs/react/editor/RichTextRenderer.js +20 -0
- package/dist-cjs/react/{RichTextTitleInput.js → editor/RichTextTitleInput.js} +18 -2
- package/dist-cjs/react/editor/blockActions.js +518 -0
- package/dist-cjs/react/editor/editorHistory.js +120 -0
- package/dist-cjs/react/{editorNavigation.js → editor/editorNavigation.js} +17 -0
- package/dist-cjs/react/editor/editorOperations.js +6 -0
- package/dist-cjs/react/editor/editorSelection.js +219 -0
- package/dist-cjs/react/{editorShortcuts.js → editor/editorShortcuts.js} +17 -1
- package/dist-cjs/react/{RichTextIcons.js → icons/RichTextIcons.js} +12 -0
- package/dist-cjs/react/index.js +9 -7
- package/dist-cjs/react/{EditorSessionProvider.js → session/EditorSessionProvider.js} +3 -3
- package/dist-cjs/react/{UnsavedChangesDialog.js → session/UnsavedChangesDialog.js} +1 -1
- package/dist-cjs/react/styles/RichTextStyles.js +1365 -0
- package/dist-cjs/react/{BlockActionTool.js → tools/BlockActionTool.js} +6 -2
- package/dist-cjs/react/tools/LinkCreationInput.js +41 -0
- package/dist-cjs/react/{SelectionFormatToolbar.js → tools/SelectionFormatToolbar.js} +3 -3
- package/dist-cjs/react/tools/SpecialBlockOption.js +11 -0
- package/dist-cjs/react/tools/SpecialBlockTool.js +129 -0
- package/dist-cjs/react/{TranscriptionControl.js → tools/TranscriptionControl.js} +71 -9
- package/dist-cjs/react/tools/blockActionToolState.js +186 -0
- package/package.json +3 -2
- package/dist/react/RichTextBody.d.ts +0 -18
- package/dist/react/RichTextBody.js +0 -66
- package/dist/react/RichTextEditor.d.ts +0 -45
- package/dist/react/RichTextEditor.js +0 -1096
- package/dist/react/RichTextRenderedBlock.d.ts +0 -4
- package/dist/react/RichTextRenderedBlock.js +0 -36
- package/dist/react/RichTextRenderer.d.ts +0 -4
- package/dist/react/RichTextRenderer.js +0 -8
- package/dist/react/RichTextStyles.js +0 -719
- package/dist/react/SpecialBlockOption.d.ts +0 -7
- package/dist/react/SpecialBlockOption.js +0 -7
- package/dist/react/SpecialBlockTool.d.ts +0 -42
- package/dist/react/SpecialBlockTool.js +0 -50
- package/dist/react/blockActionToolState.d.ts +0 -18
- package/dist/react/blockActionToolState.js +0 -53
- package/dist/react/blockActions.d.ts +0 -8
- package/dist/react/blockActions.js +0 -111
- package/dist/richText.js +0 -297
- package/dist/types.d.ts +0 -34
- package/dist-cjs/react/RichTextBody.js +0 -69
- package/dist-cjs/react/RichTextEditor.js +0 -1108
- package/dist-cjs/react/RichTextRenderedBlock.js +0 -39
- package/dist-cjs/react/RichTextRenderer.js +0 -11
- package/dist-cjs/react/RichTextStyles.js +0 -722
- package/dist-cjs/react/SpecialBlockOption.js +0 -10
- package/dist-cjs/react/SpecialBlockTool.js +0 -54
- package/dist-cjs/react/blockActionToolState.js +0 -58
- package/dist-cjs/react/blockActions.js +0 -119
- package/dist-cjs/richText.js +0 -307
- /package/dist/{types.js → core/types.js} +0 -0
- /package/dist/{writingStats.d.ts → core/writingStats.d.ts} +0 -0
- /package/dist/{writingStats.js → core/writingStats.js} +0 -0
- /package/dist/react/{RichTextDocumentSurface.d.ts → editor/RichTextDocumentSurface.d.ts} +0 -0
- /package/dist/react/{RichTextDocumentSurface.js → editor/RichTextDocumentSurface.js} +0 -0
- /package/dist/react/{UnsavedChangesDialog.d.ts → session/UnsavedChangesDialog.d.ts} +0 -0
- /package/dist/react/{RichTextStyles.d.ts → styles/RichTextStyles.d.ts} +0 -0
- /package/dist/react/{richTextBlockStyles.d.ts → styles/richTextBlockStyles.d.ts} +0 -0
- /package/dist/react/{richTextBlockStyles.js → styles/richTextBlockStyles.js} +0 -0
- /package/dist/react/{specialBlockStyles.d.ts → styles/specialBlockStyles.d.ts} +0 -0
- /package/dist/react/{specialBlockStyles.js → styles/specialBlockStyles.js} +0 -0
- /package/dist/{saveControl.d.ts → session/saveControl.d.ts} +0 -0
- /package/dist/{saveControl.js → session/saveControl.js} +0 -0
- /package/dist/{session.js → session/session.js} +0 -0
- /package/dist/{sessionRegistry.d.ts → session/sessionRegistry.d.ts} +0 -0
- /package/dist/{sessionRegistry.js → session/sessionRegistry.js} +0 -0
- /package/dist-cjs/{types.js → core/types.js} +0 -0
- /package/dist-cjs/{writingStats.js → core/writingStats.js} +0 -0
- /package/dist-cjs/react/{RichTextDocumentSurface.js → editor/RichTextDocumentSurface.js} +0 -0
- /package/dist-cjs/react/{richTextBlockStyles.js → styles/richTextBlockStyles.js} +0 -0
- /package/dist-cjs/react/{specialBlockStyles.js → styles/specialBlockStyles.js} +0 -0
- /package/dist-cjs/{saveControl.js → session/saveControl.js} +0 -0
- /package/dist-cjs/{session.js → session/session.js} +0 -0
- /package/dist-cjs/{sessionRegistry.js → session/sessionRegistry.js} +0 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEmptyRichTextBlocks = createEmptyRichTextBlocks;
|
|
4
|
+
exports.createRichTextBlockId = createRichTextBlockId;
|
|
5
|
+
exports.sanitizeRichTextBlocks = sanitizeRichTextBlocks;
|
|
6
|
+
exports.isRichTextBlocksEmpty = isRichTextBlocksEmpty;
|
|
7
|
+
exports.richTextBlocksToPlainText = richTextBlocksToPlainText;
|
|
8
|
+
exports.encodeRichTextBlocksForClipboard = encodeRichTextBlocksForClipboard;
|
|
9
|
+
exports.decodeRichTextBlocksFromClipboardText = decodeRichTextBlocksFromClipboardText;
|
|
10
|
+
exports.editorHtmlToMarkdown = editorHtmlToMarkdown;
|
|
11
|
+
exports.markdownToEditorHtml = markdownToEditorHtml;
|
|
12
|
+
exports.sanitizeRichTextHtml = sanitizeRichTextHtml;
|
|
13
|
+
const allowedInlineTags = new Set(["a", "br", "code", "em", "strong"]);
|
|
14
|
+
const textBlockTypes = new Set([
|
|
15
|
+
"paragraph",
|
|
16
|
+
"message",
|
|
17
|
+
"heading",
|
|
18
|
+
"quote",
|
|
19
|
+
"bullet",
|
|
20
|
+
"ordered",
|
|
21
|
+
"checkbox",
|
|
22
|
+
"toggle",
|
|
23
|
+
]);
|
|
24
|
+
const richTextClipboardPrefix = "bounded-rich-text-blocks-v1:";
|
|
25
|
+
const toolBlockStatuses = new Set([
|
|
26
|
+
"pending",
|
|
27
|
+
"success",
|
|
28
|
+
"error",
|
|
29
|
+
]);
|
|
30
|
+
const invalidToolData = Symbol("invalidToolData");
|
|
31
|
+
const maxToolDataDepth = 8;
|
|
32
|
+
function createEmptyRichTextBlocks() {
|
|
33
|
+
return [{ id: createRichTextBlockId(), type: "paragraph", markdown: "" }];
|
|
34
|
+
}
|
|
35
|
+
function createRichTextBlockId() {
|
|
36
|
+
if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
|
|
37
|
+
return crypto.randomUUID();
|
|
38
|
+
}
|
|
39
|
+
return `block-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Sanitizes an array of RichTextBlock objects by:
|
|
43
|
+
* - Filtering out invalid blocks
|
|
44
|
+
* - Ensuring each block has a unique ID
|
|
45
|
+
* - Returning an empty array if no valid blocks remain
|
|
46
|
+
*/
|
|
47
|
+
function sanitizeRichTextBlocks(value) {
|
|
48
|
+
return sanitizeRichTextBlocksWithSeen(value, new Set());
|
|
49
|
+
}
|
|
50
|
+
function sanitizeRichTextBlocksWithSeen(value, seenBlockIds) {
|
|
51
|
+
const blocks = Array.isArray(value) ? value : [];
|
|
52
|
+
const sanitized = blocks
|
|
53
|
+
.flatMap((block) => sanitizeRichTextBlock(block, seenBlockIds))
|
|
54
|
+
.map((block) => {
|
|
55
|
+
if (!seenBlockIds.has(block.id)) {
|
|
56
|
+
seenBlockIds.add(block.id);
|
|
57
|
+
return block;
|
|
58
|
+
}
|
|
59
|
+
const blockWithUniqueId = {
|
|
60
|
+
...block,
|
|
61
|
+
id: createUniqueRichTextBlockId(seenBlockIds),
|
|
62
|
+
};
|
|
63
|
+
seenBlockIds.add(blockWithUniqueId.id);
|
|
64
|
+
return blockWithUniqueId;
|
|
65
|
+
});
|
|
66
|
+
return sanitized.length > 0 ? sanitized : createEmptyRichTextBlocks();
|
|
67
|
+
}
|
|
68
|
+
function isRichTextBlocksEmpty(blocks) {
|
|
69
|
+
return sanitizeRichTextBlocks(blocks).every((block) => {
|
|
70
|
+
if (block.type === "divider") {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (block.type === "checkbox") {
|
|
74
|
+
return markdownToPlainText(block.markdown).trim() === "";
|
|
75
|
+
}
|
|
76
|
+
if (block.type === "image") {
|
|
77
|
+
return !block.url && typeof block.uploadProgress !== "number";
|
|
78
|
+
}
|
|
79
|
+
if (block.type === "tool") {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const text = block.type === "code" ? block.text : block.markdown;
|
|
83
|
+
return markdownToPlainText(text).trim() === "";
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function richTextBlocksToPlainText(blocks) {
|
|
87
|
+
return sanitizeRichTextBlocks(blocks)
|
|
88
|
+
.map((block) => {
|
|
89
|
+
if (block.type === "divider") {
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
if (block.type === "checkbox") {
|
|
93
|
+
return [
|
|
94
|
+
markdownToPlainText(block.markdown),
|
|
95
|
+
...richTextBlocksToPlainText(block.children ?? [])
|
|
96
|
+
.split(" ")
|
|
97
|
+
.filter(Boolean),
|
|
98
|
+
]
|
|
99
|
+
.filter(Boolean)
|
|
100
|
+
.join(" ");
|
|
101
|
+
}
|
|
102
|
+
if (block.type === "image") {
|
|
103
|
+
return block.alt ?? "";
|
|
104
|
+
}
|
|
105
|
+
if (block.type === "tool") {
|
|
106
|
+
return [
|
|
107
|
+
`[Tool: ${block.title || block.toolType} ${block.status}]`,
|
|
108
|
+
block.markdown ? markdownToPlainText(block.markdown) : "",
|
|
109
|
+
]
|
|
110
|
+
.filter(Boolean)
|
|
111
|
+
.join(" ");
|
|
112
|
+
}
|
|
113
|
+
if (block.type === "bullet" ||
|
|
114
|
+
block.type === "ordered" ||
|
|
115
|
+
block.type === "toggle") {
|
|
116
|
+
return [
|
|
117
|
+
markdownToPlainText(block.markdown),
|
|
118
|
+
richTextBlocksToPlainText(block.children ?? []),
|
|
119
|
+
]
|
|
120
|
+
.filter(Boolean)
|
|
121
|
+
.join(" ");
|
|
122
|
+
}
|
|
123
|
+
return block.type === "code"
|
|
124
|
+
? block.text
|
|
125
|
+
: markdownToPlainText(block.markdown);
|
|
126
|
+
})
|
|
127
|
+
.join(" ")
|
|
128
|
+
.replace(/\s+/g, " ")
|
|
129
|
+
.trim();
|
|
130
|
+
}
|
|
131
|
+
function encodeRichTextBlocksForClipboard(blocks) {
|
|
132
|
+
const sanitizedBlocks = sanitizeRichTextBlocks(blocks);
|
|
133
|
+
const encoded = encodeURIComponent(JSON.stringify(sanitizedBlocks));
|
|
134
|
+
const plainText = richTextBlocksToPlainText(sanitizedBlocks);
|
|
135
|
+
return `${richTextClipboardPrefix}${encoded}${plainText ? `\n${plainText}` : ""}`;
|
|
136
|
+
}
|
|
137
|
+
function decodeRichTextBlocksFromClipboardText(value) {
|
|
138
|
+
const [firstLine] = value.split(/\r?\n/, 1);
|
|
139
|
+
if (!firstLine?.startsWith(richTextClipboardPrefix)) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const decoded = decodeURIComponent(firstLine.slice(richTextClipboardPrefix.length));
|
|
144
|
+
const parsed = JSON.parse(decoded);
|
|
145
|
+
return Array.isArray(parsed) ? sanitizeRichTextBlocks(parsed) : null;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function editorHtmlToMarkdown(html) {
|
|
152
|
+
const sanitized = normalizeTypography(decodeHtmlText(sanitizeRichTextHtml(html)
|
|
153
|
+
.replace(/<br>/g, " \n")
|
|
154
|
+
.replace(/<strong>([\s\S]*?)<\/strong>/g, (_, value) => {
|
|
155
|
+
return `**${decodeHtmlText(stripTags(value))}**`;
|
|
156
|
+
})
|
|
157
|
+
.replace(/<em>([\s\S]*?)<\/em>/g, (_, value) => {
|
|
158
|
+
return `_${decodeHtmlText(stripTags(value))}_`;
|
|
159
|
+
})
|
|
160
|
+
.replace(/<code>([\s\S]*?)<\/code>/g, (_, value) => {
|
|
161
|
+
return `\`${decodeHtmlText(stripTags(value)).replace(/`/g, "\\`")}\``;
|
|
162
|
+
})
|
|
163
|
+
.replace(/<a href="([^"]*)">([\s\S]*?)<\/a>/g, (_, href, value) => {
|
|
164
|
+
return `[${decodeHtmlText(stripTags(value))}](${decodeHtmlText(href)})`;
|
|
165
|
+
})
|
|
166
|
+
.replace(/<a>([\s\S]*?)<\/a>/g, (_, value) => {
|
|
167
|
+
return decodeHtmlText(stripTags(value));
|
|
168
|
+
})
|
|
169
|
+
.replace(/<[^>]+>/g, ""))).replace(/\u00a0/g, " ");
|
|
170
|
+
return stripWhitespaceOnlyMarkdown(sanitized);
|
|
171
|
+
}
|
|
172
|
+
function markdownToEditorHtml(markdown) {
|
|
173
|
+
const tokens = [];
|
|
174
|
+
let html = escapeHtmlText(normalizeTypography(markdown));
|
|
175
|
+
html = html.replace(/`([^`\n]+)`/g, (_, value) => {
|
|
176
|
+
const token = pushToken(tokens, `<code>${value}</code>`);
|
|
177
|
+
return token;
|
|
178
|
+
});
|
|
179
|
+
html = html.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g, (_, label, href) => {
|
|
180
|
+
const safeHref = getSafeUrl(decodeHtmlText(href));
|
|
181
|
+
return safeHref ? `<a href="${safeHref}">${label}</a>` : label;
|
|
182
|
+
});
|
|
183
|
+
html = html
|
|
184
|
+
.replace(/\*\*([^*\n]+)\*\*/g, "<strong>$1</strong>")
|
|
185
|
+
.replace(/_([^_\n]+)_/g, "<em>$1</em>")
|
|
186
|
+
.replace(/ {2}\n/g, "<br>")
|
|
187
|
+
.replace(/\n/g, "<br>");
|
|
188
|
+
tokens.forEach((value, index) => {
|
|
189
|
+
html = html.replace(tokenPlaceholder(index), value);
|
|
190
|
+
});
|
|
191
|
+
return html;
|
|
192
|
+
}
|
|
193
|
+
function sanitizeRichTextHtml(html) {
|
|
194
|
+
return html
|
|
195
|
+
.replace(/<!--[\s\S]*?-->/g, "")
|
|
196
|
+
.replace(/<script[\s\S]*?<\/script>/gi, "")
|
|
197
|
+
.replace(/<style[\s\S]*?<\/style>/gi, "")
|
|
198
|
+
.replace(/<b(\s[^>]*)?>/gi, "<strong>")
|
|
199
|
+
.replace(/<\/b>/gi, "</strong>")
|
|
200
|
+
.replace(/<i(\s[^>]*)?>/gi, "<em>")
|
|
201
|
+
.replace(/<\/i>/gi, "</em>")
|
|
202
|
+
.replace(/<\/?([a-z0-9]+)([^>]*)>/gi, (match, rawTag, rawAttrs) => {
|
|
203
|
+
const tag = String(rawTag).toLowerCase();
|
|
204
|
+
const closing = match.startsWith("</");
|
|
205
|
+
if (!allowedInlineTags.has(tag)) {
|
|
206
|
+
return "";
|
|
207
|
+
}
|
|
208
|
+
if (closing) {
|
|
209
|
+
return tag === "br" ? "" : `</${tag}>`;
|
|
210
|
+
}
|
|
211
|
+
if (tag === "a") {
|
|
212
|
+
const href = getSafeAttribute(rawAttrs, "href");
|
|
213
|
+
return href ? `<a href="${href}">` : "<a>";
|
|
214
|
+
}
|
|
215
|
+
return tag === "br" ? "<br>" : `<${tag}>`;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function sanitizeRichTextBlock(block, seenBlockIds) {
|
|
219
|
+
if (!isRecord(block)) {
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
const id = readBlockId(block);
|
|
223
|
+
const type = block.type;
|
|
224
|
+
if (type === "code") {
|
|
225
|
+
return [{ id, type, text: String(block.text ?? "") }];
|
|
226
|
+
}
|
|
227
|
+
if (type === "divider") {
|
|
228
|
+
return [{ id, type }];
|
|
229
|
+
}
|
|
230
|
+
if (type === "image") {
|
|
231
|
+
const safeUrl = typeof block.url === "string" && getSafeUrl(block.url)
|
|
232
|
+
? getSafeUrl(block.url)
|
|
233
|
+
: "";
|
|
234
|
+
const uploadProgress = typeof block.uploadProgress === "number" &&
|
|
235
|
+
Number.isFinite(block.uploadProgress)
|
|
236
|
+
? clamp(Math.round(block.uploadProgress), 0, 100)
|
|
237
|
+
: null;
|
|
238
|
+
const displaySize = readImageDisplaySize(block.displaySize);
|
|
239
|
+
const customWidth = readImageCustomWidth(block.customWidth);
|
|
240
|
+
if (!safeUrl && uploadProgress === null) {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
return [
|
|
244
|
+
{
|
|
245
|
+
id,
|
|
246
|
+
type,
|
|
247
|
+
alignment: readImageAlignment(block.alignment),
|
|
248
|
+
...(displaySize ? { displaySize } : {}),
|
|
249
|
+
...(displaySize === "custom" && customWidth
|
|
250
|
+
? { customWidth }
|
|
251
|
+
: {}),
|
|
252
|
+
...(safeUrl ? { url: safeUrl } : {}),
|
|
253
|
+
...(typeof block.alt === "string" && block.alt.trim()
|
|
254
|
+
? { alt: markdownToPlainText(editorHtmlToMarkdown(block.alt)) }
|
|
255
|
+
: {}),
|
|
256
|
+
...(uploadProgress !== null ? { uploadProgress } : {}),
|
|
257
|
+
},
|
|
258
|
+
];
|
|
259
|
+
}
|
|
260
|
+
if (type === "tool") {
|
|
261
|
+
return [sanitizeToolBlock(block, id)];
|
|
262
|
+
}
|
|
263
|
+
if (typeof type === "string" && textBlockTypes.has(type)) {
|
|
264
|
+
const markdown = typeof block.markdown === "string"
|
|
265
|
+
? block.markdown
|
|
266
|
+
: typeof block.text === "string"
|
|
267
|
+
? block.text
|
|
268
|
+
: typeof block.html === "string"
|
|
269
|
+
? editorHtmlToMarkdown(block.html)
|
|
270
|
+
: "";
|
|
271
|
+
if (type === "bullet" || type === "ordered") {
|
|
272
|
+
return [
|
|
273
|
+
withSanitizedChildren({
|
|
274
|
+
id,
|
|
275
|
+
type: type,
|
|
276
|
+
markdown: sanitizeMarkdown(markdown),
|
|
277
|
+
}, block, seenBlockIds),
|
|
278
|
+
];
|
|
279
|
+
}
|
|
280
|
+
if (type === "checkbox") {
|
|
281
|
+
return [
|
|
282
|
+
withSanitizedChildren({
|
|
283
|
+
id,
|
|
284
|
+
type,
|
|
285
|
+
checked: Boolean(block.checked),
|
|
286
|
+
markdown: sanitizeMarkdown(markdown),
|
|
287
|
+
}, block, seenBlockIds),
|
|
288
|
+
];
|
|
289
|
+
}
|
|
290
|
+
if (type === "toggle") {
|
|
291
|
+
const children = sanitizeRichTextChildBlocksWithSeen(block.children, seenBlockIds);
|
|
292
|
+
return [
|
|
293
|
+
{
|
|
294
|
+
id,
|
|
295
|
+
type,
|
|
296
|
+
collapsed: Boolean(block.collapsed),
|
|
297
|
+
markdown: sanitizeMarkdown(markdown),
|
|
298
|
+
children,
|
|
299
|
+
},
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
return [
|
|
303
|
+
{
|
|
304
|
+
id,
|
|
305
|
+
type: type,
|
|
306
|
+
markdown: sanitizeMarkdown(markdown),
|
|
307
|
+
},
|
|
308
|
+
];
|
|
309
|
+
}
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
function sanitizeToolBlock(block, id) {
|
|
313
|
+
const toolType = readToolType(block.toolType, id);
|
|
314
|
+
const status = readToolStatus(block.status, id);
|
|
315
|
+
const title = typeof block.title === "string" && block.title.trim()
|
|
316
|
+
? markdownToPlainText(editorHtmlToMarkdown(block.title))
|
|
317
|
+
: "";
|
|
318
|
+
const markdown = typeof block.markdown === "string"
|
|
319
|
+
? sanitizeMarkdown(block.markdown)
|
|
320
|
+
: typeof block.text === "string"
|
|
321
|
+
? sanitizeMarkdown(block.text)
|
|
322
|
+
: typeof block.html === "string"
|
|
323
|
+
? sanitizeMarkdown(editorHtmlToMarkdown(block.html))
|
|
324
|
+
: "";
|
|
325
|
+
const dataResult = "data" in block ? sanitizeToolData(block.data, id) : null;
|
|
326
|
+
return {
|
|
327
|
+
id,
|
|
328
|
+
type: "tool",
|
|
329
|
+
toolType,
|
|
330
|
+
status,
|
|
331
|
+
...(title ? { title } : {}),
|
|
332
|
+
...(markdown ? { markdown } : {}),
|
|
333
|
+
...(dataResult?.value !== undefined ? { data: dataResult.value } : {}),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function readToolType(value, blockId) {
|
|
337
|
+
if (typeof value === "string" && value.trim()) {
|
|
338
|
+
return value.trim();
|
|
339
|
+
}
|
|
340
|
+
console.warn("[RichText] Tool block has an invalid toolType.", { blockId });
|
|
341
|
+
return "unknown";
|
|
342
|
+
}
|
|
343
|
+
function readToolStatus(value, blockId) {
|
|
344
|
+
if (typeof value === "string" &&
|
|
345
|
+
toolBlockStatuses.has(value)) {
|
|
346
|
+
return value;
|
|
347
|
+
}
|
|
348
|
+
console.warn("[RichText] Tool block has an invalid status.", {
|
|
349
|
+
blockId,
|
|
350
|
+
status: value,
|
|
351
|
+
});
|
|
352
|
+
return "success";
|
|
353
|
+
}
|
|
354
|
+
function sanitizeToolData(value, blockId) {
|
|
355
|
+
const result = sanitizeToolDataValue(value, {
|
|
356
|
+
depth: 0,
|
|
357
|
+
seen: new WeakSet(),
|
|
358
|
+
});
|
|
359
|
+
if (result.changed) {
|
|
360
|
+
console.warn("[RichText] Tool block data contained unsupported values.", {
|
|
361
|
+
blockId,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return result.value === invalidToolData
|
|
365
|
+
? null
|
|
366
|
+
: { changed: result.changed, value: result.value };
|
|
367
|
+
}
|
|
368
|
+
function sanitizeToolDataValue(value, context) {
|
|
369
|
+
if (value === null ||
|
|
370
|
+
typeof value === "boolean" ||
|
|
371
|
+
typeof value === "string") {
|
|
372
|
+
return { changed: false, value };
|
|
373
|
+
}
|
|
374
|
+
if (typeof value === "number") {
|
|
375
|
+
return Number.isFinite(value)
|
|
376
|
+
? { changed: false, value }
|
|
377
|
+
: { changed: true, value: invalidToolData };
|
|
378
|
+
}
|
|
379
|
+
if (typeof value !== "object" || value === undefined) {
|
|
380
|
+
return { changed: true, value: invalidToolData };
|
|
381
|
+
}
|
|
382
|
+
if (context.depth >= maxToolDataDepth) {
|
|
383
|
+
return { changed: true, value: invalidToolData };
|
|
384
|
+
}
|
|
385
|
+
if (context.seen.has(value)) {
|
|
386
|
+
return { changed: true, value: invalidToolData };
|
|
387
|
+
}
|
|
388
|
+
context.seen.add(value);
|
|
389
|
+
if (Array.isArray(value)) {
|
|
390
|
+
let changed = false;
|
|
391
|
+
const sanitizedArray = [];
|
|
392
|
+
value.forEach((item) => {
|
|
393
|
+
const result = sanitizeToolDataValue(item, {
|
|
394
|
+
depth: context.depth + 1,
|
|
395
|
+
seen: context.seen,
|
|
396
|
+
});
|
|
397
|
+
if (result.value === invalidToolData) {
|
|
398
|
+
changed = true;
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
changed = changed || result.changed;
|
|
402
|
+
sanitizedArray.push(result.value);
|
|
403
|
+
});
|
|
404
|
+
context.seen.delete(value);
|
|
405
|
+
return { changed, value: sanitizedArray };
|
|
406
|
+
}
|
|
407
|
+
const prototype = Object.getPrototypeOf(value);
|
|
408
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
409
|
+
context.seen.delete(value);
|
|
410
|
+
return { changed: true, value: invalidToolData };
|
|
411
|
+
}
|
|
412
|
+
let changed = false;
|
|
413
|
+
const sanitizedRecord = {};
|
|
414
|
+
Object.entries(value).forEach(([key, item]) => {
|
|
415
|
+
const result = sanitizeToolDataValue(item, {
|
|
416
|
+
depth: context.depth + 1,
|
|
417
|
+
seen: context.seen,
|
|
418
|
+
});
|
|
419
|
+
if (result.value === invalidToolData) {
|
|
420
|
+
changed = true;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
changed = changed || result.changed;
|
|
424
|
+
sanitizedRecord[key] = result.value;
|
|
425
|
+
});
|
|
426
|
+
context.seen.delete(value);
|
|
427
|
+
return { changed, value: sanitizedRecord };
|
|
428
|
+
}
|
|
429
|
+
function withSanitizedChildren(sanitizedBlock, rawBlock, seenBlockIds) {
|
|
430
|
+
const children = sanitizeRichTextChildBlocksWithSeen(rawBlock.children, seenBlockIds);
|
|
431
|
+
if (children.length === 0) {
|
|
432
|
+
return sanitizedBlock;
|
|
433
|
+
}
|
|
434
|
+
return { ...sanitizedBlock, children };
|
|
435
|
+
}
|
|
436
|
+
function sanitizeRichTextChildBlocksWithSeen(value, seenBlockIds) {
|
|
437
|
+
if (!Array.isArray(value)) {
|
|
438
|
+
return [];
|
|
439
|
+
}
|
|
440
|
+
return value
|
|
441
|
+
.flatMap((block) => sanitizeRichTextBlock(block, seenBlockIds))
|
|
442
|
+
.map((block) => {
|
|
443
|
+
if (!seenBlockIds.has(block.id)) {
|
|
444
|
+
seenBlockIds.add(block.id);
|
|
445
|
+
return block;
|
|
446
|
+
}
|
|
447
|
+
const blockWithUniqueId = {
|
|
448
|
+
...block,
|
|
449
|
+
id: createUniqueRichTextBlockId(seenBlockIds),
|
|
450
|
+
};
|
|
451
|
+
seenBlockIds.add(blockWithUniqueId.id);
|
|
452
|
+
return blockWithUniqueId;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
function readBlockId(block) {
|
|
456
|
+
return typeof block.id === "string" && block.id.trim()
|
|
457
|
+
? block.id.trim()
|
|
458
|
+
: createRichTextBlockId();
|
|
459
|
+
}
|
|
460
|
+
function createUniqueRichTextBlockId(existingIds) {
|
|
461
|
+
let id = createRichTextBlockId();
|
|
462
|
+
while (existingIds.has(id)) {
|
|
463
|
+
id = createRichTextBlockId();
|
|
464
|
+
}
|
|
465
|
+
return id;
|
|
466
|
+
}
|
|
467
|
+
function markdownToPlainText(value) {
|
|
468
|
+
return value
|
|
469
|
+
.replace(/`([^`]*)`/g, "$1")
|
|
470
|
+
.replace(/\*\*([^*]*)\*\*/g, "$1")
|
|
471
|
+
.replace(/_([^_]*)_/g, "$1")
|
|
472
|
+
.replace(/\[([^\]]*)\]\([^)]+\)/g, "$1")
|
|
473
|
+
.replace(/[#>*`_[\]()]/g, " ")
|
|
474
|
+
.replace(/\s+/g, " ")
|
|
475
|
+
.trim();
|
|
476
|
+
}
|
|
477
|
+
function sanitizeMarkdown(value) {
|
|
478
|
+
return stripWhitespaceOnlyMarkdown(normalizeTypography(value).replace(/<!--[\s\S]*?-->/g, ""));
|
|
479
|
+
}
|
|
480
|
+
function stripWhitespaceOnlyMarkdown(value) {
|
|
481
|
+
return value.trim().length > 0 ? value : "";
|
|
482
|
+
}
|
|
483
|
+
function normalizeTypography(value) {
|
|
484
|
+
const tokens = [];
|
|
485
|
+
let normalized = value.replace(/`([^`\n]+)`/g, (match) => {
|
|
486
|
+
return pushToken(tokens, match);
|
|
487
|
+
});
|
|
488
|
+
normalized = normalized.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g, (_match, label, href) => {
|
|
489
|
+
return `[${label}](${pushToken(tokens, href)})`;
|
|
490
|
+
});
|
|
491
|
+
normalized = normalized
|
|
492
|
+
.replace(/––/g, "—")
|
|
493
|
+
.replace(/–-/g, "—")
|
|
494
|
+
.replace(/---/g, "—")
|
|
495
|
+
.replace(/--/g, "–");
|
|
496
|
+
tokens.forEach((token, index) => {
|
|
497
|
+
normalized = normalized.replace(tokenPlaceholder(index), token);
|
|
498
|
+
});
|
|
499
|
+
return normalized;
|
|
500
|
+
}
|
|
501
|
+
function stripTags(value) {
|
|
502
|
+
return value.replace(/<[^>]+>/g, "");
|
|
503
|
+
}
|
|
504
|
+
function getSafeAttribute(attrs, name) {
|
|
505
|
+
const value = getPlainAttribute(attrs, name);
|
|
506
|
+
const safeValue = getSafeUrl(value);
|
|
507
|
+
if (!safeValue) {
|
|
508
|
+
return "";
|
|
509
|
+
}
|
|
510
|
+
return escapeAttribute(safeValue);
|
|
511
|
+
}
|
|
512
|
+
function getSafeUrl(value) {
|
|
513
|
+
const trimmed = value.trim();
|
|
514
|
+
if (!trimmed || /^javascript:/i.test(trimmed)) {
|
|
515
|
+
return "";
|
|
516
|
+
}
|
|
517
|
+
return trimmed;
|
|
518
|
+
}
|
|
519
|
+
function getPlainAttribute(attrs, name) {
|
|
520
|
+
const pattern = new RegExp(`${name}\\s*=\\s*("([^"]*)"|'([^']*)'|([^\\s>]+))`, "i");
|
|
521
|
+
const match = attrs.match(pattern);
|
|
522
|
+
return match?.[2] ?? match?.[3] ?? match?.[4] ?? "";
|
|
523
|
+
}
|
|
524
|
+
function escapeAttribute(value) {
|
|
525
|
+
return value
|
|
526
|
+
.replace(/&/g, "&")
|
|
527
|
+
.replace(/</g, "<")
|
|
528
|
+
.replace(/>/g, ">")
|
|
529
|
+
.replace(/"/g, """);
|
|
530
|
+
}
|
|
531
|
+
function escapeHtmlText(value) {
|
|
532
|
+
return value
|
|
533
|
+
.replace(/&/g, "&")
|
|
534
|
+
.replace(/</g, "<")
|
|
535
|
+
.replace(/>/g, ">");
|
|
536
|
+
}
|
|
537
|
+
function decodeHtmlText(value) {
|
|
538
|
+
return value
|
|
539
|
+
.replace(/ /g, " ")
|
|
540
|
+
.replace(/ /g, " ")
|
|
541
|
+
.replace(/ /gi, " ")
|
|
542
|
+
.replace(/&/g, "&")
|
|
543
|
+
.replace(/</g, "<")
|
|
544
|
+
.replace(/>/g, ">")
|
|
545
|
+
.replace(/"/g, '"')
|
|
546
|
+
.replace(/'/g, "'")
|
|
547
|
+
.replace(/'/g, "'");
|
|
548
|
+
}
|
|
549
|
+
function pushToken(tokens, value) {
|
|
550
|
+
const index = tokens.push(value) - 1;
|
|
551
|
+
return tokenPlaceholder(index);
|
|
552
|
+
}
|
|
553
|
+
function tokenPlaceholder(index) {
|
|
554
|
+
return `@@RICHTEXTTOKEN${index}@@`;
|
|
555
|
+
}
|
|
556
|
+
function clamp(value, min, max) {
|
|
557
|
+
return Math.min(Math.max(value, min), max);
|
|
558
|
+
}
|
|
559
|
+
function readImageAlignment(value) {
|
|
560
|
+
return value === "left" || value === "right" ? value : "center";
|
|
561
|
+
}
|
|
562
|
+
function readImageDisplaySize(value) {
|
|
563
|
+
return value === "small" ||
|
|
564
|
+
value === "medium" ||
|
|
565
|
+
value === "full" ||
|
|
566
|
+
value === "custom"
|
|
567
|
+
? value
|
|
568
|
+
: null;
|
|
569
|
+
}
|
|
570
|
+
function readImageCustomWidth(value) {
|
|
571
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
572
|
+
return null;
|
|
573
|
+
}
|
|
574
|
+
return clamp(Math.round(value), 120, 1600);
|
|
575
|
+
}
|
|
576
|
+
function isRecord(value) {
|
|
577
|
+
return typeof value === "object" && value !== null;
|
|
578
|
+
}
|
package/dist-cjs/index.js
CHANGED
|
@@ -1,22 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getWritingStats = exports.sanitizeRichTextHtml = exports.sanitizeRichTextBlocks = exports.richTextBlocksToPlainText = exports.markdownToEditorHtml = exports.isRichTextBlocksEmpty = exports.editorHtmlToMarkdown = exports.createRichTextBlockId = exports.createEmptyRichTextBlocks = exports.createEditorSessionRegistry = exports.getEditorSaveControlState = exports.defaultEditorSessionEquals = exports.createEditorSession = exports.canonicalSerialize = void 0;
|
|
4
|
-
var session_1 = require("./session");
|
|
3
|
+
exports.getWritingStats = exports.runRichTextSchemaMigrations = exports.instantiateRichTextTemplate = exports.createRichTextAnnotations = exports.connectRichTextCollaboration = exports.richTextJsonImportAdapter = exports.richTextJsonExportAdapter = exports.importRichTextBlocks = exports.exportRichTextBlocks = exports.richTextEditorFeatureCatalog = exports.isRichTextFeatureEnabled = exports.getRichTextFeatureAccess = exports.sanitizeRichTextHtml = exports.sanitizeRichTextBlocks = exports.richTextBlocksToPlainText = exports.markdownToEditorHtml = exports.isRichTextBlocksEmpty = exports.editorHtmlToMarkdown = exports.encodeRichTextBlocksForClipboard = exports.decodeRichTextBlocksFromClipboardText = exports.createRichTextBlockId = exports.createEmptyRichTextBlocks = exports.createEditorSessionRegistry = exports.getEditorSaveControlState = exports.defaultEditorSessionEquals = exports.createEditorSession = exports.canonicalSerialize = void 0;
|
|
4
|
+
var session_1 = require("./session/session");
|
|
5
5
|
Object.defineProperty(exports, "canonicalSerialize", { enumerable: true, get: function () { return session_1.canonicalSerialize; } });
|
|
6
6
|
Object.defineProperty(exports, "createEditorSession", { enumerable: true, get: function () { return session_1.createEditorSession; } });
|
|
7
7
|
Object.defineProperty(exports, "defaultEditorSessionEquals", { enumerable: true, get: function () { return session_1.defaultEditorSessionEquals; } });
|
|
8
|
-
var saveControl_1 = require("./saveControl");
|
|
8
|
+
var saveControl_1 = require("./session/saveControl");
|
|
9
9
|
Object.defineProperty(exports, "getEditorSaveControlState", { enumerable: true, get: function () { return saveControl_1.getEditorSaveControlState; } });
|
|
10
|
-
var sessionRegistry_1 = require("./sessionRegistry");
|
|
10
|
+
var sessionRegistry_1 = require("./session/sessionRegistry");
|
|
11
11
|
Object.defineProperty(exports, "createEditorSessionRegistry", { enumerable: true, get: function () { return sessionRegistry_1.createEditorSessionRegistry; } });
|
|
12
|
-
var richText_1 = require("./richText");
|
|
12
|
+
var richText_1 = require("./core/richText");
|
|
13
13
|
Object.defineProperty(exports, "createEmptyRichTextBlocks", { enumerable: true, get: function () { return richText_1.createEmptyRichTextBlocks; } });
|
|
14
14
|
Object.defineProperty(exports, "createRichTextBlockId", { enumerable: true, get: function () { return richText_1.createRichTextBlockId; } });
|
|
15
|
+
Object.defineProperty(exports, "decodeRichTextBlocksFromClipboardText", { enumerable: true, get: function () { return richText_1.decodeRichTextBlocksFromClipboardText; } });
|
|
16
|
+
Object.defineProperty(exports, "encodeRichTextBlocksForClipboard", { enumerable: true, get: function () { return richText_1.encodeRichTextBlocksForClipboard; } });
|
|
15
17
|
Object.defineProperty(exports, "editorHtmlToMarkdown", { enumerable: true, get: function () { return richText_1.editorHtmlToMarkdown; } });
|
|
16
18
|
Object.defineProperty(exports, "isRichTextBlocksEmpty", { enumerable: true, get: function () { return richText_1.isRichTextBlocksEmpty; } });
|
|
17
19
|
Object.defineProperty(exports, "markdownToEditorHtml", { enumerable: true, get: function () { return richText_1.markdownToEditorHtml; } });
|
|
18
20
|
Object.defineProperty(exports, "richTextBlocksToPlainText", { enumerable: true, get: function () { return richText_1.richTextBlocksToPlainText; } });
|
|
19
21
|
Object.defineProperty(exports, "sanitizeRichTextBlocks", { enumerable: true, get: function () { return richText_1.sanitizeRichTextBlocks; } });
|
|
20
22
|
Object.defineProperty(exports, "sanitizeRichTextHtml", { enumerable: true, get: function () { return richText_1.sanitizeRichTextHtml; } });
|
|
21
|
-
var
|
|
23
|
+
var features_1 = require("./core/features");
|
|
24
|
+
Object.defineProperty(exports, "getRichTextFeatureAccess", { enumerable: true, get: function () { return features_1.getRichTextFeatureAccess; } });
|
|
25
|
+
Object.defineProperty(exports, "isRichTextFeatureEnabled", { enumerable: true, get: function () { return features_1.isRichTextFeatureEnabled; } });
|
|
26
|
+
Object.defineProperty(exports, "richTextEditorFeatureCatalog", { enumerable: true, get: function () { return features_1.richTextEditorFeatureCatalog; } });
|
|
27
|
+
var exportImport_1 = require("./core/exportImport");
|
|
28
|
+
Object.defineProperty(exports, "exportRichTextBlocks", { enumerable: true, get: function () { return exportImport_1.exportRichTextBlocks; } });
|
|
29
|
+
Object.defineProperty(exports, "importRichTextBlocks", { enumerable: true, get: function () { return exportImport_1.importRichTextBlocks; } });
|
|
30
|
+
Object.defineProperty(exports, "richTextJsonExportAdapter", { enumerable: true, get: function () { return exportImport_1.richTextJsonExportAdapter; } });
|
|
31
|
+
Object.defineProperty(exports, "richTextJsonImportAdapter", { enumerable: true, get: function () { return exportImport_1.richTextJsonImportAdapter; } });
|
|
32
|
+
var proFeatures_1 = require("./core/proFeatures");
|
|
33
|
+
Object.defineProperty(exports, "connectRichTextCollaboration", { enumerable: true, get: function () { return proFeatures_1.connectRichTextCollaboration; } });
|
|
34
|
+
Object.defineProperty(exports, "createRichTextAnnotations", { enumerable: true, get: function () { return proFeatures_1.createRichTextAnnotations; } });
|
|
35
|
+
Object.defineProperty(exports, "instantiateRichTextTemplate", { enumerable: true, get: function () { return proFeatures_1.instantiateRichTextTemplate; } });
|
|
36
|
+
Object.defineProperty(exports, "runRichTextSchemaMigrations", { enumerable: true, get: function () { return proFeatures_1.runRichTextSchemaMigrations; } });
|
|
37
|
+
var writingStats_1 = require("./core/writingStats");
|
|
22
38
|
Object.defineProperty(exports, "getWritingStats", { enumerable: true, get: function () { return writingStats_1.getWritingStats; } });
|