@haklex/rich-editor 0.1.1 → 0.3.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.
Files changed (65) hide show
  1. package/dist/AlertQuoteEditNode-C55sxsR3.js +267 -0
  2. package/dist/KaTeXRenderer-CQQT3BMw.js +215 -0
  3. package/dist/LinkCardRenderer-CigqFwCv.js +45 -0
  4. package/dist/MermaidPlugin-BrOr-wQi.js +67 -0
  5. package/dist/RubyRenderer-jOkydJHg.js +15 -0
  6. package/dist/SubmitShortcutPlugin-DhyVFzoj.js +2186 -0
  7. package/dist/commands-entry.mjs +54 -74
  8. package/dist/components/decorators/PollEditDecorator.d.ts +13 -0
  9. package/dist/components/decorators/PollEditDecorator.d.ts.map +1 -0
  10. package/dist/components/renderers/PollRenderer.d.ts +3 -0
  11. package/dist/components/renderers/PollRenderer.d.ts.map +1 -0
  12. package/dist/config-B5BuLljq.js +1633 -0
  13. package/dist/config-edit.d.ts.map +1 -1
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/context/PollDataContext.d.ts +11 -0
  16. package/dist/context/PollDataContext.d.ts.map +1 -0
  17. package/dist/extractPolls-DO31LNrp.js +116 -0
  18. package/dist/grid.css-CJCkLTZc.js +44 -0
  19. package/dist/index.d.ts +5 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.mjs +121 -180
  22. package/dist/katex.css-CIOEOXyd.js +145 -0
  23. package/dist/node-registry-Dz5OTkh4.js +946 -0
  24. package/dist/nodes/PollEditNode.d.ts +14 -0
  25. package/dist/nodes/PollEditNode.d.ts.map +1 -0
  26. package/dist/nodes/PollNode.d.ts +52 -0
  27. package/dist/nodes/PollNode.d.ts.map +1 -0
  28. package/dist/nodes-entry.d.ts +3 -0
  29. package/dist/nodes-entry.d.ts.map +1 -1
  30. package/dist/nodes-entry.mjs +5 -50
  31. package/dist/normalizeSerializedEditorState-B-1wmGzd.js +78 -0
  32. package/dist/plugins-entry.mjs +3 -28
  33. package/dist/renderers-entry.mjs +41 -61
  34. package/dist/rich-editor.css +2 -1
  35. package/dist/static-entry.d.ts +5 -0
  36. package/dist/static-entry.d.ts.map +1 -1
  37. package/dist/static-entry.mjs +16 -66
  38. package/dist/styles/index.d.ts +2 -0
  39. package/dist/styles/index.d.ts.map +1 -1
  40. package/dist/styles/poll-edit.css.d.ts +35 -0
  41. package/dist/styles/poll-edit.css.d.ts.map +1 -0
  42. package/dist/styles/poll.css.d.ts +43 -0
  43. package/dist/styles/poll.css.d.ts.map +1 -0
  44. package/dist/styles-entry.mjs +3 -21
  45. package/dist/theme-B5B2EOWM.js +1099 -0
  46. package/dist/types/poll.d.ts +36 -0
  47. package/dist/types/poll.d.ts.map +1 -0
  48. package/dist/types/renderer-config.d.ts +3 -0
  49. package/dist/types/renderer-config.d.ts.map +1 -1
  50. package/dist/utils/extractPolls.d.ts +4 -0
  51. package/dist/utils/extractPolls.d.ts.map +1 -0
  52. package/package.json +30 -30
  53. package/dist/AlertQuoteEditNode-sPNf3_7P.js +0 -293
  54. package/dist/KaTeXRenderer-CQyQzNTJ.js +0 -218
  55. package/dist/LinkCardRenderer-QmkOlyXb.js +0 -36
  56. package/dist/MermaidPlugin-DKuGUcCG.js +0 -101
  57. package/dist/PresentDialogContext-DRroMIoK.js +0 -71
  58. package/dist/RubyRenderer-CJQmODir.js +0 -14
  59. package/dist/SubmitShortcutPlugin-D9uKYHda.js +0 -2427
  60. package/dist/config-Dl3ZkytB.js +0 -1362
  61. package/dist/grid.css-Md5-Cfx_.js +0 -11
  62. package/dist/katex.css-Csc-7N7u.js +0 -28
  63. package/dist/node-registry-CovhHUB6.js +0 -824
  64. package/dist/normalizeSerializedEditorState-k5G4xSi9.js +0 -85
  65. package/dist/theme-lEwScxEX.js +0 -1113
