@haklex/rich-editor 0.0.30 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{RichEditor-D1twFNL-.js → RichEditor-CXvIPtDS.js} +423 -73
- package/dist/components/decorators/GridEditDecorator.d.ts.map +1 -1
- package/dist/components/renderers/AlertStaticDecorator.d.ts +9 -0
- package/dist/components/renderers/AlertStaticDecorator.d.ts.map +1 -0
- package/dist/components/renderers/BannerStaticDecorator.d.ts +9 -0
- package/dist/components/renderers/BannerStaticDecorator.d.ts.map +1 -0
- package/dist/components/renderers/FootnoteStaticRenderer.d.ts +5 -0
- package/dist/components/renderers/FootnoteStaticRenderer.d.ts.map +1 -0
- package/dist/components/renderers/GridStaticDecorator.d.ts +9 -0
- package/dist/components/renderers/GridStaticDecorator.d.ts.map +1 -0
- package/dist/context/NestedContentRendererContext.d.ts +6 -0
- package/dist/context/NestedContentRendererContext.d.ts.map +1 -0
- package/dist/editor.mjs +2 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +95 -52
- package/dist/nodes/AlertQuoteEditNode.d.ts +9 -2
- package/dist/nodes/AlertQuoteEditNode.d.ts.map +1 -1
- package/dist/nodes/AlertQuoteNode.d.ts +5 -6
- package/dist/nodes/AlertQuoteNode.d.ts.map +1 -1
- package/dist/nodes/BannerEditNode.d.ts +9 -2
- package/dist/nodes/BannerEditNode.d.ts.map +1 -1
- package/dist/nodes/BannerNode.d.ts +5 -6
- package/dist/nodes/BannerNode.d.ts.map +1 -1
- package/dist/nodes/GridContainerNode.d.ts +3 -5
- package/dist/nodes/GridContainerNode.d.ts.map +1 -1
- package/dist/nodes/GridEditNode.d.ts +12 -1
- package/dist/nodes/GridEditNode.d.ts.map +1 -1
- package/dist/plugins/AlertPlugin.d.ts.map +1 -1
- package/dist/plugins/FootnotePlugin.d.ts.map +1 -1
- package/dist/rich-editor.css +1 -1
- package/dist/static-entry.d.ts +22 -0
- package/dist/static-entry.d.ts.map +1 -0
- package/dist/static-entry.mjs +39 -0
- package/dist/styles/shared.css.d.ts.map +1 -1
- package/dist/styles/theme.d.ts.map +1 -1
- package/dist/styles-entry.d.ts +7 -0
- package/dist/styles-entry.d.ts.map +1 -0
- package/dist/styles-entry.mjs +26 -0
- package/dist/{utils-BuZqZkYK.js → theme-C_ic3l9g.js} +665 -804
- package/dist/transformers/alert.d.ts.map +1 -1
- package/dist/transformers/container.d.ts.map +1 -1
- package/dist/transformers/grid-container.d.ts.map +1 -1
- package/dist/transformers/index.d.ts +1 -0
- package/dist/transformers/index.d.ts.map +1 -1
- package/dist/transformers/superscript-subscript.d.ts +2 -0
- package/dist/transformers/superscript-subscript.d.ts.map +1 -0
- package/dist/types.d.ts +0 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/extractTextContent.d.ts +3 -0
- package/dist/utils/extractTextContent.d.ts.map +1 -0
- package/dist/utils-C9cpKf8S.js +28 -0
- package/package.json +11 -7
- package/dist/RichRenderer-hHQ4JQs0.js +0 -113
- package/dist/components/RichRenderer.d.ts +0 -3
- package/dist/components/RichRenderer.d.ts.map +0 -1
- package/dist/renderer.d.ts +0 -3
- package/dist/renderer.d.ts.map +0 -1
- package/dist/renderer.mjs +0 -4
|
@@ -7,17 +7,24 @@ import { LinkNode, AutoLinkNode } from "@lexical/link";
|
|
|
7
7
|
import { ListNode, ListItemNode } from "@lexical/list";
|
|
8
8
|
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
9
9
|
import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
|
|
10
|
-
import { DecoratorNode,
|
|
11
|
-
import {
|
|
12
|
-
import { createContext, use, useMemo, createElement, useCallback, useState, useEffect, useRef } from "react";
|
|
10
|
+
import { DecoratorNode, $insertNodes, ElementNode, $getNodeByKey } from "lexical";
|
|
11
|
+
import { createContext, use, useMemo, createElement, useState, useRef, useEffect, useCallback } from "react";
|
|
13
12
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
14
|
-
import {
|
|
15
|
-
import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
|
|
16
|
-
import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
|
|
17
|
-
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
13
|
+
import { OctagonAlert, TriangleAlert, MessageSquareWarning, Lightbulb, Info, Code, ChevronRight, ImageIcon, Sigma, Link, Workflow, Video } from "lucide-react";
|
|
18
14
|
import { thumbHashToDataURL, rgbaToThumbHash } from "thumbhash";
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const NestedContentRendererContext = createContext(
|
|
16
|
+
null
|
|
17
|
+
);
|
|
18
|
+
const NestedContentRendererProvider = NestedContentRendererContext.Provider;
|
|
19
|
+
function useNestedContentRenderer() {
|
|
20
|
+
const fn = use(NestedContentRendererContext);
|
|
21
|
+
if (!fn) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"useNestedContentRenderer must be used within a NestedContentRendererProvider"
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return fn;
|
|
27
|
+
}
|
|
21
28
|
const RendererConfigContext = createContext({
|
|
22
29
|
config: void 0,
|
|
23
30
|
mode: "renderer",
|
|
@@ -79,10 +86,11 @@ const AlertRenderer = ({ type }) => {
|
|
|
79
86
|
/* @__PURE__ */ jsx("span", { className: "rich-alert-label", children: ALERT_LABELS[type] })
|
|
80
87
|
] });
|
|
81
88
|
};
|
|
82
|
-
function
|
|
89
|
+
function AlertStaticDecorator({
|
|
83
90
|
alertType,
|
|
84
|
-
|
|
91
|
+
contentState
|
|
85
92
|
}) {
|
|
93
|
+
const renderContent = useNestedContentRenderer();
|
|
86
94
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
87
95
|
/* @__PURE__ */ jsx(
|
|
88
96
|
RendererWrapper,
|
|
@@ -92,435 +100,18 @@ function AlertReadOnlyDecorator({
|
|
|
92
100
|
props: { type: alertType }
|
|
93
101
|
}
|
|
94
102
|
),
|
|
95
|
-
/* @__PURE__ */ jsx("div", { className: "rich-alert-content", children:
|
|
96
|
-
RichTextPlugin,
|
|
97
|
-
{
|
|
98
|
-
contentEditable: /* @__PURE__ */ jsx(
|
|
99
|
-
ContentEditable,
|
|
100
|
-
{
|
|
101
|
-
className: "rich-alert-content-editable",
|
|
102
|
-
style: { outline: "none" },
|
|
103
|
-
"aria-placeholder": "",
|
|
104
|
-
placeholder: /* @__PURE__ */ jsx("span", { style: { display: "none" } })
|
|
105
|
-
}
|
|
106
|
-
),
|
|
107
|
-
ErrorBoundary: LexicalErrorBoundary
|
|
108
|
-
}
|
|
109
|
-
) }) })
|
|
103
|
+
/* @__PURE__ */ jsx("div", { className: "rich-alert-content", children: renderContent(contentState) })
|
|
110
104
|
] });
|
|
111
105
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
code: "rich-text-code",
|
|
119
|
-
highlight: "rich-text-highlight"
|
|
120
|
-
},
|
|
121
|
-
heading: {
|
|
122
|
-
h1: "rich-heading-h1",
|
|
123
|
-
h2: "rich-heading-h2",
|
|
124
|
-
h3: "rich-heading-h3",
|
|
125
|
-
h4: "rich-heading-h4",
|
|
126
|
-
h5: "rich-heading-h5",
|
|
127
|
-
h6: "rich-heading-h6"
|
|
128
|
-
},
|
|
129
|
-
list: {
|
|
130
|
-
ol: "rich-list-ol",
|
|
131
|
-
ul: "rich-list-ul",
|
|
132
|
-
listitem: "rich-list-item",
|
|
133
|
-
listitemChecked: "rich-list-item-checked",
|
|
134
|
-
listitemUnchecked: "rich-list-item-unchecked",
|
|
135
|
-
checklist: "rich-checklist",
|
|
136
|
-
nested: {
|
|
137
|
-
listitem: "rich-list-nested-item"
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
quote: "rich-quote",
|
|
141
|
-
link: "rich-link",
|
|
142
|
-
paragraph: "rich-paragraph",
|
|
143
|
-
code: "rich-code-block",
|
|
144
|
-
table: "rich-table",
|
|
145
|
-
tableCell: "rich-table-cell",
|
|
146
|
-
tableCellHeader: "rich-table-cell-header",
|
|
147
|
-
tableScrollableWrapper: "rich-table-scrollable-wrapper",
|
|
148
|
-
/** Used by @lexical/extension HorizontalRuleNode */
|
|
149
|
-
hr: "rich-hr"
|
|
150
|
-
};
|
|
151
|
-
const FootnoteDefinitionsContext = createContext({
|
|
152
|
-
definitions: {},
|
|
153
|
-
displayNumberMap: {}
|
|
154
|
-
});
|
|
155
|
-
function FootnoteDefinitionsProvider({
|
|
156
|
-
definitions,
|
|
157
|
-
displayNumberMap,
|
|
158
|
-
children
|
|
159
|
-
}) {
|
|
160
|
-
const value = useMemo(
|
|
161
|
-
() => ({ definitions, displayNumberMap }),
|
|
162
|
-
[definitions, displayNumberMap]
|
|
163
|
-
);
|
|
164
|
-
return /* @__PURE__ */ jsx(FootnoteDefinitionsContext, { value, children });
|
|
165
|
-
}
|
|
166
|
-
function useFootnoteDefinitions() {
|
|
167
|
-
return use(FootnoteDefinitionsContext);
|
|
168
|
-
}
|
|
169
|
-
function useFootnoteContent(identifier) {
|
|
170
|
-
const { definitions } = use(FootnoteDefinitionsContext);
|
|
171
|
-
return definitions[identifier];
|
|
172
|
-
}
|
|
173
|
-
function useFootnoteDisplayNumber(identifier) {
|
|
174
|
-
const { displayNumberMap } = use(FootnoteDefinitionsContext);
|
|
175
|
-
return displayNumberMap[identifier];
|
|
176
|
-
}
|
|
177
|
-
function FootnoteRenderer({ identifier }) {
|
|
178
|
-
const content = useFootnoteContent(identifier);
|
|
179
|
-
const displayNumber = useFootnoteDisplayNumber(identifier);
|
|
180
|
-
const referenceId = `footnote-ref-${identifier}`;
|
|
181
|
-
const targetId = `footnote-${identifier}`;
|
|
182
|
-
const handleClick = useCallback(
|
|
183
|
-
(e) => {
|
|
184
|
-
const target = document.getElementById(targetId) || document.getElementById(`fn-${identifier}`);
|
|
185
|
-
if (!target) return;
|
|
186
|
-
e.preventDefault();
|
|
187
|
-
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
188
|
-
target.classList.add("rich-footnote-highlight");
|
|
189
|
-
window.setTimeout(() => {
|
|
190
|
-
target.classList.remove("rich-footnote-highlight");
|
|
191
|
-
}, 1200);
|
|
192
|
-
},
|
|
193
|
-
[identifier, targetId]
|
|
194
|
-
);
|
|
195
|
-
const label = displayNumber ?? identifier;
|
|
196
|
-
return /* @__PURE__ */ jsx("span", { className: "rich-footnote-ref-wrapper", children: /* @__PURE__ */ jsxs(TooltipRoot, { children: [
|
|
197
|
-
/* @__PURE__ */ jsx(
|
|
198
|
-
TooltipTrigger,
|
|
199
|
-
{
|
|
200
|
-
render: (props) => /* @__PURE__ */ jsx(
|
|
201
|
-
"a",
|
|
202
|
-
{
|
|
203
|
-
...props,
|
|
204
|
-
className: "rich-footnote-ref",
|
|
205
|
-
href: `#${targetId}`,
|
|
206
|
-
id: referenceId,
|
|
207
|
-
role: "doc-noteref",
|
|
208
|
-
"aria-label": content ? `Footnote ${label}: ${content}` : `Footnote ${label}`,
|
|
209
|
-
onClick: handleClick,
|
|
210
|
-
"data-footnote-ref": identifier,
|
|
211
|
-
children: label
|
|
212
|
-
}
|
|
213
|
-
)
|
|
214
|
-
}
|
|
215
|
-
),
|
|
216
|
-
content ? /* @__PURE__ */ jsx(TooltipContent, { children: content }) : null
|
|
217
|
-
] }) });
|
|
218
|
-
}
|
|
219
|
-
class FootnoteNode extends DecoratorNode {
|
|
220
|
-
constructor(identifier, key) {
|
|
221
|
-
super(key);
|
|
222
|
-
__publicField(this, "__identifier");
|
|
223
|
-
this.__identifier = identifier;
|
|
224
|
-
}
|
|
225
|
-
static getType() {
|
|
226
|
-
return "footnote";
|
|
227
|
-
}
|
|
228
|
-
static clone(node) {
|
|
229
|
-
return new FootnoteNode(node.__identifier, node.__key);
|
|
230
|
-
}
|
|
231
|
-
createDOM(_config) {
|
|
232
|
-
const sup = document.createElement("sup");
|
|
233
|
-
sup.className = "rich-footnote";
|
|
234
|
-
return sup;
|
|
235
|
-
}
|
|
236
|
-
updateDOM() {
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
isInline() {
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
static importJSON(serializedNode) {
|
|
243
|
-
return $createFootnoteNode(serializedNode.identifier);
|
|
244
|
-
}
|
|
245
|
-
exportJSON() {
|
|
246
|
-
return {
|
|
247
|
-
...super.exportJSON(),
|
|
248
|
-
type: "footnote",
|
|
249
|
-
identifier: this.__identifier,
|
|
250
|
-
version: 1
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
getIdentifier() {
|
|
254
|
-
return this.getLatest().__identifier;
|
|
255
|
-
}
|
|
256
|
-
setIdentifier(identifier) {
|
|
257
|
-
const writable = this.getWritable();
|
|
258
|
-
writable.__identifier = identifier;
|
|
259
|
-
}
|
|
260
|
-
decorate(_editor, _config) {
|
|
261
|
-
return createRendererDecoration("Footnote", FootnoteRenderer, {
|
|
262
|
-
identifier: this.__identifier
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
function $createFootnoteNode(identifier) {
|
|
267
|
-
return new FootnoteNode(identifier);
|
|
268
|
-
}
|
|
269
|
-
let katexModule = null;
|
|
270
|
-
let katexLoadPromise = null;
|
|
271
|
-
function loadKaTeX() {
|
|
272
|
-
if (katexModule) return Promise.resolve(katexModule);
|
|
273
|
-
if (!katexLoadPromise) {
|
|
274
|
-
katexLoadPromise = import("katex").then((mod) => {
|
|
275
|
-
katexModule = mod;
|
|
276
|
-
return katexModule;
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
return katexLoadPromise;
|
|
280
|
-
}
|
|
281
|
-
function KaTeXRenderer({ equation, displayMode }) {
|
|
282
|
-
const [html, setHtml] = useState(null);
|
|
283
|
-
const [error, setError] = useState(null);
|
|
284
|
-
useEffect(() => {
|
|
285
|
-
let cancelled = false;
|
|
286
|
-
loadKaTeX().then((katex) => {
|
|
287
|
-
if (cancelled) return;
|
|
288
|
-
const rendered = katex.default.renderToString(equation, {
|
|
289
|
-
displayMode,
|
|
290
|
-
throwOnError: false
|
|
291
|
-
});
|
|
292
|
-
setHtml(rendered);
|
|
293
|
-
setError(null);
|
|
294
|
-
}).catch(() => {
|
|
295
|
-
if (cancelled) return;
|
|
296
|
-
setHtml(null);
|
|
297
|
-
setError("KaTeX is not available");
|
|
298
|
-
});
|
|
299
|
-
return () => {
|
|
300
|
-
cancelled = true;
|
|
301
|
-
};
|
|
302
|
-
}, [equation, displayMode]);
|
|
303
|
-
if (error) {
|
|
304
|
-
return /* @__PURE__ */ jsx("code", { className: "rich-katex-fallback", children: equation });
|
|
305
|
-
}
|
|
306
|
-
if (html) {
|
|
307
|
-
return /* @__PURE__ */ jsx(
|
|
308
|
-
"span",
|
|
309
|
-
{
|
|
310
|
-
className: displayMode ? "rich-katex-block" : "rich-katex-inline",
|
|
311
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
312
|
-
}
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
return /* @__PURE__ */ jsx("code", { className: "rich-katex-fallback", children: equation });
|
|
316
|
-
}
|
|
317
|
-
class KaTeXInlineNode extends DecoratorNode {
|
|
318
|
-
constructor(equation, key) {
|
|
319
|
-
super(key);
|
|
320
|
-
__publicField(this, "__equation");
|
|
321
|
-
this.__equation = equation;
|
|
322
|
-
}
|
|
323
|
-
static getType() {
|
|
324
|
-
return "katex-inline";
|
|
325
|
-
}
|
|
326
|
-
static clone(node) {
|
|
327
|
-
return new KaTeXInlineNode(node.__equation, node.__key);
|
|
328
|
-
}
|
|
329
|
-
createDOM(_config) {
|
|
330
|
-
return document.createElement("span");
|
|
331
|
-
}
|
|
332
|
-
updateDOM() {
|
|
333
|
-
return false;
|
|
334
|
-
}
|
|
335
|
-
isInline() {
|
|
336
|
-
return true;
|
|
337
|
-
}
|
|
338
|
-
static importJSON(serializedNode) {
|
|
339
|
-
return $createKaTeXInlineNode(serializedNode.equation);
|
|
340
|
-
}
|
|
341
|
-
exportJSON() {
|
|
342
|
-
return {
|
|
343
|
-
...super.exportJSON(),
|
|
344
|
-
type: "katex-inline",
|
|
345
|
-
equation: this.__equation,
|
|
346
|
-
version: 1
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
getEquation() {
|
|
350
|
-
return this.__equation;
|
|
351
|
-
}
|
|
352
|
-
setEquation(equation) {
|
|
353
|
-
const writable = this.getWritable();
|
|
354
|
-
writable.__equation = equation;
|
|
355
|
-
}
|
|
356
|
-
decorate(_editor, _config) {
|
|
357
|
-
return createRendererDecoration("KaTeX", KaTeXRenderer, {
|
|
358
|
-
equation: this.__equation,
|
|
359
|
-
displayMode: false
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
function $createKaTeXInlineNode(equation) {
|
|
364
|
-
return new KaTeXInlineNode(equation);
|
|
365
|
-
}
|
|
366
|
-
function $isKaTeXInlineNode(node) {
|
|
367
|
-
return node instanceof KaTeXInlineNode;
|
|
368
|
-
}
|
|
369
|
-
function MentionRenderer({ handle, displayName }) {
|
|
370
|
-
const normalizedHandle = handle.replace(/^@+/, "");
|
|
371
|
-
const label = displayName || normalizedHandle;
|
|
372
|
-
return /* @__PURE__ */ jsx("span", { className: "rich-mention rich-mention-plain", children: /* @__PURE__ */ jsxs("span", { className: "rich-mention-handle", children: [
|
|
373
|
-
"@",
|
|
374
|
-
label
|
|
375
|
-
] }) });
|
|
376
|
-
}
|
|
377
|
-
class MentionNode extends DecoratorNode {
|
|
378
|
-
constructor(platform, handle, displayName, key) {
|
|
379
|
-
super(key);
|
|
380
|
-
__publicField(this, "__platform");
|
|
381
|
-
__publicField(this, "__handle");
|
|
382
|
-
__publicField(this, "__displayName");
|
|
383
|
-
this.__platform = platform;
|
|
384
|
-
this.__handle = handle;
|
|
385
|
-
this.__displayName = displayName;
|
|
386
|
-
}
|
|
387
|
-
static getType() {
|
|
388
|
-
return "mention";
|
|
389
|
-
}
|
|
390
|
-
static clone(node) {
|
|
391
|
-
return new MentionNode(
|
|
392
|
-
node.__platform,
|
|
393
|
-
node.__handle,
|
|
394
|
-
node.__displayName,
|
|
395
|
-
node.__key
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
createDOM(_config) {
|
|
399
|
-
const el = document.createElement("span");
|
|
400
|
-
el.style.display = "inline-flex";
|
|
401
|
-
el.style.alignItems = "center";
|
|
402
|
-
el.style.height = "1lh";
|
|
403
|
-
return el;
|
|
404
|
-
}
|
|
405
|
-
updateDOM() {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
isInline() {
|
|
409
|
-
return true;
|
|
410
|
-
}
|
|
411
|
-
getPlatform() {
|
|
412
|
-
return this.getLatest().__platform;
|
|
413
|
-
}
|
|
414
|
-
getHandle() {
|
|
415
|
-
return this.getLatest().__handle;
|
|
416
|
-
}
|
|
417
|
-
getDisplayName() {
|
|
418
|
-
return this.getLatest().__displayName;
|
|
419
|
-
}
|
|
420
|
-
static importJSON(serializedNode) {
|
|
421
|
-
return $createMentionNode(
|
|
422
|
-
serializedNode.platform,
|
|
423
|
-
serializedNode.handle,
|
|
424
|
-
serializedNode.displayName
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
exportJSON() {
|
|
428
|
-
return {
|
|
429
|
-
...super.exportJSON(),
|
|
430
|
-
type: "mention",
|
|
431
|
-
platform: this.__platform,
|
|
432
|
-
handle: this.__handle,
|
|
433
|
-
...this.__displayName ? { displayName: this.__displayName } : {},
|
|
434
|
-
version: 1
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
decorate(_editor, _config) {
|
|
438
|
-
return createRendererDecoration("Mention", MentionRenderer, {
|
|
439
|
-
platform: this.__platform,
|
|
440
|
-
handle: this.__handle,
|
|
441
|
-
displayName: this.__displayName
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
function $createMentionNode(platform, handle, displayName) {
|
|
446
|
-
return new MentionNode(platform, handle, displayName);
|
|
447
|
-
}
|
|
448
|
-
class SpoilerNode extends ElementNode {
|
|
449
|
-
static getType() {
|
|
450
|
-
return "spoiler";
|
|
451
|
-
}
|
|
452
|
-
static clone(node) {
|
|
453
|
-
return new SpoilerNode(node.__key);
|
|
454
|
-
}
|
|
455
|
-
constructor(key) {
|
|
456
|
-
super(key);
|
|
457
|
-
}
|
|
458
|
-
createDOM(_config) {
|
|
459
|
-
const span = document.createElement("span");
|
|
460
|
-
span.className = "rich-spoiler";
|
|
461
|
-
span.setAttribute("role", "button");
|
|
462
|
-
span.setAttribute("tabindex", "0");
|
|
463
|
-
span.setAttribute("aria-label", "Spoiler (click to reveal)");
|
|
464
|
-
const toggle = () => {
|
|
465
|
-
if (span.isContentEditable) return;
|
|
466
|
-
const revealed = span.classList.toggle("rich-spoiler-revealed");
|
|
467
|
-
span.setAttribute(
|
|
468
|
-
"aria-label",
|
|
469
|
-
revealed ? "Spoiler (revealed)" : "Spoiler (click to reveal)"
|
|
470
|
-
);
|
|
471
|
-
};
|
|
472
|
-
span.addEventListener("click", toggle);
|
|
473
|
-
span.addEventListener("keydown", (e) => {
|
|
474
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
475
|
-
e.preventDefault();
|
|
476
|
-
toggle();
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
return span;
|
|
480
|
-
}
|
|
481
|
-
updateDOM() {
|
|
482
|
-
return false;
|
|
483
|
-
}
|
|
484
|
-
static importJSON(_serializedNode) {
|
|
485
|
-
return $createSpoilerNode();
|
|
486
|
-
}
|
|
487
|
-
exportJSON() {
|
|
488
|
-
return {
|
|
489
|
-
...super.exportJSON(),
|
|
490
|
-
type: "spoiler",
|
|
491
|
-
version: 1
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
canInsertTextBefore() {
|
|
495
|
-
return true;
|
|
496
|
-
}
|
|
497
|
-
canInsertTextAfter() {
|
|
498
|
-
return true;
|
|
499
|
-
}
|
|
500
|
-
isInline() {
|
|
501
|
-
return true;
|
|
106
|
+
function extractTextContent(state) {
|
|
107
|
+
function walk(node) {
|
|
108
|
+
if (node.text) return node.text;
|
|
109
|
+
if (node.children) return node.children.map(walk).join("");
|
|
110
|
+
if (node.root) return walk(node.root);
|
|
111
|
+
return "";
|
|
502
112
|
}
|
|
113
|
+
return walk(state);
|
|
503
114
|
}
|
|
504
|
-
function $createSpoilerNode() {
|
|
505
|
-
return new SpoilerNode();
|
|
506
|
-
}
|
|
507
|
-
const NESTED_EDITOR_NODES = [
|
|
508
|
-
HeadingNode,
|
|
509
|
-
QuoteNode,
|
|
510
|
-
ListNode,
|
|
511
|
-
ListItemNode,
|
|
512
|
-
LinkNode,
|
|
513
|
-
AutoLinkNode,
|
|
514
|
-
HorizontalRuleNode,
|
|
515
|
-
CodeNode,
|
|
516
|
-
TableNode,
|
|
517
|
-
TableCellNode,
|
|
518
|
-
TableRowNode,
|
|
519
|
-
SpoilerNode,
|
|
520
|
-
MentionNode,
|
|
521
|
-
FootnoteNode,
|
|
522
|
-
KaTeXInlineNode
|
|
523
|
-
];
|
|
524
115
|
const ALERT_TYPES = [
|
|
525
116
|
"note",
|
|
526
117
|
"tip",
|
|
@@ -535,33 +126,39 @@ const ALERT_LABELS = {
|
|
|
535
126
|
warning: "Warning",
|
|
536
127
|
caution: "Caution"
|
|
537
128
|
};
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
namespace: "AlertContent",
|
|
541
|
-
nodes: NESTED_EDITOR_NODES,
|
|
542
|
-
theme: editorTheme,
|
|
543
|
-
onError: (error) => {
|
|
544
|
-
console.error("[AlertContent]", error);
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
const _AlertQuoteNode = class _AlertQuoteNode extends DecoratorNode {
|
|
549
|
-
constructor(alertType, contentEditor, key) {
|
|
129
|
+
class AlertQuoteNode extends DecoratorNode {
|
|
130
|
+
constructor(alertType, contentState, key) {
|
|
550
131
|
super(key);
|
|
551
132
|
__publicField(this, "__alertType");
|
|
552
|
-
__publicField(this, "
|
|
133
|
+
__publicField(this, "__contentState");
|
|
553
134
|
this.__alertType = alertType;
|
|
554
|
-
this.
|
|
135
|
+
this.__contentState = contentState || {
|
|
136
|
+
root: {
|
|
137
|
+
children: [
|
|
138
|
+
{
|
|
139
|
+
type: "paragraph",
|
|
140
|
+
children: [],
|
|
141
|
+
direction: null,
|
|
142
|
+
format: "",
|
|
143
|
+
indent: 0,
|
|
144
|
+
textFormat: 0,
|
|
145
|
+
textStyle: "",
|
|
146
|
+
version: 1
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
direction: null,
|
|
150
|
+
format: "",
|
|
151
|
+
indent: 0,
|
|
152
|
+
type: "root",
|
|
153
|
+
version: 1
|
|
154
|
+
}
|
|
155
|
+
};
|
|
555
156
|
}
|
|
556
157
|
static getType() {
|
|
557
158
|
return "alert-quote";
|
|
558
159
|
}
|
|
559
160
|
static clone(node) {
|
|
560
|
-
return new
|
|
561
|
-
node.__alertType,
|
|
562
|
-
node.__contentEditor,
|
|
563
|
-
node.__key
|
|
564
|
-
);
|
|
161
|
+
return new AlertQuoteNode(node.__alertType, node.__contentState, node.__key);
|
|
565
162
|
}
|
|
566
163
|
createDOM(_config) {
|
|
567
164
|
const div = document.createElement("div");
|
|
@@ -584,81 +181,34 @@ const _AlertQuoteNode = class _AlertQuoteNode extends DecoratorNode {
|
|
|
584
181
|
const writable = this.getWritable();
|
|
585
182
|
writable.__alertType = alertType;
|
|
586
183
|
}
|
|
587
|
-
|
|
588
|
-
return this.
|
|
184
|
+
getContentState() {
|
|
185
|
+
return this.getLatest().__contentState;
|
|
186
|
+
}
|
|
187
|
+
setContentState(state) {
|
|
188
|
+
const writable = this.getWritable();
|
|
189
|
+
writable.__contentState = state;
|
|
589
190
|
}
|
|
590
191
|
getTextContent() {
|
|
591
|
-
return this.
|
|
592
|
-
return $getRoot().getTextContent();
|
|
593
|
-
});
|
|
192
|
+
return extractTextContent(this.__contentState);
|
|
594
193
|
}
|
|
595
194
|
static importJSON(serializedNode) {
|
|
596
|
-
|
|
597
|
-
if (serializedNode.content) {
|
|
598
|
-
const editorState = node.__contentEditor.parseEditorState(
|
|
599
|
-
serializedNode.content
|
|
600
|
-
);
|
|
601
|
-
node.__contentEditor.setEditorState(editorState);
|
|
602
|
-
}
|
|
603
|
-
return node;
|
|
195
|
+
return new AlertQuoteNode(serializedNode.alertType, serializedNode.content);
|
|
604
196
|
}
|
|
605
197
|
exportJSON() {
|
|
606
198
|
return {
|
|
607
199
|
...super.exportJSON(),
|
|
608
200
|
type: "alert-quote",
|
|
609
201
|
alertType: this.__alertType,
|
|
610
|
-
content: this.
|
|
202
|
+
content: this.__contentState,
|
|
611
203
|
version: 1
|
|
612
204
|
};
|
|
613
205
|
}
|
|
614
206
|
decorate(_editor, _config) {
|
|
615
|
-
return createElement(
|
|
207
|
+
return createElement(AlertStaticDecorator, {
|
|
616
208
|
alertType: this.__alertType,
|
|
617
|
-
|
|
209
|
+
contentState: this.__contentState
|
|
618
210
|
});
|
|
619
211
|
}
|
|
620
|
-
};
|
|
621
|
-
__publicField(_AlertQuoteNode, "slashMenuItems", [
|
|
622
|
-
{
|
|
623
|
-
title: "Callout",
|
|
624
|
-
icon: createElement(Info, { size: 20 }),
|
|
625
|
-
description: "Info callout block",
|
|
626
|
-
keywords: ["alert", "note", "info", "callout"],
|
|
627
|
-
section: "ADVANCED",
|
|
628
|
-
onSelect: (editor) => {
|
|
629
|
-
editor.update(() => {
|
|
630
|
-
$insertNodes([$createAlertQuoteNode("note")]);
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
},
|
|
634
|
-
{
|
|
635
|
-
title: "Tip",
|
|
636
|
-
icon: createElement(Lightbulb, { size: 20 }),
|
|
637
|
-
description: "Highlight a useful tip",
|
|
638
|
-
keywords: ["alert", "tip", "hint"],
|
|
639
|
-
section: "ADVANCED",
|
|
640
|
-
onSelect: (editor) => {
|
|
641
|
-
editor.update(() => {
|
|
642
|
-
$insertNodes([$createAlertQuoteNode("tip")]);
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
},
|
|
646
|
-
{
|
|
647
|
-
title: "Warning",
|
|
648
|
-
icon: createElement(TriangleAlert, { size: 20 }),
|
|
649
|
-
description: "Warn about something",
|
|
650
|
-
keywords: ["alert", "warning", "caution"],
|
|
651
|
-
section: "ADVANCED",
|
|
652
|
-
onSelect: (editor) => {
|
|
653
|
-
editor.update(() => {
|
|
654
|
-
$insertNodes([$createAlertQuoteNode("warning")]);
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
]);
|
|
659
|
-
let AlertQuoteNode = _AlertQuoteNode;
|
|
660
|
-
function $createAlertQuoteNode(alertType) {
|
|
661
|
-
return new AlertQuoteNode(alertType);
|
|
662
212
|
}
|
|
663
213
|
function $isAlertQuoteNode(node) {
|
|
664
214
|
return node instanceof AlertQuoteNode;
|
|
@@ -666,10 +216,11 @@ function $isAlertQuoteNode(node) {
|
|
|
666
216
|
const BannerRenderer = ({ type }) => {
|
|
667
217
|
return /* @__PURE__ */ jsx("span", { className: `rich-banner-icon rich-banner-icon-${type}` });
|
|
668
218
|
};
|
|
669
|
-
function
|
|
219
|
+
function BannerStaticDecorator({
|
|
670
220
|
bannerType,
|
|
671
|
-
|
|
221
|
+
contentState
|
|
672
222
|
}) {
|
|
223
|
+
const renderContent = useNestedContentRenderer();
|
|
673
224
|
return /* @__PURE__ */ jsxs("div", { className: "rich-banner-inner", children: [
|
|
674
225
|
/* @__PURE__ */ jsx(
|
|
675
226
|
RendererWrapper,
|
|
@@ -679,21 +230,7 @@ function BannerReadOnlyDecorator({
|
|
|
679
230
|
props: { type: bannerType }
|
|
680
231
|
}
|
|
681
232
|
),
|
|
682
|
-
/* @__PURE__ */ jsx("div", { className: "rich-banner-content", children:
|
|
683
|
-
RichTextPlugin,
|
|
684
|
-
{
|
|
685
|
-
contentEditable: /* @__PURE__ */ jsx(
|
|
686
|
-
ContentEditable,
|
|
687
|
-
{
|
|
688
|
-
className: "rich-banner-content-editable",
|
|
689
|
-
style: { outline: "none" },
|
|
690
|
-
"aria-placeholder": "",
|
|
691
|
-
placeholder: /* @__PURE__ */ jsx("span", { style: { display: "none" } })
|
|
692
|
-
}
|
|
693
|
-
),
|
|
694
|
-
ErrorBoundary: LexicalErrorBoundary
|
|
695
|
-
}
|
|
696
|
-
) }) })
|
|
233
|
+
/* @__PURE__ */ jsx("div", { className: "rich-banner-content", children: renderContent(contentState) })
|
|
697
234
|
] });
|
|
698
235
|
}
|
|
699
236
|
const LEGACY_TYPE_MAP = {
|
|
@@ -719,29 +256,39 @@ const BANNER_LABELS = {
|
|
|
719
256
|
warning: "Warning",
|
|
720
257
|
caution: "Caution"
|
|
721
258
|
};
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
namespace: "BannerContent",
|
|
725
|
-
nodes: NESTED_EDITOR_NODES,
|
|
726
|
-
theme: editorTheme,
|
|
727
|
-
onError: (error) => {
|
|
728
|
-
console.error("[BannerContent]", error);
|
|
729
|
-
}
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
const _BannerNode = class _BannerNode extends DecoratorNode {
|
|
733
|
-
constructor(bannerType, contentEditor, key) {
|
|
259
|
+
class BannerNode extends DecoratorNode {
|
|
260
|
+
constructor(bannerType, contentState, key) {
|
|
734
261
|
super(key);
|
|
735
262
|
__publicField(this, "__bannerType");
|
|
736
|
-
__publicField(this, "
|
|
263
|
+
__publicField(this, "__contentState");
|
|
737
264
|
this.__bannerType = bannerType;
|
|
738
|
-
this.
|
|
265
|
+
this.__contentState = contentState || {
|
|
266
|
+
root: {
|
|
267
|
+
children: [
|
|
268
|
+
{
|
|
269
|
+
type: "paragraph",
|
|
270
|
+
children: [],
|
|
271
|
+
direction: null,
|
|
272
|
+
format: "",
|
|
273
|
+
indent: 0,
|
|
274
|
+
textFormat: 0,
|
|
275
|
+
textStyle: "",
|
|
276
|
+
version: 1
|
|
277
|
+
}
|
|
278
|
+
],
|
|
279
|
+
direction: null,
|
|
280
|
+
format: "",
|
|
281
|
+
indent: 0,
|
|
282
|
+
type: "root",
|
|
283
|
+
version: 1
|
|
284
|
+
}
|
|
285
|
+
};
|
|
739
286
|
}
|
|
740
287
|
static getType() {
|
|
741
288
|
return "banner";
|
|
742
289
|
}
|
|
743
290
|
static clone(node) {
|
|
744
|
-
return new
|
|
291
|
+
return new BannerNode(node.__bannerType, node.__contentState, node.__key);
|
|
745
292
|
}
|
|
746
293
|
createDOM(_config) {
|
|
747
294
|
const div = document.createElement("div");
|
|
@@ -764,24 +311,23 @@ const _BannerNode = class _BannerNode extends DecoratorNode {
|
|
|
764
311
|
const writable = this.getWritable();
|
|
765
312
|
writable.__bannerType = bannerType;
|
|
766
313
|
}
|
|
767
|
-
|
|
768
|
-
return this.
|
|
314
|
+
getContentState() {
|
|
315
|
+
return this.getLatest().__contentState;
|
|
316
|
+
}
|
|
317
|
+
setContentState(state) {
|
|
318
|
+
const writable = this.getWritable();
|
|
319
|
+
writable.__contentState = state;
|
|
769
320
|
}
|
|
770
321
|
getTextContent() {
|
|
771
|
-
return this.
|
|
772
|
-
return $getRoot().getTextContent();
|
|
773
|
-
});
|
|
322
|
+
return extractTextContent(this.__contentState);
|
|
774
323
|
}
|
|
775
324
|
static importJSON(serializedNode) {
|
|
776
325
|
const legacy = serializedNode;
|
|
777
326
|
const bannerType = normalizeBannerType(serializedNode.bannerType);
|
|
778
|
-
const node = new _BannerNode(bannerType);
|
|
779
327
|
if (serializedNode.content) {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
node.__contentEditor.setEditorState(editorState);
|
|
784
|
-
} else if (legacy.children) {
|
|
328
|
+
return new BannerNode(bannerType, serializedNode.content);
|
|
329
|
+
}
|
|
330
|
+
if (legacy.children) {
|
|
785
331
|
const content = {
|
|
786
332
|
root: {
|
|
787
333
|
children: legacy.children,
|
|
@@ -792,44 +338,25 @@ const _BannerNode = class _BannerNode extends DecoratorNode {
|
|
|
792
338
|
version: 1
|
|
793
339
|
}
|
|
794
340
|
};
|
|
795
|
-
|
|
796
|
-
node.__contentEditor.setEditorState(editorState);
|
|
341
|
+
return new BannerNode(bannerType, content);
|
|
797
342
|
}
|
|
798
|
-
return
|
|
343
|
+
return new BannerNode(bannerType);
|
|
799
344
|
}
|
|
800
345
|
exportJSON() {
|
|
801
346
|
return {
|
|
802
347
|
...super.exportJSON(),
|
|
803
348
|
type: "banner",
|
|
804
349
|
bannerType: this.__bannerType,
|
|
805
|
-
content: this.
|
|
350
|
+
content: this.__contentState,
|
|
806
351
|
version: 1
|
|
807
352
|
};
|
|
808
353
|
}
|
|
809
354
|
decorate(_editor, _config) {
|
|
810
|
-
return createElement(
|
|
355
|
+
return createElement(BannerStaticDecorator, {
|
|
811
356
|
bannerType: this.__bannerType,
|
|
812
|
-
|
|
357
|
+
contentState: this.__contentState
|
|
813
358
|
});
|
|
814
359
|
}
|
|
815
|
-
};
|
|
816
|
-
__publicField(_BannerNode, "slashMenuItems", [
|
|
817
|
-
{
|
|
818
|
-
title: "Banner",
|
|
819
|
-
icon: createElement(Flag, { size: 20 }),
|
|
820
|
-
description: "Highlighted banner block",
|
|
821
|
-
keywords: ["banner", "notice", "announcement"],
|
|
822
|
-
section: "ADVANCED",
|
|
823
|
-
onSelect: (editor) => {
|
|
824
|
-
editor.update(() => {
|
|
825
|
-
$insertNodes([$createBannerNode("note")]);
|
|
826
|
-
});
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
]);
|
|
830
|
-
let BannerNode = _BannerNode;
|
|
831
|
-
function $createBannerNode(bannerType) {
|
|
832
|
-
return new BannerNode(bannerType);
|
|
833
360
|
}
|
|
834
361
|
function $isBannerNode(node) {
|
|
835
362
|
return node instanceof BannerNode;
|
|
@@ -1152,6 +679,117 @@ let DetailsNode = _DetailsNode;
|
|
|
1152
679
|
function $createDetailsNode(summary, open = false) {
|
|
1153
680
|
return new DetailsNode(summary, open);
|
|
1154
681
|
}
|
|
682
|
+
const FootnoteDefinitionsContext = createContext({
|
|
683
|
+
definitions: {},
|
|
684
|
+
displayNumberMap: {}
|
|
685
|
+
});
|
|
686
|
+
function FootnoteDefinitionsProvider({
|
|
687
|
+
definitions,
|
|
688
|
+
displayNumberMap,
|
|
689
|
+
children
|
|
690
|
+
}) {
|
|
691
|
+
const value = useMemo(
|
|
692
|
+
() => ({ definitions, displayNumberMap }),
|
|
693
|
+
[definitions, displayNumberMap]
|
|
694
|
+
);
|
|
695
|
+
return /* @__PURE__ */ jsx(FootnoteDefinitionsContext, { value, children });
|
|
696
|
+
}
|
|
697
|
+
function useFootnoteDefinitions() {
|
|
698
|
+
return use(FootnoteDefinitionsContext);
|
|
699
|
+
}
|
|
700
|
+
function useFootnoteContent(identifier) {
|
|
701
|
+
const { definitions } = use(FootnoteDefinitionsContext);
|
|
702
|
+
return definitions[identifier];
|
|
703
|
+
}
|
|
704
|
+
function useFootnoteDisplayNumber(identifier) {
|
|
705
|
+
const { displayNumberMap } = use(FootnoteDefinitionsContext);
|
|
706
|
+
return displayNumberMap[identifier];
|
|
707
|
+
}
|
|
708
|
+
function FootnoteStaticRenderer({
|
|
709
|
+
identifier
|
|
710
|
+
}) {
|
|
711
|
+
const content = useFootnoteContent(identifier);
|
|
712
|
+
const displayNumber = useFootnoteDisplayNumber(identifier);
|
|
713
|
+
const referenceId = `footnote-ref-${identifier}`;
|
|
714
|
+
const targetId = `footnote-${identifier}`;
|
|
715
|
+
const handleClick = useCallback(
|
|
716
|
+
(e) => {
|
|
717
|
+
const target = document.getElementById(targetId) || document.getElementById(`fn-${identifier}`);
|
|
718
|
+
if (!target) return;
|
|
719
|
+
e.preventDefault();
|
|
720
|
+
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
721
|
+
target.classList.add("rich-footnote-highlight");
|
|
722
|
+
window.setTimeout(() => {
|
|
723
|
+
target.classList.remove("rich-footnote-highlight");
|
|
724
|
+
}, 1200);
|
|
725
|
+
},
|
|
726
|
+
[identifier, targetId]
|
|
727
|
+
);
|
|
728
|
+
const label = displayNumber ?? identifier;
|
|
729
|
+
return /* @__PURE__ */ jsx("span", { className: "rich-footnote-ref-wrapper", children: /* @__PURE__ */ jsx(
|
|
730
|
+
"a",
|
|
731
|
+
{
|
|
732
|
+
className: "rich-footnote-ref",
|
|
733
|
+
href: `#${targetId}`,
|
|
734
|
+
id: referenceId,
|
|
735
|
+
role: "doc-noteref",
|
|
736
|
+
"aria-label": content ? `Footnote ${label}: ${content}` : `Footnote ${label}`,
|
|
737
|
+
onClick: handleClick,
|
|
738
|
+
"data-footnote-ref": identifier,
|
|
739
|
+
children: label
|
|
740
|
+
}
|
|
741
|
+
) });
|
|
742
|
+
}
|
|
743
|
+
class FootnoteNode extends DecoratorNode {
|
|
744
|
+
constructor(identifier, key) {
|
|
745
|
+
super(key);
|
|
746
|
+
__publicField(this, "__identifier");
|
|
747
|
+
this.__identifier = identifier;
|
|
748
|
+
}
|
|
749
|
+
static getType() {
|
|
750
|
+
return "footnote";
|
|
751
|
+
}
|
|
752
|
+
static clone(node) {
|
|
753
|
+
return new FootnoteNode(node.__identifier, node.__key);
|
|
754
|
+
}
|
|
755
|
+
createDOM(_config) {
|
|
756
|
+
const sup = document.createElement("sup");
|
|
757
|
+
sup.className = "rich-footnote";
|
|
758
|
+
return sup;
|
|
759
|
+
}
|
|
760
|
+
updateDOM() {
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
isInline() {
|
|
764
|
+
return true;
|
|
765
|
+
}
|
|
766
|
+
static importJSON(serializedNode) {
|
|
767
|
+
return $createFootnoteNode(serializedNode.identifier);
|
|
768
|
+
}
|
|
769
|
+
exportJSON() {
|
|
770
|
+
return {
|
|
771
|
+
...super.exportJSON(),
|
|
772
|
+
type: "footnote",
|
|
773
|
+
identifier: this.__identifier,
|
|
774
|
+
version: 1
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
getIdentifier() {
|
|
778
|
+
return this.getLatest().__identifier;
|
|
779
|
+
}
|
|
780
|
+
setIdentifier(identifier) {
|
|
781
|
+
const writable = this.getWritable();
|
|
782
|
+
writable.__identifier = identifier;
|
|
783
|
+
}
|
|
784
|
+
decorate(_editor, _config) {
|
|
785
|
+
return createRendererDecoration("Footnote", FootnoteStaticRenderer, {
|
|
786
|
+
identifier: this.__identifier
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function $createFootnoteNode(identifier) {
|
|
791
|
+
return new FootnoteNode(identifier);
|
|
792
|
+
}
|
|
1155
793
|
function FootnoteSectionRenderer({
|
|
1156
794
|
definitions
|
|
1157
795
|
}) {
|
|
@@ -1292,11 +930,12 @@ function $createFootnoteSectionNode(definitions = {}) {
|
|
|
1292
930
|
function $isFootnoteSectionNode(node) {
|
|
1293
931
|
return node instanceof FootnoteSectionNode;
|
|
1294
932
|
}
|
|
1295
|
-
function
|
|
933
|
+
function GridStaticDecorator({
|
|
1296
934
|
cols,
|
|
1297
935
|
gap,
|
|
1298
|
-
|
|
936
|
+
cellStates
|
|
1299
937
|
}) {
|
|
938
|
+
const renderContent = useNestedContentRenderer();
|
|
1300
939
|
return /* @__PURE__ */ jsx(
|
|
1301
940
|
"div",
|
|
1302
941
|
{
|
|
@@ -1306,59 +945,53 @@ function GridReadOnlyDecorator({
|
|
|
1306
945
|
gridTemplateColumns: `repeat(${cols}, 1fr)`,
|
|
1307
946
|
gap
|
|
1308
947
|
},
|
|
1309
|
-
children:
|
|
1310
|
-
RichTextPlugin,
|
|
1311
|
-
{
|
|
1312
|
-
contentEditable: /* @__PURE__ */ jsx(
|
|
1313
|
-
ContentEditable,
|
|
1314
|
-
{
|
|
1315
|
-
className: "rich-grid-cell-editable",
|
|
1316
|
-
style: { outline: "none" },
|
|
1317
|
-
"aria-placeholder": "",
|
|
1318
|
-
placeholder: /* @__PURE__ */ jsx("span", { style: { display: "none" } })
|
|
1319
|
-
}
|
|
1320
|
-
),
|
|
1321
|
-
ErrorBoundary: LexicalErrorBoundary
|
|
1322
|
-
}
|
|
1323
|
-
) }) }, i))
|
|
948
|
+
children: cellStates.map((state, i) => /* @__PURE__ */ jsx("div", { className: "rich-grid-cell", children: renderContent(state) }, i))
|
|
1324
949
|
}
|
|
1325
950
|
);
|
|
1326
951
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
namespace: "GridCell",
|
|
1330
|
-
nodes: NESTED_EDITOR_NODES,
|
|
1331
|
-
theme: editorTheme,
|
|
1332
|
-
onError: (error) => {
|
|
1333
|
-
console.error("[GridCell]", error);
|
|
1334
|
-
}
|
|
1335
|
-
});
|
|
1336
|
-
}
|
|
1337
|
-
const _GridContainerNode = class _GridContainerNode extends DecoratorNode {
|
|
1338
|
-
constructor(cols = 2, gap, cellEditors, key) {
|
|
952
|
+
class GridContainerNode extends DecoratorNode {
|
|
953
|
+
constructor(cols = 2, gap, cellStates, key) {
|
|
1339
954
|
super(key);
|
|
1340
955
|
__publicField(this, "__cols");
|
|
1341
956
|
__publicField(this, "__gap");
|
|
1342
|
-
__publicField(this, "
|
|
957
|
+
__publicField(this, "__cellStates");
|
|
1343
958
|
this.__cols = cols;
|
|
1344
959
|
this.__gap = gap || "16px";
|
|
1345
|
-
if (
|
|
1346
|
-
this.
|
|
960
|
+
if (cellStates) {
|
|
961
|
+
this.__cellStates = cellStates;
|
|
1347
962
|
} else {
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
963
|
+
const emptyState = {
|
|
964
|
+
root: {
|
|
965
|
+
children: [
|
|
966
|
+
{
|
|
967
|
+
type: "paragraph",
|
|
968
|
+
children: [],
|
|
969
|
+
direction: null,
|
|
970
|
+
format: "",
|
|
971
|
+
indent: 0,
|
|
972
|
+
textFormat: 0,
|
|
973
|
+
textStyle: "",
|
|
974
|
+
version: 1
|
|
975
|
+
}
|
|
976
|
+
],
|
|
977
|
+
direction: null,
|
|
978
|
+
format: "",
|
|
979
|
+
indent: 0,
|
|
980
|
+
type: "root",
|
|
981
|
+
version: 1
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
this.__cellStates = Array.from({ length: cols }, () => emptyState);
|
|
1352
985
|
}
|
|
1353
986
|
}
|
|
1354
987
|
static getType() {
|
|
1355
988
|
return "grid-container";
|
|
1356
989
|
}
|
|
1357
990
|
static clone(node) {
|
|
1358
|
-
return new
|
|
991
|
+
return new GridContainerNode(
|
|
1359
992
|
node.__cols,
|
|
1360
993
|
node.__gap,
|
|
1361
|
-
[...node.
|
|
994
|
+
[...node.__cellStates],
|
|
1362
995
|
node.__key
|
|
1363
996
|
);
|
|
1364
997
|
}
|
|
@@ -1378,11 +1011,32 @@ const _GridContainerNode = class _GridContainerNode extends DecoratorNode {
|
|
|
1378
1011
|
}
|
|
1379
1012
|
setCols(cols) {
|
|
1380
1013
|
const writable = this.getWritable();
|
|
1381
|
-
const prev = writable.
|
|
1014
|
+
const prev = writable.__cellStates.length;
|
|
1382
1015
|
writable.__cols = cols;
|
|
1383
1016
|
if (cols > prev) {
|
|
1017
|
+
const emptyState = {
|
|
1018
|
+
root: {
|
|
1019
|
+
children: [
|
|
1020
|
+
{
|
|
1021
|
+
type: "paragraph",
|
|
1022
|
+
children: [],
|
|
1023
|
+
direction: null,
|
|
1024
|
+
format: "",
|
|
1025
|
+
indent: 0,
|
|
1026
|
+
textFormat: 0,
|
|
1027
|
+
textStyle: "",
|
|
1028
|
+
version: 1
|
|
1029
|
+
}
|
|
1030
|
+
],
|
|
1031
|
+
direction: null,
|
|
1032
|
+
format: "",
|
|
1033
|
+
indent: 0,
|
|
1034
|
+
type: "root",
|
|
1035
|
+
version: 1
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1384
1038
|
for (let i = prev; i < cols; i++) {
|
|
1385
|
-
writable.
|
|
1039
|
+
writable.__cellStates.push(emptyState);
|
|
1386
1040
|
}
|
|
1387
1041
|
}
|
|
1388
1042
|
}
|
|
@@ -1393,69 +1047,77 @@ const _GridContainerNode = class _GridContainerNode extends DecoratorNode {
|
|
|
1393
1047
|
const writable = this.getWritable();
|
|
1394
1048
|
writable.__gap = gap;
|
|
1395
1049
|
}
|
|
1396
|
-
|
|
1397
|
-
return this.getLatest().
|
|
1050
|
+
getCellStates() {
|
|
1051
|
+
return this.getLatest().__cellStates;
|
|
1398
1052
|
}
|
|
1399
1053
|
addCells(count) {
|
|
1400
1054
|
const writable = this.getWritable();
|
|
1055
|
+
const emptyState = {
|
|
1056
|
+
root: {
|
|
1057
|
+
children: [
|
|
1058
|
+
{
|
|
1059
|
+
type: "paragraph",
|
|
1060
|
+
children: [],
|
|
1061
|
+
direction: null,
|
|
1062
|
+
format: "",
|
|
1063
|
+
indent: 0,
|
|
1064
|
+
textFormat: 0,
|
|
1065
|
+
textStyle: "",
|
|
1066
|
+
version: 1
|
|
1067
|
+
}
|
|
1068
|
+
],
|
|
1069
|
+
direction: null,
|
|
1070
|
+
format: "",
|
|
1071
|
+
indent: 0,
|
|
1072
|
+
type: "root",
|
|
1073
|
+
version: 1
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1401
1076
|
for (let i = 0; i < count; i++) {
|
|
1402
|
-
writable.
|
|
1077
|
+
writable.__cellStates.push(emptyState);
|
|
1403
1078
|
}
|
|
1404
1079
|
}
|
|
1405
1080
|
removeCells(count) {
|
|
1406
1081
|
const writable = this.getWritable();
|
|
1407
|
-
const
|
|
1408
|
-
const toRemove = Math.min(count,
|
|
1082
|
+
const states = writable.__cellStates;
|
|
1083
|
+
const toRemove = Math.min(count, states.length);
|
|
1409
1084
|
for (let i = 0; i < toRemove; i++) {
|
|
1410
|
-
const
|
|
1411
|
-
if (!
|
|
1412
|
-
const isEmpty =
|
|
1413
|
-
return $getRoot().getTextContentSize() === 0;
|
|
1414
|
-
});
|
|
1085
|
+
const state = states.at(-1);
|
|
1086
|
+
if (!state) break;
|
|
1087
|
+
const isEmpty = extractTextContent(state).trim() === "";
|
|
1415
1088
|
if (!isEmpty) break;
|
|
1416
|
-
|
|
1089
|
+
states.pop();
|
|
1417
1090
|
}
|
|
1418
1091
|
}
|
|
1419
1092
|
getTextContent() {
|
|
1420
|
-
return this.
|
|
1421
|
-
(editor) => editor.getEditorState().read(() => $getRoot().getTextContent())
|
|
1422
|
-
).join("\n");
|
|
1093
|
+
return this.__cellStates.map((s) => extractTextContent(s)).join("\n");
|
|
1423
1094
|
}
|
|
1424
1095
|
static importJSON(serializedNode) {
|
|
1425
1096
|
const legacy = serializedNode;
|
|
1426
1097
|
const cols = legacy.cols || 2;
|
|
1427
1098
|
const rawGap = legacy.gap;
|
|
1428
1099
|
const gap = typeof rawGap === "number" ? `${rawGap}px` : rawGap;
|
|
1429
|
-
const node = new _GridContainerNode(cols, gap);
|
|
1430
1100
|
if (legacy.cells && legacy.cells.length > 0) {
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
version: 1
|
|
1450
|
-
}
|
|
1451
|
-
};
|
|
1452
|
-
const editorState = editor.parseEditorState(content);
|
|
1453
|
-
editor.setEditorState(editorState);
|
|
1454
|
-
return editor;
|
|
1455
|
-
});
|
|
1456
|
-
node.__cellEditors = editors;
|
|
1101
|
+
return new GridContainerNode(cols, gap, legacy.cells);
|
|
1102
|
+
}
|
|
1103
|
+
if (legacy.children) {
|
|
1104
|
+
const cellStates = legacy.children.map(
|
|
1105
|
+
(child) => {
|
|
1106
|
+
return {
|
|
1107
|
+
root: {
|
|
1108
|
+
children: [child],
|
|
1109
|
+
direction: null,
|
|
1110
|
+
format: "",
|
|
1111
|
+
indent: 0,
|
|
1112
|
+
type: "root",
|
|
1113
|
+
version: 1
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
);
|
|
1118
|
+
return new GridContainerNode(cols, gap, cellStates);
|
|
1457
1119
|
}
|
|
1458
|
-
return
|
|
1120
|
+
return new GridContainerNode(cols, gap);
|
|
1459
1121
|
}
|
|
1460
1122
|
exportJSON() {
|
|
1461
1123
|
return {
|
|
@@ -1463,35 +1125,18 @@ const _GridContainerNode = class _GridContainerNode extends DecoratorNode {
|
|
|
1463
1125
|
type: "grid-container",
|
|
1464
1126
|
cols: this.__cols,
|
|
1465
1127
|
gap: this.__gap,
|
|
1466
|
-
cells: this.
|
|
1467
|
-
(editor) => editor.getEditorState().toJSON()
|
|
1468
|
-
),
|
|
1128
|
+
cells: this.__cellStates,
|
|
1469
1129
|
version: 1
|
|
1470
1130
|
};
|
|
1471
1131
|
}
|
|
1472
1132
|
decorate(_editor, _config) {
|
|
1473
|
-
return createElement(
|
|
1133
|
+
return createElement(GridStaticDecorator, {
|
|
1474
1134
|
cols: this.__cols,
|
|
1475
1135
|
gap: this.__gap,
|
|
1476
|
-
|
|
1136
|
+
cellStates: this.__cellStates
|
|
1477
1137
|
});
|
|
1478
1138
|
}
|
|
1479
|
-
}
|
|
1480
|
-
__publicField(_GridContainerNode, "slashMenuItems", [
|
|
1481
|
-
{
|
|
1482
|
-
title: "Grid",
|
|
1483
|
-
icon: createElement(LayoutGrid, { size: 20 }),
|
|
1484
|
-
description: "Grid layout container",
|
|
1485
|
-
keywords: ["grid", "columns", "layout"],
|
|
1486
|
-
section: "LAYOUT",
|
|
1487
|
-
onSelect: (editor) => {
|
|
1488
|
-
editor.update(() => {
|
|
1489
|
-
$insertNodes([$createGridContainerNode(2)]);
|
|
1490
|
-
});
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
]);
|
|
1494
|
-
let GridContainerNode = _GridContainerNode;
|
|
1139
|
+
}
|
|
1495
1140
|
function $createGridContainerNode(cols = 2, gap) {
|
|
1496
1141
|
return new GridContainerNode(cols, gap);
|
|
1497
1142
|
}
|
|
@@ -1752,10 +1397,58 @@ __publicField(_ImageNode, "slashMenuItems", [
|
|
|
1752
1397
|
});
|
|
1753
1398
|
}
|
|
1754
1399
|
}
|
|
1755
|
-
]);
|
|
1756
|
-
let ImageNode = _ImageNode;
|
|
1757
|
-
function $createImageNode(payload) {
|
|
1758
|
-
return new ImageNode(payload);
|
|
1400
|
+
]);
|
|
1401
|
+
let ImageNode = _ImageNode;
|
|
1402
|
+
function $createImageNode(payload) {
|
|
1403
|
+
return new ImageNode(payload);
|
|
1404
|
+
}
|
|
1405
|
+
let katexModule = null;
|
|
1406
|
+
let katexLoadPromise = null;
|
|
1407
|
+
function loadKaTeX() {
|
|
1408
|
+
if (katexModule) return Promise.resolve(katexModule);
|
|
1409
|
+
if (!katexLoadPromise) {
|
|
1410
|
+
katexLoadPromise = import("katex").then((mod) => {
|
|
1411
|
+
katexModule = mod;
|
|
1412
|
+
return katexModule;
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
return katexLoadPromise;
|
|
1416
|
+
}
|
|
1417
|
+
function KaTeXRenderer({ equation, displayMode }) {
|
|
1418
|
+
const [html, setHtml] = useState(null);
|
|
1419
|
+
const [error, setError] = useState(null);
|
|
1420
|
+
useEffect(() => {
|
|
1421
|
+
let cancelled = false;
|
|
1422
|
+
loadKaTeX().then((katex) => {
|
|
1423
|
+
if (cancelled) return;
|
|
1424
|
+
const rendered = katex.default.renderToString(equation, {
|
|
1425
|
+
displayMode,
|
|
1426
|
+
throwOnError: false
|
|
1427
|
+
});
|
|
1428
|
+
setHtml(rendered);
|
|
1429
|
+
setError(null);
|
|
1430
|
+
}).catch(() => {
|
|
1431
|
+
if (cancelled) return;
|
|
1432
|
+
setHtml(null);
|
|
1433
|
+
setError("KaTeX is not available");
|
|
1434
|
+
});
|
|
1435
|
+
return () => {
|
|
1436
|
+
cancelled = true;
|
|
1437
|
+
};
|
|
1438
|
+
}, [equation, displayMode]);
|
|
1439
|
+
if (error) {
|
|
1440
|
+
return /* @__PURE__ */ jsx("code", { className: "rich-katex-fallback", children: equation });
|
|
1441
|
+
}
|
|
1442
|
+
if (html) {
|
|
1443
|
+
return /* @__PURE__ */ jsx(
|
|
1444
|
+
"span",
|
|
1445
|
+
{
|
|
1446
|
+
className: displayMode ? "rich-katex-block" : "rich-katex-inline",
|
|
1447
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
1448
|
+
}
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
1451
|
+
return /* @__PURE__ */ jsx("code", { className: "rich-katex-fallback", children: equation });
|
|
1759
1452
|
}
|
|
1760
1453
|
const _KaTeXBlockNode = class _KaTeXBlockNode extends DecoratorNode {
|
|
1761
1454
|
constructor(equation, key) {
|
|
@@ -1826,6 +1519,58 @@ function $createKaTeXBlockNode(equation) {
|
|
|
1826
1519
|
function $isKaTeXBlockNode(node) {
|
|
1827
1520
|
return node instanceof KaTeXBlockNode;
|
|
1828
1521
|
}
|
|
1522
|
+
class KaTeXInlineNode extends DecoratorNode {
|
|
1523
|
+
constructor(equation, key) {
|
|
1524
|
+
super(key);
|
|
1525
|
+
__publicField(this, "__equation");
|
|
1526
|
+
this.__equation = equation;
|
|
1527
|
+
}
|
|
1528
|
+
static getType() {
|
|
1529
|
+
return "katex-inline";
|
|
1530
|
+
}
|
|
1531
|
+
static clone(node) {
|
|
1532
|
+
return new KaTeXInlineNode(node.__equation, node.__key);
|
|
1533
|
+
}
|
|
1534
|
+
createDOM(_config) {
|
|
1535
|
+
return document.createElement("span");
|
|
1536
|
+
}
|
|
1537
|
+
updateDOM() {
|
|
1538
|
+
return false;
|
|
1539
|
+
}
|
|
1540
|
+
isInline() {
|
|
1541
|
+
return true;
|
|
1542
|
+
}
|
|
1543
|
+
static importJSON(serializedNode) {
|
|
1544
|
+
return $createKaTeXInlineNode(serializedNode.equation);
|
|
1545
|
+
}
|
|
1546
|
+
exportJSON() {
|
|
1547
|
+
return {
|
|
1548
|
+
...super.exportJSON(),
|
|
1549
|
+
type: "katex-inline",
|
|
1550
|
+
equation: this.__equation,
|
|
1551
|
+
version: 1
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
getEquation() {
|
|
1555
|
+
return this.__equation;
|
|
1556
|
+
}
|
|
1557
|
+
setEquation(equation) {
|
|
1558
|
+
const writable = this.getWritable();
|
|
1559
|
+
writable.__equation = equation;
|
|
1560
|
+
}
|
|
1561
|
+
decorate(_editor, _config) {
|
|
1562
|
+
return createRendererDecoration("KaTeX", KaTeXRenderer, {
|
|
1563
|
+
equation: this.__equation,
|
|
1564
|
+
displayMode: false
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
function $createKaTeXInlineNode(equation) {
|
|
1569
|
+
return new KaTeXInlineNode(equation);
|
|
1570
|
+
}
|
|
1571
|
+
function $isKaTeXInlineNode(node) {
|
|
1572
|
+
return node instanceof KaTeXInlineNode;
|
|
1573
|
+
}
|
|
1829
1574
|
function LinkCardRenderer({
|
|
1830
1575
|
url,
|
|
1831
1576
|
title,
|
|
@@ -1992,6 +1737,85 @@ function $createLinkCardNode(payload) {
|
|
|
1992
1737
|
function $isLinkCardNode(node) {
|
|
1993
1738
|
return node instanceof LinkCardNode;
|
|
1994
1739
|
}
|
|
1740
|
+
function MentionRenderer({ handle, displayName }) {
|
|
1741
|
+
const normalizedHandle = handle.replace(/^@+/, "");
|
|
1742
|
+
const label = displayName || normalizedHandle;
|
|
1743
|
+
return /* @__PURE__ */ jsx("span", { className: "rich-mention rich-mention-plain", children: /* @__PURE__ */ jsxs("span", { className: "rich-mention-handle", children: [
|
|
1744
|
+
"@",
|
|
1745
|
+
label
|
|
1746
|
+
] }) });
|
|
1747
|
+
}
|
|
1748
|
+
class MentionNode extends DecoratorNode {
|
|
1749
|
+
constructor(platform, handle, displayName, key) {
|
|
1750
|
+
super(key);
|
|
1751
|
+
__publicField(this, "__platform");
|
|
1752
|
+
__publicField(this, "__handle");
|
|
1753
|
+
__publicField(this, "__displayName");
|
|
1754
|
+
this.__platform = platform;
|
|
1755
|
+
this.__handle = handle;
|
|
1756
|
+
this.__displayName = displayName;
|
|
1757
|
+
}
|
|
1758
|
+
static getType() {
|
|
1759
|
+
return "mention";
|
|
1760
|
+
}
|
|
1761
|
+
static clone(node) {
|
|
1762
|
+
return new MentionNode(
|
|
1763
|
+
node.__platform,
|
|
1764
|
+
node.__handle,
|
|
1765
|
+
node.__displayName,
|
|
1766
|
+
node.__key
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1769
|
+
createDOM(_config) {
|
|
1770
|
+
const el = document.createElement("span");
|
|
1771
|
+
el.style.display = "inline-flex";
|
|
1772
|
+
el.style.alignItems = "center";
|
|
1773
|
+
el.style.height = "1lh";
|
|
1774
|
+
return el;
|
|
1775
|
+
}
|
|
1776
|
+
updateDOM() {
|
|
1777
|
+
return false;
|
|
1778
|
+
}
|
|
1779
|
+
isInline() {
|
|
1780
|
+
return true;
|
|
1781
|
+
}
|
|
1782
|
+
getPlatform() {
|
|
1783
|
+
return this.getLatest().__platform;
|
|
1784
|
+
}
|
|
1785
|
+
getHandle() {
|
|
1786
|
+
return this.getLatest().__handle;
|
|
1787
|
+
}
|
|
1788
|
+
getDisplayName() {
|
|
1789
|
+
return this.getLatest().__displayName;
|
|
1790
|
+
}
|
|
1791
|
+
static importJSON(serializedNode) {
|
|
1792
|
+
return $createMentionNode(
|
|
1793
|
+
serializedNode.platform,
|
|
1794
|
+
serializedNode.handle,
|
|
1795
|
+
serializedNode.displayName
|
|
1796
|
+
);
|
|
1797
|
+
}
|
|
1798
|
+
exportJSON() {
|
|
1799
|
+
return {
|
|
1800
|
+
...super.exportJSON(),
|
|
1801
|
+
type: "mention",
|
|
1802
|
+
platform: this.__platform,
|
|
1803
|
+
handle: this.__handle,
|
|
1804
|
+
...this.__displayName ? { displayName: this.__displayName } : {},
|
|
1805
|
+
version: 1
|
|
1806
|
+
};
|
|
1807
|
+
}
|
|
1808
|
+
decorate(_editor, _config) {
|
|
1809
|
+
return createRendererDecoration("Mention", MentionRenderer, {
|
|
1810
|
+
platform: this.__platform,
|
|
1811
|
+
handle: this.__handle,
|
|
1812
|
+
displayName: this.__displayName
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
function $createMentionNode(platform, handle, displayName) {
|
|
1817
|
+
return new MentionNode(platform, handle, displayName);
|
|
1818
|
+
}
|
|
1995
1819
|
function MermaidRenderer({ content }) {
|
|
1996
1820
|
return /* @__PURE__ */ jsx("div", { className: "rich-mermaid-block", children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: content }) }) });
|
|
1997
1821
|
}
|
|
@@ -2074,6 +1898,65 @@ function $createMermaidNode(diagram) {
|
|
|
2074
1898
|
function $isMermaidNode(node) {
|
|
2075
1899
|
return node instanceof MermaidNode;
|
|
2076
1900
|
}
|
|
1901
|
+
class SpoilerNode extends ElementNode {
|
|
1902
|
+
static getType() {
|
|
1903
|
+
return "spoiler";
|
|
1904
|
+
}
|
|
1905
|
+
static clone(node) {
|
|
1906
|
+
return new SpoilerNode(node.__key);
|
|
1907
|
+
}
|
|
1908
|
+
constructor(key) {
|
|
1909
|
+
super(key);
|
|
1910
|
+
}
|
|
1911
|
+
createDOM(_config) {
|
|
1912
|
+
const span = document.createElement("span");
|
|
1913
|
+
span.className = "rich-spoiler";
|
|
1914
|
+
span.setAttribute("role", "button");
|
|
1915
|
+
span.setAttribute("tabindex", "0");
|
|
1916
|
+
span.setAttribute("aria-label", "Spoiler (click to reveal)");
|
|
1917
|
+
const toggle = () => {
|
|
1918
|
+
if (span.isContentEditable) return;
|
|
1919
|
+
const revealed = span.classList.toggle("rich-spoiler-revealed");
|
|
1920
|
+
span.setAttribute(
|
|
1921
|
+
"aria-label",
|
|
1922
|
+
revealed ? "Spoiler (revealed)" : "Spoiler (click to reveal)"
|
|
1923
|
+
);
|
|
1924
|
+
};
|
|
1925
|
+
span.addEventListener("click", toggle);
|
|
1926
|
+
span.addEventListener("keydown", (e) => {
|
|
1927
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1928
|
+
e.preventDefault();
|
|
1929
|
+
toggle();
|
|
1930
|
+
}
|
|
1931
|
+
});
|
|
1932
|
+
return span;
|
|
1933
|
+
}
|
|
1934
|
+
updateDOM() {
|
|
1935
|
+
return false;
|
|
1936
|
+
}
|
|
1937
|
+
static importJSON(_serializedNode) {
|
|
1938
|
+
return $createSpoilerNode();
|
|
1939
|
+
}
|
|
1940
|
+
exportJSON() {
|
|
1941
|
+
return {
|
|
1942
|
+
...super.exportJSON(),
|
|
1943
|
+
type: "spoiler",
|
|
1944
|
+
version: 1
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
canInsertTextBefore() {
|
|
1948
|
+
return true;
|
|
1949
|
+
}
|
|
1950
|
+
canInsertTextAfter() {
|
|
1951
|
+
return true;
|
|
1952
|
+
}
|
|
1953
|
+
isInline() {
|
|
1954
|
+
return true;
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
function $createSpoilerNode() {
|
|
1958
|
+
return new SpoilerNode();
|
|
1959
|
+
}
|
|
2077
1960
|
function VideoRenderer({
|
|
2078
1961
|
src,
|
|
2079
1962
|
poster,
|
|
@@ -2217,135 +2100,113 @@ const allNodes = [
|
|
|
2217
2100
|
...builtinNodes,
|
|
2218
2101
|
...customNodes
|
|
2219
2102
|
];
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
return /* @__PURE__ */ jsx(
|
|
2249
|
-
FootnoteDefinitionsProvider,
|
|
2250
|
-
{
|
|
2251
|
-
definitions,
|
|
2252
|
-
displayNumberMap,
|
|
2253
|
-
children
|
|
2103
|
+
const editorTheme = {
|
|
2104
|
+
text: {
|
|
2105
|
+
bold: "rich-text-bold",
|
|
2106
|
+
italic: "rich-text-italic",
|
|
2107
|
+
underline: "rich-text-underline",
|
|
2108
|
+
strikethrough: "rich-text-strikethrough",
|
|
2109
|
+
superscript: "rich-text-superscript",
|
|
2110
|
+
subscript: "rich-text-subscript",
|
|
2111
|
+
code: "rich-text-code",
|
|
2112
|
+
highlight: "rich-text-highlight"
|
|
2113
|
+
},
|
|
2114
|
+
heading: {
|
|
2115
|
+
h1: "rich-heading-h1",
|
|
2116
|
+
h2: "rich-heading-h2",
|
|
2117
|
+
h3: "rich-heading-h3",
|
|
2118
|
+
h4: "rich-heading-h4",
|
|
2119
|
+
h5: "rich-heading-h5",
|
|
2120
|
+
h6: "rich-heading-h6"
|
|
2121
|
+
},
|
|
2122
|
+
list: {
|
|
2123
|
+
ol: "rich-list-ol",
|
|
2124
|
+
ul: "rich-list-ul",
|
|
2125
|
+
listitem: "rich-list-item",
|
|
2126
|
+
listitemChecked: "rich-list-item-checked",
|
|
2127
|
+
listitemUnchecked: "rich-list-item-unchecked",
|
|
2128
|
+
checklist: "rich-checklist",
|
|
2129
|
+
nested: {
|
|
2130
|
+
listitem: "rich-list-nested-item"
|
|
2254
2131
|
}
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
if (variant === "comment") {
|
|
2268
|
-
return colorScheme === "dark" ? darkCommentVariant : commentVariant;
|
|
2269
|
-
}
|
|
2270
|
-
if (variant === "note") {
|
|
2271
|
-
return colorScheme === "dark" ? darkNoteVariant : noteVariant;
|
|
2272
|
-
}
|
|
2273
|
-
return colorScheme === "dark" ? darkArticleVariant : articleVariant;
|
|
2274
|
-
}
|
|
2132
|
+
},
|
|
2133
|
+
quote: "rich-quote",
|
|
2134
|
+
link: "rich-link",
|
|
2135
|
+
paragraph: "rich-paragraph",
|
|
2136
|
+
code: "rich-code-block",
|
|
2137
|
+
table: "rich-table",
|
|
2138
|
+
tableCell: "rich-table-cell",
|
|
2139
|
+
tableCellHeader: "rich-table-cell-header",
|
|
2140
|
+
tableScrollableWrapper: "rich-table-scrollable-wrapper",
|
|
2141
|
+
/** Used by @lexical/extension HorizontalRuleNode */
|
|
2142
|
+
hr: "rich-hr"
|
|
2143
|
+
};
|
|
2275
2144
|
export {
|
|
2276
2145
|
$createFootnoteSectionNode as $,
|
|
2277
2146
|
ALERT_LABELS as A,
|
|
2278
2147
|
BANNER_LABELS as B,
|
|
2279
2148
|
ColorSchemeProvider as C,
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2149
|
+
FootnoteSectionNode as D,
|
|
2150
|
+
FootnoteStaticRenderer as E,
|
|
2151
|
+
FootnoteDefinitionsProvider as F,
|
|
2283
2152
|
GridContainerNode as G,
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2153
|
+
KaTeXInlineNode as H,
|
|
2154
|
+
KaTeXRenderer as I,
|
|
2155
|
+
LinkCardRenderer as J,
|
|
2287
2156
|
KaTeXBlockNode as K,
|
|
2288
2157
|
LinkCardNode as L,
|
|
2289
2158
|
MermaidNode as M,
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2159
|
+
NestedContentRendererProvider as N,
|
|
2160
|
+
computeImageMeta as O,
|
|
2161
|
+
decodeThumbHash as P,
|
|
2162
|
+
$isAlertQuoteNode as Q,
|
|
2294
2163
|
RendererConfigProvider as R,
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2164
|
+
AlertRenderer as S,
|
|
2165
|
+
SpoilerNode as T,
|
|
2166
|
+
MentionNode as U,
|
|
2167
|
+
FootnoteNode as V,
|
|
2168
|
+
AlertQuoteNode as W,
|
|
2169
|
+
$isBannerNode as X,
|
|
2170
|
+
BannerRenderer as Y,
|
|
2171
|
+
BannerNode as Z,
|
|
2172
|
+
normalizeBannerType as _,
|
|
2304
2173
|
allNodes as a,
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
$
|
|
2318
|
-
$createImageNode as ad,
|
|
2319
|
-
$createKaTeXInlineNode as ae,
|
|
2320
|
-
$createKaTeXBlockNode as af,
|
|
2321
|
-
$createBannerNode as ag,
|
|
2322
|
-
$createDetailsNode as ah,
|
|
2323
|
-
$createFootnoteNode as ai,
|
|
2324
|
-
$createMentionNode as aj,
|
|
2325
|
-
$createSpoilerNode as ak,
|
|
2174
|
+
$isCodeBlockNode as a0,
|
|
2175
|
+
CodeBlockRenderer as a1,
|
|
2176
|
+
CodeBlockNode as a2,
|
|
2177
|
+
ImageNode as a3,
|
|
2178
|
+
VideoNode as a4,
|
|
2179
|
+
DetailsNode as a5,
|
|
2180
|
+
$createImageNode as a6,
|
|
2181
|
+
$createKaTeXInlineNode as a7,
|
|
2182
|
+
$createKaTeXBlockNode as a8,
|
|
2183
|
+
$createDetailsNode as a9,
|
|
2184
|
+
$createFootnoteNode as aa,
|
|
2185
|
+
$createMentionNode as ab,
|
|
2186
|
+
$createSpoilerNode as ac,
|
|
2326
2187
|
builtinNodes as b,
|
|
2327
2188
|
customNodes as c,
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
$
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2189
|
+
RendererWrapper as d,
|
|
2190
|
+
createRendererDecoration as e,
|
|
2191
|
+
editorTheme as f,
|
|
2192
|
+
extractTextContent as g,
|
|
2193
|
+
useFootnoteContent as h,
|
|
2194
|
+
useFootnoteDefinitions as i,
|
|
2195
|
+
useFootnoteDisplayNumber as j,
|
|
2196
|
+
useNestedContentRenderer as k,
|
|
2197
|
+
useRendererConfig as l,
|
|
2198
|
+
useRendererMode as m,
|
|
2199
|
+
useVariant as n,
|
|
2200
|
+
$createGridContainerNode as o,
|
|
2201
|
+
$createLinkCardNode as p,
|
|
2202
|
+
$createMermaidNode as q,
|
|
2203
|
+
$isFootnoteSectionNode as r,
|
|
2204
|
+
$isGridContainerNode as s,
|
|
2205
|
+
$isKaTeXBlockNode as t,
|
|
2206
|
+
useColorScheme as u,
|
|
2207
|
+
$isKaTeXInlineNode as v,
|
|
2208
|
+
$isLinkCardNode as w,
|
|
2209
|
+
$isMermaidNode as x,
|
|
2210
|
+
ALERT_TYPES as y,
|
|
2211
|
+
BANNER_TYPES as z
|
|
2351
2212
|
};
|