@@ -1,1362 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { CodeNode } from "@lexical/code-core";
5
- import { HorizontalRuleNode } from "@lexical/extension";
6
- import { LinkNode, AutoLinkNode } from "@lexical/link";
7
- import { ListNode, ListItemNode } from "@lexical/list";
8
- import { HeadingNode, QuoteNode } from "@lexical/rich-text";
9
- import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
10
- import { u as useNestedContentRenderer, o as extractTextContent, S as SpoilerNode, M as MentionNode, k as KaTeXInlineNode, K as KaTeXBlockNode, I as ImageNode, v as AlertQuoteNode, F as FootnoteNode, l as MermaidNode, T as TagNode } from "./theme-lEwScxEX.js";
11
- import { DecoratorNode, $insertNodes, TextNode, ElementNode, $createTextNode } from "lexical";
12
- import { createElement, createContext, use, useState, useRef, useEffect, useCallback } from "react";
13
- import { jsx, jsxs } from "react/jsx-runtime";
14
- import { a as RendererWrapper, g as useVariant, c as createRendererDecoration, b as useFootnoteDefinitions } from "./KaTeXRenderer-CQyQzNTJ.js";
15
- import { Code, MessageSquareQuote, ChevronRight, Link, Video } from "lucide-react";
16
- import { s as semanticClassNames, d as sharedStyles, e as clsx } from "./katex.css-Csc-7N7u.js";
17
- import { d as detailsClassNames, a as detailsStyles, b as gridStyles, g as gridClassNames } from "./grid.css-Md5-Cfx_.js";
18
- import { L as LinkCardRenderer } from "./LinkCardRenderer-QmkOlyXb.js";
19
- const BannerRenderer = ({ type }) => {
20
- return /* @__PURE__ */ jsx("span", { className: `rich-banner-icon rich-banner-icon-${type}` });
21
- };
22
- function BannerStaticDecorator({ bannerType, contentState }) {
23
- const renderContent = useNestedContentRenderer();
24
- return /* @__PURE__ */ jsxs("div", { className: "rich-banner-inner", children: [
25
- /* @__PURE__ */ jsx(
26
- RendererWrapper,
27
- {
28
- defaultRenderer: BannerRenderer,
29
- props: { type: bannerType },
30
- rendererKey: "Banner"
31
- }
32
- ),
33
- /* @__PURE__ */ jsx("div", { className: "rich-banner-content", children: renderContent(contentState) })
34
- ] });
35
- }
36
- const LEGACY_TYPE_MAP = {
37
- info: "note",
38
- success: "tip",
39
- error: "caution"
40
- };
41
- function normalizeBannerType(type) {
42
- if (type in LEGACY_TYPE_MAP) return LEGACY_TYPE_MAP[type];
43
- return type || "note";
44
- }
45
- const BANNER_TYPES = [
46
- "note",
47
- "tip",
48
- "important",
49
- "warning",
50
- "caution"
51
- ];
52
- const BANNER_LABELS = {
53
- note: "Note",
54
- tip: "Tip",
55
- important: "Important",
56
- warning: "Warning",
57
- caution: "Caution"
58
- };
59
- class BannerNode extends DecoratorNode {
60
- constructor(bannerType, contentState, key) {
61
- super(key);
62
- __publicField(this, "__bannerType");
63
- __publicField(this, "__contentState");
64
- this.__bannerType = bannerType;
65
- this.__contentState = contentState || {
66
- root: {
67
- children: [
68
- {
69
- type: "paragraph",
70
- children: [],
71
- direction: null,
72
- format: "",
73
- indent: 0,
74
- textFormat: 0,
75
- textStyle: "",
76
- version: 1
77
- }
78
- ],
79
- direction: null,
80
- format: "",
81
- indent: 0,
82
- type: "root",
83
- version: 1
84
- }
85
- };
86
- }
87
- static getType() {
88
- return "banner";
89
- }
90
- static clone(node) {
91
- return new BannerNode(node.__bannerType, node.__contentState, node.__key);
92
- }
93
- createDOM(_config) {
94
- const div = document.createElement("div");
95
- div.className = `rich-banner rich-banner-${this.__bannerType}`;
96
- return div;
97
- }
98
- updateDOM(prevNode, dom) {
99
- if (prevNode.__bannerType !== this.__bannerType) {
100
- dom.className = `rich-banner rich-banner-${this.__bannerType}`;
101
- }
102
- return false;
103
- }
104
- isInline() {
105
- return false;
106
- }
107
- getBannerType() {
108
- return this.__bannerType;
109
- }
110
- setBannerType(bannerType) {
111
- const writable = this.getWritable();
112
- writable.__bannerType = bannerType;
113
- }
114
- getContentState() {
115
- return this.getLatest().__contentState;
116
- }
117
- setContentState(state) {
118
- const writable = this.getWritable();
119
- writable.__contentState = state;
120
- }
121
- getTextContent() {
122
- return extractTextContent(this.__contentState);
123
- }
124
- static importJSON(serializedNode) {
125
- const legacy = serializedNode;
126
- const bannerType = normalizeBannerType(serializedNode.bannerType);
127
- if (serializedNode.content) {
128
- return new BannerNode(bannerType, serializedNode.content);
129
- }
130
- if (legacy.children) {
131
- const content = {
132
- root: {
133
- children: legacy.children,
134
- direction: null,
135
- format: "",
136
- indent: 0,
137
- type: "root",
138
- version: 1
139
- }
140
- };
141
- return new BannerNode(bannerType, content);
142
- }
143
- return new BannerNode(bannerType);
144
- }
145
- exportJSON() {
146
- return {
147
- ...super.exportJSON(),
148
- type: "banner",
149
- bannerType: this.__bannerType,
150
- content: this.__contentState,
151
- version: 1
152
- };
153
- }
154
- decorate(_editor, _config) {
155
- return createElement(BannerStaticDecorator, {
156
- bannerType: this.__bannerType,
157
- contentState: this.__contentState
158
- });
159
- }
160
- }
161
- function $isBannerNode(node) {
162
- return node instanceof BannerNode;
163
- }
164
- const ColorSchemeContext = createContext("light");
165
- function ColorSchemeProvider({
166
- colorScheme,
167
- children
168
- }) {
169
- return /* @__PURE__ */ jsx(ColorSchemeContext.Provider, { value: colorScheme, children });
170
- }
171
- function useColorScheme() {
172
- return use(ColorSchemeContext);
173
- }
174
- let codeToHtmlFn = null;
175
- let shikiLoadPromise = null;
176
- function loadCodeToHtml() {
177
- if (codeToHtmlFn) return Promise.resolve(codeToHtmlFn);
178
- if (!shikiLoadPromise) {
179
- shikiLoadPromise = import("shiki/bundle/web").then((mod) => {
180
- codeToHtmlFn = mod.codeToHtml;
181
- return mod.codeToHtml;
182
- }).catch((err) => {
183
- shikiLoadPromise = null;
184
- throw err;
185
- });
186
- }
187
- return shikiLoadPromise;
188
- }
189
- function CodeBlockRenderer({
190
- code,
191
- language,
192
- showLineNumbers: showLineNumbersProp
193
- }) {
194
- const variant = useVariant();
195
- const showLineNumbers = showLineNumbersProp ?? variant !== "comment";
196
- const colorScheme = useColorScheme();
197
- const shikiTheme = colorScheme === "dark" ? "github-dark" : "github-light";
198
- const [highlightedHtml, setHighlightedHtml] = useState(null);
199
- const [copied, setCopied] = useState(false);
200
- const copyTimerRef = useRef(void 0);
201
- useEffect(() => {
202
- let cancelled = false;
203
- setHighlightedHtml(null);
204
- loadCodeToHtml().then(
205
- (toHtml) => toHtml(code, {
206
- lang: language,
207
- theme: shikiTheme
208
- })
209
- ).then((html) => {
210
- if (!cancelled) {
211
- setHighlightedHtml(html);
212
- }
213
- }).catch(() => {
214
- if (!cancelled) {
215
- setHighlightedHtml(null);
216
- }
217
- });
218
- return () => {
219
- cancelled = true;
220
- };
221
- }, [code, language, shikiTheme]);
222
- useEffect(() => {
223
- return () => clearTimeout(copyTimerRef.current);
224
- }, []);
225
- const handleCopy = useCallback(() => {
226
- navigator.clipboard.writeText(code).then(() => {
227
- setCopied(true);
228
- clearTimeout(copyTimerRef.current);
229
- copyTimerRef.current = setTimeout(() => setCopied(false), 2e3);
230
- }).catch(() => {
231
- });
232
- }, [code]);
233
- const header = language ? /* @__PURE__ */ jsxs("div", { className: "rich-code-block-header", children: [
234
- /* @__PURE__ */ jsx("span", { className: "rich-code-block-lang", children: language }),
235
- /* @__PURE__ */ jsx(
236
- "button",
237
- {
238
- "aria-label": copied ? "Copied to clipboard" : "Copy code",
239
- className: "rich-code-block-copy",
240
- type: "button",
241
- onClick: handleCopy,
242
- children: copied ? "Copied" : "Copy"
243
- }
244
- )
245
- ] }) : null;
246
- const wrapperClass = showLineNumbers ? "rich-code-block rich-code-block-numbered" : "rich-code-block";
247
- if (highlightedHtml) {
248
- return /* @__PURE__ */ jsxs("div", { className: wrapperClass, children: [
249
- header,
250
- /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: highlightedHtml } })
251
- ] });
252
- }
253
- const lines = code.split("\n");
254
- return /* @__PURE__ */ jsxs("div", { className: wrapperClass, children: [
255
- header,
256
- /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: lines.map((line, i) => /* @__PURE__ */ jsxs("span", { className: "line", children: [
257
- line,
258
- i < lines.length - 1 ? "\n" : ""
259
- ] }, i)) }) })
260
- ] });
261
- }
262
- const _CodeBlockNode = class _CodeBlockNode extends DecoratorNode {
263
- constructor(code, language, key) {
264
- super(key);
265
- __publicField(this, "__code");
266
- __publicField(this, "__language");
267
- this.__code = code;
268
- this.__language = language;
269
- }
270
- static getType() {
271
- return "code-block";
272
- }
273
- static clone(node) {
274
- return new _CodeBlockNode(node.__code, node.__language, node.__key);
275
- }
276
- createDOM(_config) {
277
- const div = document.createElement("div");
278
- div.className = "rich-code-block-wrapper";
279
- return div;
280
- }
281
- updateDOM() {
282
- return false;
283
- }
284
- isInline() {
285
- return false;
286
- }
287
- isKeyboardSelectable() {
288
- return true;
289
- }
290
- static importJSON(serializedNode) {
291
- return $createCodeBlockNode(serializedNode.code, serializedNode.language);
292
- }
293
- exportJSON() {
294
- return {
295
- ...super.exportJSON(),
296
- type: "code-block",
297
- code: this.__code,
298
- language: this.__language,
299
- version: 1
300
- };
301
- }
302
- getCode() {
303
- return this.__code;
304
- }
305
- setCode(code) {
306
- const writable = this.getWritable();
307
- writable.__code = code;
308
- }
309
- getLanguage() {
310
- return this.__language;
311
- }
312
- setLanguage(language) {
313
- const writable = this.getWritable();
314
- writable.__language = language;
315
- }
316
- decorate(_editor, _config) {
317
- return createRendererDecoration("CodeBlock", CodeBlockRenderer, {
318
- code: this.__code,
319
- language: this.__language
320
- });
321
- }
322
- };
323
- __publicField(_CodeBlockNode, "commandItems", [
324
- {
325
- title: "Code Block",
326
- icon: createElement(Code, { size: 20 }),
327
- description: "Syntax-highlighted code",
328
- keywords: ["code", "snippet", "codeblock"],
329
- section: "MEDIA",
330
- placement: ["slash", "toolbar"],
331
- group: "insert",
332
- onSelect: (editor) => {
333
- editor.update(() => {
334
- $insertNodes([$createCodeBlockNode("", "text")]);
335
- });
336
- }
337
- }
338
- ]);
339
- let CodeBlockNode = _CodeBlockNode;
340
- function $createCodeBlockNode(code, language) {
341
- return new CodeBlockNode(code, language);
342
- }
343
- function $isCodeBlockNode(node) {
344
- return node instanceof CodeBlockNode;
345
- }
346
- const DEFAULT_COMMENT_TEXT = "comment";
347
- const _CommentNode = class _CommentNode extends TextNode {
348
- static getType() {
349
- return "comment";
350
- }
351
- static clone(node) {
352
- return new _CommentNode(node.__text, node.__key);
353
- }
354
- static importDOM() {
355
- return {
356
- "#comment": () => ({
357
- conversion: (domNode) => {
358
- if (!(domNode instanceof Comment)) return null;
359
- return {
360
- node: $createCommentNode(domNode.data)
361
- };
362
- },
363
- priority: 4
364
- }),
365
- "span": () => ({
366
- conversion: (domNode) => {
367
- if (!(domNode instanceof HTMLElement)) return null;
368
- if (!domNode.classList.contains(semanticClassNames.comment)) return null;
369
- return {
370
- node: $createCommentNode(domNode.dataset.comment ?? domNode.textContent ?? "")
371
- };
372
- },
373
- priority: 2
374
- })
375
- };
376
- }
377
- constructor(text, key) {
378
- super(text, key);
379
- }
380
- createDOM(config) {
381
- const element = super.createDOM(config);
382
- element.classList.add(semanticClassNames.comment, sharedStyles.comment);
383
- element.dataset.comment = this.__text;
384
- return element;
385
- }
386
- updateDOM(prevNode, dom, config) {
387
- const updated = super.updateDOM(prevNode, dom, config);
388
- dom.classList.add(semanticClassNames.comment, sharedStyles.comment);
389
- if (prevNode.__text !== this.__text) {
390
- dom.dataset.comment = this.__text;
391
- }
392
- return updated;
393
- }
394
- exportDOM(_editor) {
395
- return {
396
- element: document.createComment(this.getTextContent())
397
- };
398
- }
399
- static importJSON(serializedNode) {
400
- const node = $createCommentNode(serializedNode.text ?? "");
401
- node.setFormat(serializedNode.format ?? 0);
402
- node.setDetail(serializedNode.detail ?? 0);
403
- node.setMode(serializedNode.mode ?? "normal");
404
- node.setStyle(serializedNode.style ?? "");
405
- return node;
406
- }
407
- exportJSON() {
408
- return {
409
- ...super.exportJSON(),
410
- type: "comment",
411
- version: 1
412
- };
413
- }
414
- };
415
- __publicField(_CommentNode, "commandItems", [
416
- {
417
- title: "HTML Comment",
418
- icon: createElement(MessageSquareQuote, { size: 20 }),
419
- description: "Insert an HTML comment node",
420
- keywords: ["comment", "html", "annotation", "hidden", "<!-- -->"],
421
- section: "INLINE",
422
- placement: ["slash", "toolbar"],
423
- group: "insert",
424
- onSelect: (editor, _queryString) => {
425
- editor.update(() => {
426
- const node = $createCommentNode(DEFAULT_COMMENT_TEXT);
427
- $insertNodes([node]);
428
- node.select(0, node.getTextContentSize());
429
- });
430
- }
431
- }
432
- ]);
433
- let CommentNode = _CommentNode;
434
- function $createCommentNode(text) {
435
- return new CommentNode(text);
436
- }
437
- function $createCommentPlaceholderNode() {
438
- return $createCommentNode(DEFAULT_COMMENT_TEXT);
439
- }
440
- function $isCommentNode(node) {
441
- return node instanceof CommentNode;
442
- }
443
- const SVG_NS = "http://www.w3.org/2000/svg";
444
- const DEFAULT_ATTRS = {
445
- xmlns: SVG_NS,
446
- width: "24",
447
- height: "24",
448
- viewBox: "0 0 24 24",
449
- fill: "none",
450
- stroke: "currentColor",
451
- "stroke-width": "2",
452
- "stroke-linecap": "round",
453
- "stroke-linejoin": "round"
454
- };
455
- function createLucideSvg(iconNode, attrs = {}) {
456
- const svg = document.createElementNS(SVG_NS, "svg");
457
- const merged = { ...DEFAULT_ATTRS, ...attrs };
458
- for (const [k, v] of Object.entries(merged)) {
459
- svg.setAttribute(k, v);
460
- }
461
- for (const [tag, elAttrs] of iconNode) {
462
- const el = document.createElementNS(SVG_NS, tag);
463
- for (const [k, v] of Object.entries(elAttrs)) {
464
- if (k === "key") continue;
465
- el.setAttribute(k, v);
466
- }
467
- svg.append(el);
468
- }
469
- return svg;
470
- }
471
- const ChevronRightIconNode = [["path", { d: "M8 6L12 10L8 14" }]];
472
- const _DetailsNode = class _DetailsNode extends ElementNode {
473
- constructor(summary, open = false, key) {
474
- super(key);
475
- __publicField(this, "__summary");
476
- __publicField(this, "__open");
477
- this.__summary = summary;
478
- this.__open = open;
479
- }
480
- static getType() {
481
- return "details";
482
- }
483
- static clone(node) {
484
- return new _DetailsNode(node.__summary, node.__open, node.__key);
485
- }
486
- createDOM(_config) {
487
- const details = document.createElement("details");
488
- details.className = `${detailsClassNames.details} ${detailsStyles.details}`;
489
- if (this.__open) {
490
- details.open = true;
491
- }
492
- const summary = document.createElement("summary");
493
- summary.className = `${detailsClassNames.summary} ${detailsStyles.summary}`;
494
- const chevron = document.createElement("span");
495
- chevron.className = `${detailsClassNames.chevron} ${detailsStyles.chevron}`;
496
- chevron.setAttribute("aria-hidden", "true");
497
- chevron.append(
498
- createLucideSvg(ChevronRightIconNode, {
499
- "width": "20",
500
- "height": "20",
501
- "viewBox": "0 0 20 20",
502
- "stroke-width": "1.5"
503
- })
504
- );
505
- summary.append(chevron);
506
- const label = document.createElement("span");
507
- label.className = `${detailsClassNames.summaryText} ${detailsStyles.summaryText}`;
508
- label.textContent = this.__summary;
509
- summary.append(label);
510
- const content = document.createElement("div");
511
- content.className = `${detailsClassNames.content} ${detailsStyles.content}`;
512
- details.append(summary, content);
513
- return details;
514
- }
515
- updateDOM(prevNode, dom) {
516
- const details = dom;
517
- if (prevNode.__open !== this.__open) {
518
- details.open = this.__open;
519
- }
520
- if (prevNode.__summary !== this.__summary) {
521
- const label = dom.querySelector(`.${detailsClassNames.summaryText}`);
522
- if (label) {
523
- label.textContent = this.__summary;
524
- }
525
- }
526
- return false;
527
- }
528
- static importJSON(serializedNode) {
529
- return $createDetailsNode(serializedNode.summary, serializedNode.open);
530
- }
531
- exportJSON() {
532
- return {
533
- ...super.exportJSON(),
534
- type: "details",
535
- summary: this.__summary,
536
- open: this.__open,
537
- version: 1
538
- };
539
- }
540
- getSummary() {
541
- return this.getLatest().__summary;
542
- }
543
- setSummary(summary) {
544
- const writable = this.getWritable();
545
- writable.__summary = summary;
546
- }
547
- getOpen() {
548
- return this.getLatest().__open;
549
- }
550
- setOpen(open) {
551
- const writable = this.getWritable();
552
- writable.__open = open;
553
- }
554
- toggleOpen() {
555
- this.setOpen(!this.getOpen());
556
- }
557
- getDOMSlot(element) {
558
- const content = element.querySelector(`.${detailsClassNames.content}`);
559
- return super.getDOMSlot(element).withElement(content);
560
- }
561
- isInline() {
562
- return false;
563
- }
564
- };
565
- __publicField(_DetailsNode, "slashMenuItems", [
566
- {
567
- title: "Details",
568
- icon: createElement(ChevronRight, { size: 20 }),
569
- description: "Collapsible content block",
570
- keywords: ["details", "toggle", "collapse", "accordion"],
571
- section: "ADVANCED",
572
- onSelect: (editor) => {
573
- editor.update(() => {
574
- $insertNodes([$createDetailsNode("Details")]);
575
- });
576
- }
577
- }
578
- ]);
579
- let DetailsNode = _DetailsNode;
580
- function $createDetailsNode(summary, open = false) {
581
- return new DetailsNode(summary, open);
582
- }
583
- function FootnoteSectionRenderer({ definitions }) {
584
- const { displayNumberMap } = useFootnoteDefinitions();
585
- const sortedEntries = Object.entries(definitions).sort(
586
- ([a], [b]) => (displayNumberMap[a] ?? 0) - (displayNumberMap[b] ?? 0)
587
- );
588
- if (sortedEntries.length === 0) return null;
589
- return /* @__PURE__ */ jsxs(
590
- "div",
591
- {
592
- role: "doc-endnotes",
593
- className: clsx(
594
- "rich-footnote-section-content",
595
- semanticClassNames.footnoteSection,
596
- sharedStyles.footnoteSection
597
- ),
598
- children: [
599
- /* @__PURE__ */ jsx(
600
- "hr",
601
- {
602
- className: clsx(
603
- semanticClassNames.footnoteSectionDivider,
604
- sharedStyles.footnoteSectionDivider
605
- )
606
- }
607
- ),
608
- /* @__PURE__ */ jsx(
609
- "ol",
610
- {
611
- className: clsx(semanticClassNames.footnoteSectionList, sharedStyles.footnoteSectionList),
612
- children: sortedEntries.map(([identifier, content]) => {
613
- const displayNum = displayNumberMap[identifier] ?? identifier;
614
- return /* @__PURE__ */ jsx(
615
- FootnoteSectionItem,
616
- {
617
- content,
618
- displayNum,
619
- identifier
620
- },
621
- identifier
622
- );
623
- })
624
- }
625
- )
626
- ]
627
- }
628
- );
629
- }
630
- function FootnoteSectionItem({
631
- identifier,
632
- content,
633
- displayNum
634
- }) {
635
- const targetId = `footnote-${identifier}`;
636
- const refId = `footnote-ref-${identifier}`;
637
- const handleBackClick = useCallback(
638
- (e) => {
639
- e.preventDefault();
640
- const refElement = document.getElementById(refId);
641
- if (!refElement) return;
642
- refElement.scrollIntoView({ behavior: "smooth", block: "center" });
643
- refElement.classList.add(
644
- semanticClassNames.footnoteHighlight,
645
- sharedStyles.footnoteHighlight
646
- );
647
- window.setTimeout(() => {
648
- refElement.classList.remove(
649
- semanticClassNames.footnoteHighlight,
650
- sharedStyles.footnoteHighlight
651
- );
652
- }, 1200);
653
- },
654
- [refId]
655
- );
656
- return /* @__PURE__ */ jsxs(
657
- "li",
658
- {
659
- className: clsx(semanticClassNames.footnoteSectionItem, sharedStyles.footnoteSectionItem),
660
- id: targetId,
661
- value: typeof displayNum === "number" ? displayNum : void 0,
662
- children: [
663
- /* @__PURE__ */ jsx("span", { className: "rich-footnote-section-item-content", children: content }),
664
- /* @__PURE__ */ jsx(
665
- "a",
666
- {
667
- "aria-label": `Back to reference ${displayNum}`,
668
- className: clsx(semanticClassNames.footnoteBackRef, sharedStyles.footnoteBackRef),
669
- href: `#${refId}`,
670
- role: "doc-backlink",
671
- onClick: handleBackClick,
672
- children: "↩"
673
- }
674
- )
675
- ]
676
- }
677
- );
678
- }
679
- class FootnoteSectionNode extends DecoratorNode {
680
- constructor(definitions, key) {
681
- super(key);
682
- __publicField(this, "__definitions");
683
- this.__definitions = definitions;
684
- }
685
- static getType() {
686
- return "footnote-section";
687
- }
688
- static clone(node) {
689
- return new FootnoteSectionNode({ ...node.__definitions }, node.__key);
690
- }
691
- createDOM(_config) {
692
- const div = document.createElement("div");
693
- div.className = `${semanticClassNames.footnoteSection} ${sharedStyles.footnoteSection}`;
694
- return div;
695
- }
696
- updateDOM() {
697
- return false;
698
- }
699
- isInline() {
700
- return false;
701
- }
702
- static importJSON(serializedNode) {
703
- return $createFootnoteSectionNode(serializedNode.definitions);
704
- }
705
- exportJSON() {
706
- return {
707
- ...super.exportJSON(),
708
- type: "footnote-section",
709
- definitions: this.__definitions,
710
- version: 1
711
- };
712
- }
713
- getDefinitions() {
714
- return this.getLatest().__definitions;
715
- }
716
- setDefinitions(definitions) {
717
- const writable = this.getWritable();
718
- writable.__definitions = definitions;
719
- }
720
- getDefinition(identifier) {
721
- return this.getLatest().__definitions[identifier];
722
- }
723
- setDefinition(identifier, content) {
724
- const writable = this.getWritable();
725
- writable.__definitions = {
726
- ...writable.__definitions,
727
- [identifier]: content
728
- };
729
- }
730
- removeDefinition(identifier) {
731
- const writable = this.getWritable();
732
- const { [identifier]: _, ...rest } = writable.__definitions;
733
- writable.__definitions = rest;
734
- }
735
- decorate(_editor, _config) {
736
- return createRendererDecoration("FootnoteSection", FootnoteSectionRenderer, {
737
- definitions: this.__definitions,
738
- nodeKey: this.__key
739
- });
740
- }
741
- }
742
- function $createFootnoteSectionNode(definitions = {}) {
743
- return new FootnoteSectionNode(definitions);
744
- }
745
- function $isFootnoteSectionNode(node) {
746
- return node instanceof FootnoteSectionNode;
747
- }
748
- function GridStaticDecorator({ cols, gap, cellStates }) {
749
- const renderContent = useNestedContentRenderer();
750
- return /* @__PURE__ */ jsx(
751
- "div",
752
- {
753
- className: clsx(gridClassNames.inner, gridStyles.inner),
754
- style: {
755
- display: "grid",
756
- gridTemplateColumns: `repeat(${cols}, 1fr)`,
757
- gap
758
- },
759
- children: cellStates.map((state, i) => /* @__PURE__ */ jsx("div", { className: clsx(gridClassNames.cell, gridStyles.cell), children: renderContent(state) }, i))
760
- }
761
- );
762
- }
763
- class GridContainerNode extends DecoratorNode {
764
- constructor(cols = 2, gap, cellStates, key) {
765
- super(key);
766
- __publicField(this, "__cols");
767
- __publicField(this, "__gap");
768
- __publicField(this, "__cellStates");
769
- this.__cols = cols;
770
- this.__gap = gap || "16px";
771
- if (cellStates) {
772
- this.__cellStates = cellStates;
773
- } else {
774
- const emptyState = {
775
- root: {
776
- children: [
777
- {
778
- type: "paragraph",
779
- children: [],
780
- direction: null,
781
- format: "",
782
- indent: 0,
783
- textFormat: 0,
784
- textStyle: "",
785
- version: 1
786
- }
787
- ],
788
- direction: null,
789
- format: "",
790
- indent: 0,
791
- type: "root",
792
- version: 1
793
- }
794
- };
795
- this.__cellStates = Array.from({ length: cols }, () => emptyState);
796
- }
797
- }
798
- static getType() {
799
- return "grid-container";
800
- }
801
- static clone(node) {
802
- return new GridContainerNode(node.__cols, node.__gap, [...node.__cellStates], node.__key);
803
- }
804
- createDOM(_config) {
805
- const div = document.createElement("div");
806
- div.className = `${gridClassNames.container} ${gridStyles.container}`;
807
- return div;
808
- }
809
- updateDOM() {
810
- return false;
811
- }
812
- isInline() {
813
- return false;
814
- }
815
- getCols() {
816
- return this.getLatest().__cols;
817
- }
818
- setCols(cols) {
819
- const writable = this.getWritable();
820
- const prev = writable.__cellStates.length;
821
- writable.__cols = cols;
822
- if (cols > prev) {
823
- const emptyState = {
824
- root: {
825
- children: [
826
- {
827
- type: "paragraph",
828
- children: [],
829
- direction: null,
830
- format: "",
831
- indent: 0,
832
- textFormat: 0,
833
- textStyle: "",
834
- version: 1
835
- }
836
- ],
837
- direction: null,
838
- format: "",
839
- indent: 0,
840
- type: "root",
841
- version: 1
842
- }
843
- };
844
- for (let i = prev; i < cols; i++) {
845
- writable.__cellStates.push(emptyState);
846
- }
847
- }
848
- }
849
- getGap() {
850
- return this.getLatest().__gap;
851
- }
852
- setGap(gap) {
853
- const writable = this.getWritable();
854
- writable.__gap = gap;
855
- }
856
- getCellStates() {
857
- return this.getLatest().__cellStates;
858
- }
859
- addCells(count) {
860
- const writable = this.getWritable();
861
- const emptyState = {
862
- root: {
863
- children: [
864
- {
865
- type: "paragraph",
866
- children: [],
867
- direction: null,
868
- format: "",
869
- indent: 0,
870
- textFormat: 0,
871
- textStyle: "",
872
- version: 1
873
- }
874
- ],
875
- direction: null,
876
- format: "",
877
- indent: 0,
878
- type: "root",
879
- version: 1
880
- }
881
- };
882
- for (let i = 0; i < count; i++) {
883
- writable.__cellStates.push(emptyState);
884
- }
885
- }
886
- removeCells(count) {
887
- const writable = this.getWritable();
888
- const states = writable.__cellStates;
889
- const toRemove = Math.min(count, states.length);
890
- for (let i = 0; i < toRemove; i++) {
891
- const state = states.at(-1);
892
- if (!state) break;
893
- const isEmpty = extractTextContent(state).trim() === "";
894
- if (!isEmpty) break;
895
- states.pop();
896
- }
897
- }
898
- getTextContent() {
899
- return this.__cellStates.map((s) => extractTextContent(s)).join("\n");
900
- }
901
- static importJSON(serializedNode) {
902
- const legacy = serializedNode;
903
- const cols = legacy.cols || 2;
904
- const rawGap = legacy.gap;
905
- const gap = typeof rawGap === "number" ? `${rawGap}px` : rawGap;
906
- if (legacy.cells && legacy.cells.length > 0) {
907
- return new GridContainerNode(cols, gap, legacy.cells);
908
- }
909
- if (legacy.children) {
910
- const cellStates = legacy.children.map((child) => {
911
- return {
912
- root: {
913
- children: [child],
914
- direction: null,
915
- format: "",
916
- indent: 0,
917
- type: "root",
918
- version: 1
919
- }
920
- };
921
- });
922
- return new GridContainerNode(cols, gap, cellStates);
923
- }
924
- return new GridContainerNode(cols, gap);
925
- }
926
- exportJSON() {
927
- return {
928
- ...super.exportJSON(),
929
- type: "grid-container",
930
- cols: this.__cols,
931
- gap: this.__gap,
932
- cells: this.__cellStates,
933
- version: 1
934
- };
935
- }
936
- decorate(_editor, _config) {
937
- return createElement(GridStaticDecorator, {
938
- cols: this.__cols,
939
- gap: this.__gap,
940
- cellStates: this.__cellStates
941
- });
942
- }
943
- }
944
- function $createGridContainerNode(cols = 2, gap) {
945
- return new GridContainerNode(cols, gap);
946
- }
947
- function $isGridContainerNode(node) {
948
- return node instanceof GridContainerNode;
949
- }
950
- const _LinkCardNode = class _LinkCardNode extends DecoratorNode {
951
- constructor(payload, key) {
952
- super(key);
953
- __publicField(this, "__url");
954
- __publicField(this, "__source");
955
- __publicField(this, "__id");
956
- __publicField(this, "__title");
957
- __publicField(this, "__description");
958
- __publicField(this, "__favicon");
959
- __publicField(this, "__image");
960
- this.__url = payload.url;
961
- this.__source = payload.source;
962
- this.__id = payload.id;
963
- this.__title = payload.title;
964
- this.__description = payload.description;
965
- this.__favicon = payload.favicon;
966
- this.__image = payload.image;
967
- }
968
- static getType() {
969
- return "link-card";
970
- }
971
- static clone(node) {
972
- return new _LinkCardNode(
973
- {
974
- url: node.__url,
975
- source: node.__source,
976
- id: node.__id,
977
- title: node.__title,
978
- description: node.__description,
979
- favicon: node.__favicon,
980
- image: node.__image
981
- },
982
- node.__key
983
- );
984
- }
985
- createDOM(_config) {
986
- const div = document.createElement("div");
987
- div.className = "rich-link-card-wrapper";
988
- return div;
989
- }
990
- updateDOM() {
991
- return false;
992
- }
993
- isInline() {
994
- return false;
995
- }
996
- static importJSON(serializedNode) {
997
- return $createLinkCardNode({
998
- url: serializedNode.url,
999
- source: serializedNode.source,
1000
- id: serializedNode.id,
1001
- title: serializedNode.title,
1002
- description: serializedNode.description,
1003
- favicon: serializedNode.favicon,
1004
- image: serializedNode.image
1005
- });
1006
- }
1007
- exportJSON() {
1008
- return {
1009
- ...super.exportJSON(),
1010
- type: "link-card",
1011
- url: this.__url,
1012
- source: this.__source,
1013
- id: this.__id,
1014
- title: this.__title,
1015
- description: this.__description,
1016
- favicon: this.__favicon,
1017
- image: this.__image,
1018
- version: 1
1019
- };
1020
- }
1021
- getUrl() {
1022
- return this.getLatest().__url;
1023
- }
1024
- setUrl(url) {
1025
- const writable = this.getWritable();
1026
- writable.__url = url;
1027
- }
1028
- getSource() {
1029
- return this.getLatest().__source;
1030
- }
1031
- setSource(source) {
1032
- const writable = this.getWritable();
1033
- writable.__source = source;
1034
- }
1035
- getId() {
1036
- return this.getLatest().__id;
1037
- }
1038
- setId(id) {
1039
- const writable = this.getWritable();
1040
- writable.__id = id;
1041
- }
1042
- decorate(_editor, _config) {
1043
- return createRendererDecoration("LinkCard", LinkCardRenderer, {
1044
- url: this.__url,
1045
- source: this.__source,
1046
- id: this.__id,
1047
- title: this.__title,
1048
- description: this.__description,
1049
- favicon: this.__favicon,
1050
- image: this.__image
1051
- });
1052
- }
1053
- };
1054
- __publicField(_LinkCardNode, "commandItems", [
1055
- {
1056
- title: "Link Card",
1057
- icon: createElement(Link, { size: 20 }),
1058
- description: "Link preview card",
1059
- keywords: ["link", "card", "bookmark", "embed"],
1060
- section: "MEDIA",
1061
- placement: ["slash", "toolbar"],
1062
- group: "insert",
1063
- onSelect: (editor) => {
1064
- editor.update(() => {
1065
- $insertNodes([$createLinkCardNode({ url: "" })]);
1066
- });
1067
- }
1068
- }
1069
- ]);
1070
- let LinkCardNode = _LinkCardNode;
1071
- function $createLinkCardNode(payload) {
1072
- return new LinkCardNode(payload);
1073
- }
1074
- function $isLinkCardNode(node) {
1075
- return node instanceof LinkCardNode;
1076
- }
1077
- function readBaseTextFromRuby(element) {
1078
- let base = "";
1079
- for (const child of Array.from(element.childNodes)) {
1080
- if (child.nodeType === Node.TEXT_NODE) {
1081
- base += child.textContent ?? "";
1082
- continue;
1083
- }
1084
- if (child.nodeType !== Node.ELEMENT_NODE) continue;
1085
- const childElement = child;
1086
- const tag = childElement.tagName.toLowerCase();
1087
- if (tag === "rt" || tag === "rp") continue;
1088
- base += childElement.textContent ?? "";
1089
- }
1090
- return base;
1091
- }
1092
- class RubyNode extends ElementNode {
1093
- constructor(reading, key) {
1094
- super(key);
1095
- __publicField(this, "__reading");
1096
- this.__reading = reading;
1097
- }
1098
- static getType() {
1099
- return "ruby";
1100
- }
1101
- static clone(node) {
1102
- return new RubyNode(node.__reading, node.__key);
1103
- }
1104
- static importJSON(serializedNode) {
1105
- return $createRubyNode(serializedNode.reading ?? "");
1106
- }
1107
- exportJSON() {
1108
- return {
1109
- ...super.exportJSON(),
1110
- type: "ruby",
1111
- reading: this.__reading,
1112
- version: 1
1113
- };
1114
- }
1115
- static importDOM() {
1116
- return {
1117
- ruby: () => ({
1118
- conversion: (domNode) => {
1119
- if (!(domNode instanceof HTMLElement)) return null;
1120
- const reading = domNode.querySelector("rt")?.textContent ?? "";
1121
- const baseText = readBaseTextFromRuby(domNode);
1122
- const node = $createRubyNode(reading);
1123
- if (baseText) {
1124
- node.append($createTextNode(baseText));
1125
- }
1126
- return { node };
1127
- },
1128
- priority: 2
1129
- })
1130
- };
1131
- }
1132
- exportDOM() {
1133
- const ruby = document.createElement("ruby");
1134
- ruby.className = `${semanticClassNames.ruby} ${sharedStyles.ruby}`;
1135
- const baseText = this.getTextContent();
1136
- if (baseText) {
1137
- ruby.append(baseText);
1138
- }
1139
- if (this.__reading) {
1140
- const rt = document.createElement("rt");
1141
- rt.className = `${semanticClassNames.rubyRt} ${sharedStyles.rubyRt}`;
1142
- rt.textContent = this.__reading;
1143
- ruby.append(rt);
1144
- }
1145
- return { element: ruby };
1146
- }
1147
- createDOM(_config) {
1148
- const span = document.createElement("span");
1149
- span.className = `${semanticClassNames.ruby} ${sharedStyles.ruby}`;
1150
- if (this.__reading) {
1151
- span.dataset.ruby = this.__reading;
1152
- }
1153
- return span;
1154
- }
1155
- updateDOM(prevNode, dom) {
1156
- if (prevNode.__reading !== this.__reading) {
1157
- if (this.__reading) {
1158
- dom.dataset.ruby = this.__reading;
1159
- } else {
1160
- delete dom.dataset.ruby;
1161
- }
1162
- }
1163
- return false;
1164
- }
1165
- canInsertTextBefore() {
1166
- return true;
1167
- }
1168
- canInsertTextAfter() {
1169
- return true;
1170
- }
1171
- isInline() {
1172
- return true;
1173
- }
1174
- getReading() {
1175
- return this.getLatest().__reading;
1176
- }
1177
- setReading(reading) {
1178
- const writable = this.getWritable();
1179
- writable.__reading = reading;
1180
- }
1181
- }
1182
- function $createRubyNode(reading) {
1183
- return new RubyNode(reading);
1184
- }
1185
- function $isRubyNode(node) {
1186
- return node instanceof RubyNode;
1187
- }
1188
- function VideoRenderer({ src, poster, width, height }) {
1189
- return /* @__PURE__ */ jsx("figure", { className: "rich-video", children: /* @__PURE__ */ jsx(
1190
- "video",
1191
- {
1192
- controls: true,
1193
- height,
1194
- poster,
1195
- preload: "metadata",
1196
- src,
1197
- style: { maxWidth: "100%", height: "auto" },
1198
- width
1199
- }
1200
- ) });
1201
- }
1202
- const _VideoNode = class _VideoNode extends DecoratorNode {
1203
- constructor(payload, key) {
1204
- super(key);
1205
- __publicField(this, "__src");
1206
- __publicField(this, "__poster");
1207
- __publicField(this, "__width");
1208
- __publicField(this, "__height");
1209
- this.__src = payload.src;
1210
- this.__poster = payload.poster;
1211
- this.__width = payload.width;
1212
- this.__height = payload.height;
1213
- }
1214
- static getType() {
1215
- return "video";
1216
- }
1217
- static clone(node) {
1218
- return new _VideoNode(
1219
- {
1220
- src: node.__src,
1221
- poster: node.__poster,
1222
- width: node.__width,
1223
- height: node.__height
1224
- },
1225
- node.__key
1226
- );
1227
- }
1228
- createDOM(_config) {
1229
- const div = document.createElement("div");
1230
- div.className = "rich-video-wrapper";
1231
- return div;
1232
- }
1233
- updateDOM() {
1234
- return false;
1235
- }
1236
- isInline() {
1237
- return false;
1238
- }
1239
- static importJSON(serializedNode) {
1240
- return $createVideoNode({
1241
- src: serializedNode.src,
1242
- poster: serializedNode.poster,
1243
- width: serializedNode.width,
1244
- height: serializedNode.height
1245
- });
1246
- }
1247
- exportJSON() {
1248
- return {
1249
- ...super.exportJSON(),
1250
- type: "video",
1251
- src: this.__src,
1252
- poster: this.__poster,
1253
- width: this.__width,
1254
- height: this.__height,
1255
- version: 1
1256
- };
1257
- }
1258
- getSrc() {
1259
- return this.getLatest().__src;
1260
- }
1261
- setSrc(src) {
1262
- const writable = this.getWritable();
1263
- writable.__src = src;
1264
- }
1265
- decorate(_editor, _config) {
1266
- return createRendererDecoration("Video", VideoRenderer, {
1267
- src: this.__src,
1268
- poster: this.__poster,
1269
- width: this.__width,
1270
- height: this.__height
1271
- });
1272
- }
1273
- };
1274
- __publicField(_VideoNode, "commandItems", [
1275
- {
1276
- title: "Video",
1277
- icon: createElement(Video, { size: 20 }),
1278
- description: "Embed a video",
1279
- keywords: ["video", "media", "mp4"],
1280
- section: "MEDIA",
1281
- placement: ["slash", "toolbar"],
1282
- group: "insert",
1283
- onSelect: (editor) => {
1284
- editor.update(() => {
1285
- $insertNodes([$createVideoNode({ src: "" })]);
1286
- });
1287
- }
1288
- }
1289
- ]);
1290
- let VideoNode = _VideoNode;
1291
- function $createVideoNode(payload) {
1292
- return new VideoNode(payload);
1293
- }
1294
- const builtinNodes = [
1295
- HeadingNode,
1296
- QuoteNode,
1297
- ListNode,
1298
- ListItemNode,
1299
- LinkNode,
1300
- AutoLinkNode,
1301
- HorizontalRuleNode,
1302
- TableNode,
1303
- TableCellNode,
1304
- TableRowNode,
1305
- CodeNode
1306
- ];
1307
- const customNodes = [
1308
- SpoilerNode,
1309
- MentionNode,
1310
- KaTeXInlineNode,
1311
- KaTeXBlockNode,
1312
- ImageNode,
1313
- AlertQuoteNode,
1314
- CodeBlockNode,
1315
- FootnoteNode,
1316
- FootnoteSectionNode,
1317
- VideoNode,
1318
- LinkCardNode,
1319
- CommentNode,
1320
- DetailsNode,
1321
- GridContainerNode,
1322
- BannerNode,
1323
- MermaidNode,
1324
- RubyNode,
1325
- TagNode
1326
- ];
1327
- const allNodes = [...builtinNodes, ...customNodes];
1328
- export {
1329
- $createCommentNode as $,
1330
- BANNER_LABELS as B,
1331
- CommentNode as C,
1332
- DetailsNode as D,
1333
- FootnoteSectionNode as F,
1334
- GridContainerNode as G,
1335
- LinkCardNode as L,
1336
- RubyNode as R,
1337
- VideoNode as V,
1338
- $createFootnoteSectionNode as a,
1339
- $createGridContainerNode as b,
1340
- $createLinkCardNode as c,
1341
- $createRubyNode as d,
1342
- $isCommentNode as e,
1343
- $isFootnoteSectionNode as f,
1344
- $isGridContainerNode as g,
1345
- $isLinkCardNode as h,
1346
- $isRubyNode as i,
1347
- BANNER_TYPES as j,
1348
- allNodes as k,
1349
- builtinNodes as l,
1350
- customNodes as m,
1351
- ColorSchemeProvider as n,
1352
- $isBannerNode as o,
1353
- BannerRenderer as p,
1354
- BannerNode as q,
1355
- normalizeBannerType as r,
1356
- $isCodeBlockNode as s,
1357
- CodeBlockRenderer as t,
1358
- useColorScheme as u,
1359
- CodeBlockNode as v,
1360
- $createCommentPlaceholderNode as w,
1361
- $createDetailsNode as x
1362
- };