@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.
- package/dist/AlertQuoteEditNode-C55sxsR3.js +267 -0
- package/dist/KaTeXRenderer-CQQT3BMw.js +215 -0
- package/dist/LinkCardRenderer-CigqFwCv.js +45 -0
- package/dist/MermaidPlugin-BrOr-wQi.js +67 -0
- package/dist/RubyRenderer-jOkydJHg.js +15 -0
- package/dist/SubmitShortcutPlugin-DhyVFzoj.js +2186 -0
- package/dist/commands-entry.mjs +54 -74
- package/dist/components/decorators/PollEditDecorator.d.ts +13 -0
- package/dist/components/decorators/PollEditDecorator.d.ts.map +1 -0
- package/dist/components/renderers/PollRenderer.d.ts +3 -0
- package/dist/components/renderers/PollRenderer.d.ts.map +1 -0
- package/dist/config-B5BuLljq.js +1633 -0
- package/dist/config-edit.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/context/PollDataContext.d.ts +11 -0
- package/dist/context/PollDataContext.d.ts.map +1 -0
- package/dist/extractPolls-DO31LNrp.js +116 -0
- package/dist/grid.css-CJCkLTZc.js +44 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +121 -180
- package/dist/katex.css-CIOEOXyd.js +145 -0
- package/dist/node-registry-Dz5OTkh4.js +946 -0
- package/dist/nodes/PollEditNode.d.ts +14 -0
- package/dist/nodes/PollEditNode.d.ts.map +1 -0
- package/dist/nodes/PollNode.d.ts +52 -0
- package/dist/nodes/PollNode.d.ts.map +1 -0
- package/dist/nodes-entry.d.ts +3 -0
- package/dist/nodes-entry.d.ts.map +1 -1
- package/dist/nodes-entry.mjs +5 -50
- package/dist/normalizeSerializedEditorState-B-1wmGzd.js +78 -0
- package/dist/plugins-entry.mjs +3 -28
- package/dist/renderers-entry.mjs +41 -61
- package/dist/rich-editor.css +2 -1
- package/dist/static-entry.d.ts +5 -0
- package/dist/static-entry.d.ts.map +1 -1
- package/dist/static-entry.mjs +16 -66
- package/dist/styles/index.d.ts +2 -0
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/poll-edit.css.d.ts +35 -0
- package/dist/styles/poll-edit.css.d.ts.map +1 -0
- package/dist/styles/poll.css.d.ts +43 -0
- package/dist/styles/poll.css.d.ts.map +1 -0
- package/dist/styles-entry.mjs +3 -21
- package/dist/theme-B5B2EOWM.js +1099 -0
- package/dist/types/poll.d.ts +36 -0
- package/dist/types/poll.d.ts.map +1 -0
- package/dist/types/renderer-config.d.ts +3 -0
- package/dist/types/renderer-config.d.ts.map +1 -1
- package/dist/utils/extractPolls.d.ts +4 -0
- package/dist/utils/extractPolls.d.ts.map +1 -0
- package/package.json +30 -30
- package/dist/AlertQuoteEditNode-sPNf3_7P.js +0 -293
- package/dist/KaTeXRenderer-CQyQzNTJ.js +0 -218
- package/dist/LinkCardRenderer-QmkOlyXb.js +0 -36
- package/dist/MermaidPlugin-DKuGUcCG.js +0 -101
- package/dist/PresentDialogContext-DRroMIoK.js +0 -71
- package/dist/RubyRenderer-CJQmODir.js +0 -14
- package/dist/SubmitShortcutPlugin-D9uKYHda.js +0 -2427
- package/dist/config-Dl3ZkytB.js +0 -1362
- package/dist/grid.css-Md5-Cfx_.js +0 -11
- package/dist/katex.css-Csc-7N7u.js +0 -28
- package/dist/node-registry-CovhHUB6.js +0 -824
- package/dist/normalizeSerializedEditorState-k5G4xSi9.js +0 -85
- package/dist/theme-lEwScxEX.js +0 -1113
|
@@ -0,0 +1,1099 @@
|
|
|
1
|
+
import { i as FootnoteStaticRenderer, l as RendererWrapper, r as decodeThumbHash, t as KaTeXRenderer, u as createRendererDecoration } from "./KaTeXRenderer-CQQT3BMw.js";
|
|
2
|
+
import { l as semanticClassNames, u as sharedStyles } from "./katex.css-CIOEOXyd.js";
|
|
3
|
+
import { createContext, createElement, use, useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { $getEditor, $getNodeByKey, $getSelection, $insertNodes, $isRangeSelection, DecoratorNode, ElementNode, TextNode, createCommand, getRegisteredNode } from "lexical";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { ImageIcon, Info, Lightbulb, MessageSquareWarning, OctagonAlert, Sigma, Tag, TriangleAlert, Workflow } from "lucide-react";
|
|
7
|
+
//#region src/context/NestedContentRendererContext.tsx
|
|
8
|
+
var NestedContentRendererContext = createContext(null);
|
|
9
|
+
var NestedContentRendererProvider = NestedContentRendererContext.Provider;
|
|
10
|
+
function useOptionalNestedContentRenderer() {
|
|
11
|
+
return use(NestedContentRendererContext);
|
|
12
|
+
}
|
|
13
|
+
function useNestedContentRenderer() {
|
|
14
|
+
const fn = use(NestedContentRendererContext);
|
|
15
|
+
if (!fn) throw new Error("useNestedContentRenderer must be used within a NestedContentRendererProvider");
|
|
16
|
+
return fn;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/components/renderers/AlertRenderer.tsx
|
|
20
|
+
var InfoIcon = () => /* @__PURE__ */ jsx(Info, { size: 16 });
|
|
21
|
+
var LightbulbIcon = () => /* @__PURE__ */ jsx(Lightbulb, { size: 16 });
|
|
22
|
+
var MessageWarningIcon = () => /* @__PURE__ */ jsx(MessageSquareWarning, { size: 16 });
|
|
23
|
+
var TriangleAlertIcon = () => /* @__PURE__ */ jsx(TriangleAlert, { size: 16 });
|
|
24
|
+
var OctagonAlertIcon = () => /* @__PURE__ */ jsx(OctagonAlert, { size: 16 });
|
|
25
|
+
var ALERT_ICONS = {
|
|
26
|
+
note: InfoIcon,
|
|
27
|
+
tip: LightbulbIcon,
|
|
28
|
+
important: MessageWarningIcon,
|
|
29
|
+
warning: TriangleAlertIcon,
|
|
30
|
+
caution: OctagonAlertIcon
|
|
31
|
+
};
|
|
32
|
+
var AlertRenderer = ({ type }) => {
|
|
33
|
+
const Icon = ALERT_ICONS[type];
|
|
34
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
35
|
+
className: `rich-alert-header rich-alert-header-${type}`,
|
|
36
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
37
|
+
className: "rich-alert-icon",
|
|
38
|
+
children: /* @__PURE__ */ jsx(Icon, {})
|
|
39
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
40
|
+
className: "rich-alert-label",
|
|
41
|
+
children: ALERT_LABELS[type]
|
|
42
|
+
})]
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/components/renderers/AlertStaticDecorator.tsx
|
|
47
|
+
function AlertStaticDecorator({ alertType, contentState }) {
|
|
48
|
+
const renderContent = useNestedContentRenderer();
|
|
49
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(RendererWrapper, {
|
|
50
|
+
defaultRenderer: AlertRenderer,
|
|
51
|
+
props: { type: alertType },
|
|
52
|
+
rendererKey: "Alert"
|
|
53
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
54
|
+
className: "rich-alert-content",
|
|
55
|
+
children: renderContent(contentState)
|
|
56
|
+
})] });
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/utils/extractTextContent.ts
|
|
60
|
+
function extractTextContent(state) {
|
|
61
|
+
function walk(node) {
|
|
62
|
+
if (node.text) return node.text;
|
|
63
|
+
if (node.children) return node.children.map(walk).join("");
|
|
64
|
+
if (node.root) return walk(node.root);
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
return walk(state);
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/typeof.js
|
|
71
|
+
function _typeof(o) {
|
|
72
|
+
"@babel/helpers - typeof";
|
|
73
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
74
|
+
return typeof o;
|
|
75
|
+
} : function(o) {
|
|
76
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
77
|
+
}, _typeof(o);
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/toPrimitive.js
|
|
81
|
+
function toPrimitive(t, r) {
|
|
82
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
83
|
+
var e = t[Symbol.toPrimitive];
|
|
84
|
+
if (void 0 !== e) {
|
|
85
|
+
var i = e.call(t, r || "default");
|
|
86
|
+
if ("object" != _typeof(i)) return i;
|
|
87
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
88
|
+
}
|
|
89
|
+
return ("string" === r ? String : Number)(t);
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/toPropertyKey.js
|
|
93
|
+
function toPropertyKey(t) {
|
|
94
|
+
var i = toPrimitive(t, "string");
|
|
95
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/defineProperty.js
|
|
99
|
+
function _defineProperty(e, r, t) {
|
|
100
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
101
|
+
value: t,
|
|
102
|
+
enumerable: !0,
|
|
103
|
+
configurable: !0,
|
|
104
|
+
writable: !0
|
|
105
|
+
}) : e[r] = t, e;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/nodes/AlertQuoteNode.ts
|
|
109
|
+
var ALERT_TYPES = [
|
|
110
|
+
"note",
|
|
111
|
+
"tip",
|
|
112
|
+
"important",
|
|
113
|
+
"warning",
|
|
114
|
+
"caution"
|
|
115
|
+
];
|
|
116
|
+
var ALERT_LABELS = {
|
|
117
|
+
note: "Note",
|
|
118
|
+
tip: "Tip",
|
|
119
|
+
important: "Important",
|
|
120
|
+
warning: "Warning",
|
|
121
|
+
caution: "Caution"
|
|
122
|
+
};
|
|
123
|
+
var AlertQuoteNode = class AlertQuoteNode extends DecoratorNode {
|
|
124
|
+
static getType() {
|
|
125
|
+
return "alert-quote";
|
|
126
|
+
}
|
|
127
|
+
static clone(node) {
|
|
128
|
+
return new AlertQuoteNode(node.__alertType, node.__contentState, node.__key);
|
|
129
|
+
}
|
|
130
|
+
constructor(alertType, contentState, key) {
|
|
131
|
+
super(key);
|
|
132
|
+
_defineProperty(this, "__alertType", void 0);
|
|
133
|
+
_defineProperty(this, "__contentState", void 0);
|
|
134
|
+
this.__alertType = alertType;
|
|
135
|
+
this.__contentState = contentState || { root: {
|
|
136
|
+
children: [{
|
|
137
|
+
type: "paragraph",
|
|
138
|
+
children: [],
|
|
139
|
+
direction: null,
|
|
140
|
+
format: "",
|
|
141
|
+
indent: 0,
|
|
142
|
+
textFormat: 0,
|
|
143
|
+
textStyle: "",
|
|
144
|
+
version: 1
|
|
145
|
+
}],
|
|
146
|
+
direction: null,
|
|
147
|
+
format: "",
|
|
148
|
+
indent: 0,
|
|
149
|
+
type: "root",
|
|
150
|
+
version: 1
|
|
151
|
+
} };
|
|
152
|
+
}
|
|
153
|
+
createDOM(_config) {
|
|
154
|
+
const div = document.createElement("div");
|
|
155
|
+
div.className = `${semanticClassNames.alert} ${sharedStyles.alert} rich-alert-${this.__alertType}`;
|
|
156
|
+
return div;
|
|
157
|
+
}
|
|
158
|
+
updateDOM(prevNode, dom) {
|
|
159
|
+
if (prevNode.__alertType !== this.__alertType) dom.className = `${semanticClassNames.alert} ${sharedStyles.alert} rich-alert-${this.__alertType}`;
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
isInline() {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
getAlertType() {
|
|
166
|
+
return this.__alertType;
|
|
167
|
+
}
|
|
168
|
+
setAlertType(alertType) {
|
|
169
|
+
const writable = this.getWritable();
|
|
170
|
+
writable.__alertType = alertType;
|
|
171
|
+
}
|
|
172
|
+
getContentState() {
|
|
173
|
+
return this.getLatest().__contentState;
|
|
174
|
+
}
|
|
175
|
+
setContentState(state) {
|
|
176
|
+
const writable = this.getWritable();
|
|
177
|
+
writable.__contentState = state;
|
|
178
|
+
}
|
|
179
|
+
getTextContent() {
|
|
180
|
+
return extractTextContent(this.__contentState);
|
|
181
|
+
}
|
|
182
|
+
static importJSON(serializedNode) {
|
|
183
|
+
return new AlertQuoteNode(serializedNode.alertType, serializedNode.content);
|
|
184
|
+
}
|
|
185
|
+
exportJSON() {
|
|
186
|
+
return {
|
|
187
|
+
...super.exportJSON(),
|
|
188
|
+
type: "alert-quote",
|
|
189
|
+
alertType: this.__alertType,
|
|
190
|
+
content: this.__contentState,
|
|
191
|
+
version: 1
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
decorate(_editor, _config) {
|
|
195
|
+
return createElement(AlertStaticDecorator, {
|
|
196
|
+
alertType: this.__alertType,
|
|
197
|
+
contentState: this.__contentState
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
function $isAlertQuoteNode(node) {
|
|
202
|
+
return node instanceof AlertQuoteNode;
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/nodes/FootnoteNode.ts
|
|
206
|
+
var FootnoteNode = class FootnoteNode extends DecoratorNode {
|
|
207
|
+
static getType() {
|
|
208
|
+
return "footnote";
|
|
209
|
+
}
|
|
210
|
+
static clone(node) {
|
|
211
|
+
return new FootnoteNode(node.__identifier, node.__key);
|
|
212
|
+
}
|
|
213
|
+
constructor(identifier, key) {
|
|
214
|
+
super(key);
|
|
215
|
+
_defineProperty(this, "__identifier", void 0);
|
|
216
|
+
this.__identifier = identifier;
|
|
217
|
+
}
|
|
218
|
+
createDOM(_config) {
|
|
219
|
+
const sup = document.createElement("sup");
|
|
220
|
+
sup.className = `${semanticClassNames.footnote} ${sharedStyles.footnote}`;
|
|
221
|
+
return sup;
|
|
222
|
+
}
|
|
223
|
+
updateDOM() {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
isInline() {
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
static importJSON(serializedNode) {
|
|
230
|
+
return $createFootnoteNode(serializedNode.identifier);
|
|
231
|
+
}
|
|
232
|
+
exportJSON() {
|
|
233
|
+
return {
|
|
234
|
+
...super.exportJSON(),
|
|
235
|
+
type: "footnote",
|
|
236
|
+
identifier: this.__identifier,
|
|
237
|
+
version: 1
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
getIdentifier() {
|
|
241
|
+
return this.getLatest().__identifier;
|
|
242
|
+
}
|
|
243
|
+
setIdentifier(identifier) {
|
|
244
|
+
const writable = this.getWritable();
|
|
245
|
+
writable.__identifier = identifier;
|
|
246
|
+
}
|
|
247
|
+
decorate(_editor, _config) {
|
|
248
|
+
return createRendererDecoration("Footnote", FootnoteStaticRenderer, { identifier: this.__identifier });
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
function $createFootnoteNode(identifier) {
|
|
252
|
+
return new FootnoteNode(identifier);
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/components/renderers/ImageRenderer.tsx
|
|
256
|
+
function ImageRenderer({ src, altText, width, height, caption, thumbhash, accent }) {
|
|
257
|
+
const [loaded, setLoaded] = useState(false);
|
|
258
|
+
const [zoomed, setZoomed] = useState(false);
|
|
259
|
+
const handleLoad = useCallback(() => setLoaded(true), []);
|
|
260
|
+
const handleZoomOpen = useCallback(() => {
|
|
261
|
+
if (!loaded) return;
|
|
262
|
+
setZoomed(true);
|
|
263
|
+
}, [loaded]);
|
|
264
|
+
const handleZoomClose = useCallback(() => setZoomed(false), []);
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
if (!zoomed) return;
|
|
267
|
+
const onKeyDown = (e) => {
|
|
268
|
+
if (e.key === "Escape") setZoomed(false);
|
|
269
|
+
};
|
|
270
|
+
document.addEventListener("keydown", onKeyDown);
|
|
271
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
272
|
+
}, [zoomed]);
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
if (!zoomed) return;
|
|
275
|
+
const prev = document.body.style.overflow;
|
|
276
|
+
document.body.style.overflow = "hidden";
|
|
277
|
+
return () => {
|
|
278
|
+
document.body.style.overflow = prev;
|
|
279
|
+
};
|
|
280
|
+
}, [zoomed]);
|
|
281
|
+
const handleContainerKeyDown = useCallback((e) => {
|
|
282
|
+
if ((e.key === "Enter" || e.key === " ") && loaded) {
|
|
283
|
+
e.preventDefault();
|
|
284
|
+
setZoomed(true);
|
|
285
|
+
}
|
|
286
|
+
}, [loaded]);
|
|
287
|
+
const placeholderUrl = useMemo(() => thumbhash ? decodeThumbHash(thumbhash) : void 0, [thumbhash]);
|
|
288
|
+
const aspectStyle = width && height ? {
|
|
289
|
+
aspectRatio: `${width} / ${height}`,
|
|
290
|
+
maxWidth: "100%",
|
|
291
|
+
width
|
|
292
|
+
} : { maxWidth: "100%" };
|
|
293
|
+
return /* @__PURE__ */ jsxs("figure", {
|
|
294
|
+
className: "rich-image",
|
|
295
|
+
children: [
|
|
296
|
+
/* @__PURE__ */ jsx("div", {
|
|
297
|
+
"aria-label": loaded ? `Zoom image: ${altText}` : void 0,
|
|
298
|
+
className: `rich-image-container${loaded ? " rich-image-loaded" : ""}`,
|
|
299
|
+
role: "button",
|
|
300
|
+
tabIndex: loaded ? 0 : -1,
|
|
301
|
+
style: {
|
|
302
|
+
...aspectStyle,
|
|
303
|
+
backgroundColor: !loaded && !placeholderUrl ? accent : void 0,
|
|
304
|
+
backgroundImage: !loaded && placeholderUrl ? `url(${placeholderUrl})` : void 0,
|
|
305
|
+
backgroundSize: "cover",
|
|
306
|
+
cursor: loaded ? "zoom-in" : void 0
|
|
307
|
+
},
|
|
308
|
+
onClick: handleZoomOpen,
|
|
309
|
+
onKeyDown: handleContainerKeyDown,
|
|
310
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
311
|
+
alt: altText,
|
|
312
|
+
className: loaded ? "rich-image-visible" : "rich-image-hidden",
|
|
313
|
+
height,
|
|
314
|
+
loading: "lazy",
|
|
315
|
+
src,
|
|
316
|
+
style: {
|
|
317
|
+
maxWidth: "100%",
|
|
318
|
+
height: "auto"
|
|
319
|
+
},
|
|
320
|
+
width,
|
|
321
|
+
onLoad: handleLoad
|
|
322
|
+
})
|
|
323
|
+
}),
|
|
324
|
+
caption && /* @__PURE__ */ jsx("figcaption", { children: caption }),
|
|
325
|
+
zoomed && /* @__PURE__ */ jsx("div", {
|
|
326
|
+
"aria-label": `Zoomed image: ${altText}`,
|
|
327
|
+
"aria-modal": "true",
|
|
328
|
+
className: "rich-image-zoom-overlay",
|
|
329
|
+
role: "dialog",
|
|
330
|
+
tabIndex: 0,
|
|
331
|
+
onClick: handleZoomClose,
|
|
332
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
333
|
+
alt: altText,
|
|
334
|
+
className: "rich-image-zoom-img",
|
|
335
|
+
src
|
|
336
|
+
})
|
|
337
|
+
})
|
|
338
|
+
]
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/plugins/image-upload-command.ts
|
|
343
|
+
var OPEN_IMAGE_UPLOAD_DIALOG_COMMAND = createCommand("OPEN_IMAGE_UPLOAD_DIALOG_COMMAND");
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/nodes/ImageNode.ts
|
|
346
|
+
function sanitizeImageSrc(src) {
|
|
347
|
+
const trimmed = src.trim();
|
|
348
|
+
if (/^(?:javascript\s*:|vbscript\s*:|data\s*:(?!image\/))/i.test(trimmed)) return "";
|
|
349
|
+
return trimmed;
|
|
350
|
+
}
|
|
351
|
+
function sanitizeColor(value) {
|
|
352
|
+
if (!value) return void 0;
|
|
353
|
+
const trimmed = value.trim();
|
|
354
|
+
if (/^#[\da-f]{3,8}$/i.test(trimmed)) return trimmed;
|
|
355
|
+
if (/^(?:rgb|hsl)a?\([^)]+\)$/i.test(trimmed)) return trimmed;
|
|
356
|
+
if (/^[a-z]{3,20}$/i.test(trimmed)) return trimmed;
|
|
357
|
+
}
|
|
358
|
+
var ImageNode = class ImageNode extends DecoratorNode {
|
|
359
|
+
static getType() {
|
|
360
|
+
return "image";
|
|
361
|
+
}
|
|
362
|
+
static clone(node) {
|
|
363
|
+
return new ImageNode({
|
|
364
|
+
src: node.__src,
|
|
365
|
+
altText: node.__altText,
|
|
366
|
+
width: node.__width,
|
|
367
|
+
height: node.__height,
|
|
368
|
+
caption: node.__caption,
|
|
369
|
+
thumbhash: node.__thumbhash,
|
|
370
|
+
accent: node.__accent
|
|
371
|
+
}, node.__key);
|
|
372
|
+
}
|
|
373
|
+
constructor(payload, key) {
|
|
374
|
+
super(key);
|
|
375
|
+
_defineProperty(this, "__src", void 0);
|
|
376
|
+
_defineProperty(this, "__altText", void 0);
|
|
377
|
+
_defineProperty(this, "__width", void 0);
|
|
378
|
+
_defineProperty(this, "__height", void 0);
|
|
379
|
+
_defineProperty(this, "__caption", void 0);
|
|
380
|
+
_defineProperty(this, "__thumbhash", void 0);
|
|
381
|
+
_defineProperty(this, "__accent", void 0);
|
|
382
|
+
this.__src = sanitizeImageSrc(payload.src);
|
|
383
|
+
this.__altText = payload.altText;
|
|
384
|
+
this.__width = payload.width;
|
|
385
|
+
this.__height = payload.height;
|
|
386
|
+
this.__caption = payload.caption;
|
|
387
|
+
this.__thumbhash = payload.thumbhash;
|
|
388
|
+
this.__accent = sanitizeColor(payload.accent);
|
|
389
|
+
}
|
|
390
|
+
createDOM(_config) {
|
|
391
|
+
const div = document.createElement("div");
|
|
392
|
+
div.className = "rich-image-wrapper";
|
|
393
|
+
return div;
|
|
394
|
+
}
|
|
395
|
+
updateDOM() {
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
isInline() {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
static importJSON(serializedNode) {
|
|
402
|
+
return $createImageNode({
|
|
403
|
+
src: serializedNode.src,
|
|
404
|
+
altText: serializedNode.altText,
|
|
405
|
+
width: serializedNode.width,
|
|
406
|
+
height: serializedNode.height,
|
|
407
|
+
caption: serializedNode.caption,
|
|
408
|
+
thumbhash: serializedNode.thumbhash,
|
|
409
|
+
accent: serializedNode.accent
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
exportJSON() {
|
|
413
|
+
return {
|
|
414
|
+
...super.exportJSON(),
|
|
415
|
+
type: "image",
|
|
416
|
+
src: this.__src,
|
|
417
|
+
altText: this.__altText,
|
|
418
|
+
width: this.__width,
|
|
419
|
+
height: this.__height,
|
|
420
|
+
caption: this.__caption,
|
|
421
|
+
thumbhash: this.__thumbhash,
|
|
422
|
+
accent: this.__accent,
|
|
423
|
+
version: 1
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
setSrc(src) {
|
|
427
|
+
const writable = this.getWritable();
|
|
428
|
+
writable.__src = sanitizeImageSrc(src);
|
|
429
|
+
}
|
|
430
|
+
setAltText(altText) {
|
|
431
|
+
const writable = this.getWritable();
|
|
432
|
+
writable.__altText = altText;
|
|
433
|
+
}
|
|
434
|
+
setCaption(caption) {
|
|
435
|
+
const writable = this.getWritable();
|
|
436
|
+
writable.__caption = caption;
|
|
437
|
+
}
|
|
438
|
+
setDimensions(width, height) {
|
|
439
|
+
const writable = this.getWritable();
|
|
440
|
+
writable.__width = width;
|
|
441
|
+
writable.__height = height;
|
|
442
|
+
}
|
|
443
|
+
setThumbhash(thumbhash) {
|
|
444
|
+
const writable = this.getWritable();
|
|
445
|
+
writable.__thumbhash = thumbhash;
|
|
446
|
+
}
|
|
447
|
+
setAccent(accent) {
|
|
448
|
+
const writable = this.getWritable();
|
|
449
|
+
writable.__accent = sanitizeColor(accent);
|
|
450
|
+
}
|
|
451
|
+
getSrc() {
|
|
452
|
+
return this.__src;
|
|
453
|
+
}
|
|
454
|
+
getAltText() {
|
|
455
|
+
return this.__altText;
|
|
456
|
+
}
|
|
457
|
+
getCaption() {
|
|
458
|
+
return this.__caption;
|
|
459
|
+
}
|
|
460
|
+
getWidth() {
|
|
461
|
+
return this.__width;
|
|
462
|
+
}
|
|
463
|
+
getHeight() {
|
|
464
|
+
return this.__height;
|
|
465
|
+
}
|
|
466
|
+
getThumbhash() {
|
|
467
|
+
return this.__thumbhash;
|
|
468
|
+
}
|
|
469
|
+
getAccent() {
|
|
470
|
+
return this.__accent;
|
|
471
|
+
}
|
|
472
|
+
decorate(_editor, _config) {
|
|
473
|
+
return createRendererDecoration("Image", ImageRenderer, {
|
|
474
|
+
src: this.__src,
|
|
475
|
+
altText: this.__altText,
|
|
476
|
+
width: this.__width,
|
|
477
|
+
height: this.__height,
|
|
478
|
+
caption: this.__caption,
|
|
479
|
+
thumbhash: this.__thumbhash,
|
|
480
|
+
accent: this.__accent
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
_defineProperty(ImageNode, "commandItems", [{
|
|
485
|
+
title: "Image",
|
|
486
|
+
icon: createElement(ImageIcon, { size: 20 }),
|
|
487
|
+
description: "Upload or embed an image",
|
|
488
|
+
keywords: [
|
|
489
|
+
"image",
|
|
490
|
+
"picture",
|
|
491
|
+
"photo"
|
|
492
|
+
],
|
|
493
|
+
section: "MEDIA",
|
|
494
|
+
placement: ["slash", "toolbar"],
|
|
495
|
+
group: "insert",
|
|
496
|
+
onSelect: (editor) => {
|
|
497
|
+
if (editor.dispatchCommand(OPEN_IMAGE_UPLOAD_DIALOG_COMMAND, void 0)) return;
|
|
498
|
+
editor.update(() => {
|
|
499
|
+
$insertNodes([$createImageNode({
|
|
500
|
+
src: "",
|
|
501
|
+
altText: ""
|
|
502
|
+
})]);
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}]);
|
|
506
|
+
function $createImageNode(payload) {
|
|
507
|
+
return new ImageNode(payload);
|
|
508
|
+
}
|
|
509
|
+
function $isImageNode(node) {
|
|
510
|
+
return node instanceof ImageNode;
|
|
511
|
+
}
|
|
512
|
+
//#endregion
|
|
513
|
+
//#region src/utils/katex-defaults.ts
|
|
514
|
+
var DEFAULT_KATEX_EQUATION = "x^2 + y^2 = z^2";
|
|
515
|
+
function resolveKaTeXEquation(equation, options) {
|
|
516
|
+
if (options?.autoOpenOnMount && !equation.trim()) return DEFAULT_KATEX_EQUATION;
|
|
517
|
+
return equation;
|
|
518
|
+
}
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region src/utils/getRegisteredNodeKlass.ts
|
|
521
|
+
function isMissingActiveEditorError(error) {
|
|
522
|
+
return error instanceof Error && error.message.includes("Unable to find an active editor");
|
|
523
|
+
}
|
|
524
|
+
function getRegisteredNodeKlass(nodeType, fallbackKlass) {
|
|
525
|
+
try {
|
|
526
|
+
const registeredKlass = getRegisteredNode($getEditor(), nodeType)?.klass;
|
|
527
|
+
if (registeredKlass && (registeredKlass === fallbackKlass || registeredKlass.prototype instanceof fallbackKlass)) return registeredKlass;
|
|
528
|
+
} catch (error) {
|
|
529
|
+
if (!isMissingActiveEditorError(error)) throw error;
|
|
530
|
+
}
|
|
531
|
+
return fallbackKlass;
|
|
532
|
+
}
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region src/nodes/KaTeXBlockNode.ts
|
|
535
|
+
var KaTeXBlockNode = class KaTeXBlockNode extends DecoratorNode {
|
|
536
|
+
static getType() {
|
|
537
|
+
return "katex-block";
|
|
538
|
+
}
|
|
539
|
+
static clone(node) {
|
|
540
|
+
return new KaTeXBlockNode(node.__equation, node.__key, node.__autoOpenOnMount);
|
|
541
|
+
}
|
|
542
|
+
constructor(equation, key, autoOpenOnMount = false) {
|
|
543
|
+
super(key);
|
|
544
|
+
_defineProperty(this, "__equation", void 0);
|
|
545
|
+
_defineProperty(this, "__autoOpenOnMount", void 0);
|
|
546
|
+
this.__equation = equation;
|
|
547
|
+
this.__autoOpenOnMount = autoOpenOnMount;
|
|
548
|
+
}
|
|
549
|
+
createDOM(_config) {
|
|
550
|
+
const div = document.createElement("div");
|
|
551
|
+
div.className = "rich-katex-block-wrapper";
|
|
552
|
+
return div;
|
|
553
|
+
}
|
|
554
|
+
updateDOM() {
|
|
555
|
+
return false;
|
|
556
|
+
}
|
|
557
|
+
isInline() {
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
static importJSON(serializedNode) {
|
|
561
|
+
return $createKaTeXBlockNode(serializedNode.equation);
|
|
562
|
+
}
|
|
563
|
+
exportJSON() {
|
|
564
|
+
return {
|
|
565
|
+
...super.exportJSON(),
|
|
566
|
+
type: "katex-block",
|
|
567
|
+
equation: this.__equation,
|
|
568
|
+
version: 1
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
getEquation() {
|
|
572
|
+
return this.__equation;
|
|
573
|
+
}
|
|
574
|
+
setEquation(equation) {
|
|
575
|
+
const writable = this.getWritable();
|
|
576
|
+
writable.__equation = equation;
|
|
577
|
+
}
|
|
578
|
+
getShouldAutoOpenOnMount() {
|
|
579
|
+
return this.getLatest().__autoOpenOnMount;
|
|
580
|
+
}
|
|
581
|
+
setShouldAutoOpenOnMount(autoOpenOnMount) {
|
|
582
|
+
const writable = this.getWritable();
|
|
583
|
+
writable.__autoOpenOnMount = autoOpenOnMount;
|
|
584
|
+
}
|
|
585
|
+
decorate(_editor, _config) {
|
|
586
|
+
return createRendererDecoration("KaTeX", KaTeXRenderer, {
|
|
587
|
+
equation: this.__equation,
|
|
588
|
+
displayMode: true
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
_defineProperty(KaTeXBlockNode, "slashMenuItems", [{
|
|
593
|
+
title: "Math Equation",
|
|
594
|
+
icon: createElement(Sigma, { size: 20 }),
|
|
595
|
+
description: "KaTeX block formula",
|
|
596
|
+
keywords: [
|
|
597
|
+
"math",
|
|
598
|
+
"equation",
|
|
599
|
+
"latex",
|
|
600
|
+
"katex"
|
|
601
|
+
],
|
|
602
|
+
section: "ADVANCED",
|
|
603
|
+
onSelect: (editor) => {
|
|
604
|
+
editor.update(() => {
|
|
605
|
+
$insertNodes([$createKaTeXBlockNode("", { autoOpenOnMount: true })]);
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}]);
|
|
609
|
+
function $createKaTeXBlockNode(equation, options) {
|
|
610
|
+
const node = new (getRegisteredNodeKlass(KaTeXBlockNode.getType(), KaTeXBlockNode))(resolveKaTeXEquation(equation, options));
|
|
611
|
+
if (options?.autoOpenOnMount) node.setShouldAutoOpenOnMount(true);
|
|
612
|
+
return node;
|
|
613
|
+
}
|
|
614
|
+
function $isKaTeXBlockNode(node) {
|
|
615
|
+
return node instanceof KaTeXBlockNode;
|
|
616
|
+
}
|
|
617
|
+
//#endregion
|
|
618
|
+
//#region src/nodes/KaTeXInlineNode.ts
|
|
619
|
+
var KaTeXInlineNode = class KaTeXInlineNode extends DecoratorNode {
|
|
620
|
+
static getType() {
|
|
621
|
+
return "katex-inline";
|
|
622
|
+
}
|
|
623
|
+
static clone(node) {
|
|
624
|
+
return new KaTeXInlineNode(node.__equation, node.__key, node.__autoOpenOnMount, node.__color);
|
|
625
|
+
}
|
|
626
|
+
constructor(equation, key, autoOpenOnMount = false, color = null) {
|
|
627
|
+
super(key);
|
|
628
|
+
_defineProperty(this, "__equation", void 0);
|
|
629
|
+
_defineProperty(this, "__autoOpenOnMount", void 0);
|
|
630
|
+
_defineProperty(this, "__color", void 0);
|
|
631
|
+
this.__equation = equation;
|
|
632
|
+
this.__autoOpenOnMount = autoOpenOnMount;
|
|
633
|
+
this.__color = color;
|
|
634
|
+
}
|
|
635
|
+
createDOM(_config) {
|
|
636
|
+
return document.createElement("span");
|
|
637
|
+
}
|
|
638
|
+
updateDOM() {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
isInline() {
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
static importJSON(serializedNode) {
|
|
645
|
+
const node = $createKaTeXInlineNode(serializedNode.equation);
|
|
646
|
+
if (serializedNode.color) node.setColor(serializedNode.color);
|
|
647
|
+
return node;
|
|
648
|
+
}
|
|
649
|
+
exportJSON() {
|
|
650
|
+
return {
|
|
651
|
+
...super.exportJSON(),
|
|
652
|
+
type: "katex-inline",
|
|
653
|
+
equation: this.__equation,
|
|
654
|
+
color: this.__color,
|
|
655
|
+
version: 1
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
getEquation() {
|
|
659
|
+
return this.__equation;
|
|
660
|
+
}
|
|
661
|
+
setEquation(equation) {
|
|
662
|
+
const writable = this.getWritable();
|
|
663
|
+
writable.__equation = equation;
|
|
664
|
+
}
|
|
665
|
+
getShouldAutoOpenOnMount() {
|
|
666
|
+
return this.getLatest().__autoOpenOnMount;
|
|
667
|
+
}
|
|
668
|
+
setShouldAutoOpenOnMount(autoOpenOnMount) {
|
|
669
|
+
const writable = this.getWritable();
|
|
670
|
+
writable.__autoOpenOnMount = autoOpenOnMount;
|
|
671
|
+
}
|
|
672
|
+
getColor() {
|
|
673
|
+
return this.getLatest().__color;
|
|
674
|
+
}
|
|
675
|
+
setColor(color) {
|
|
676
|
+
const writable = this.getWritable();
|
|
677
|
+
writable.__color = color;
|
|
678
|
+
}
|
|
679
|
+
decorate(_editor, _config) {
|
|
680
|
+
const decoration = createRendererDecoration("KaTeX", KaTeXRenderer, {
|
|
681
|
+
equation: this.__equation,
|
|
682
|
+
displayMode: false
|
|
683
|
+
});
|
|
684
|
+
if (!this.__color) return decoration;
|
|
685
|
+
return createElement("span", { style: { color: this.__color } }, decoration);
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
function $createKaTeXInlineNode(equation, options) {
|
|
689
|
+
const node = new (getRegisteredNodeKlass(KaTeXInlineNode.getType(), KaTeXInlineNode))(resolveKaTeXEquation(equation, options));
|
|
690
|
+
if (options?.autoOpenOnMount) node.setShouldAutoOpenOnMount(true);
|
|
691
|
+
return node;
|
|
692
|
+
}
|
|
693
|
+
function $isKaTeXInlineNode(node) {
|
|
694
|
+
return node instanceof KaTeXInlineNode;
|
|
695
|
+
}
|
|
696
|
+
//#endregion
|
|
697
|
+
//#region src/components/renderers/MentionRenderer.tsx
|
|
698
|
+
function MentionRenderer({ handle, displayName }) {
|
|
699
|
+
const normalizedHandle = handle.replace(/^@+/, "");
|
|
700
|
+
return /* @__PURE__ */ jsx("span", {
|
|
701
|
+
className: "rich-mention rich-mention-plain",
|
|
702
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
703
|
+
className: "rich-mention-handle",
|
|
704
|
+
children: ["@", displayName || normalizedHandle]
|
|
705
|
+
})
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
//#endregion
|
|
709
|
+
//#region src/nodes/MentionNode.ts
|
|
710
|
+
var MentionNode = class MentionNode extends DecoratorNode {
|
|
711
|
+
static getType() {
|
|
712
|
+
return "mention";
|
|
713
|
+
}
|
|
714
|
+
static clone(node) {
|
|
715
|
+
return new MentionNode(node.__platform, node.__handle, node.__displayName, node.__key);
|
|
716
|
+
}
|
|
717
|
+
constructor(platform, handle, displayName, key) {
|
|
718
|
+
super(key);
|
|
719
|
+
_defineProperty(this, "__platform", void 0);
|
|
720
|
+
_defineProperty(this, "__handle", void 0);
|
|
721
|
+
_defineProperty(this, "__displayName", void 0);
|
|
722
|
+
this.__platform = platform;
|
|
723
|
+
this.__handle = handle;
|
|
724
|
+
this.__displayName = displayName;
|
|
725
|
+
}
|
|
726
|
+
createDOM(_config) {
|
|
727
|
+
const el = document.createElement("span");
|
|
728
|
+
el.style.display = "inline-flex";
|
|
729
|
+
el.style.alignItems = "center";
|
|
730
|
+
el.style.height = "1lh";
|
|
731
|
+
return el;
|
|
732
|
+
}
|
|
733
|
+
updateDOM() {
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
isInline() {
|
|
737
|
+
return true;
|
|
738
|
+
}
|
|
739
|
+
getPlatform() {
|
|
740
|
+
return this.getLatest().__platform;
|
|
741
|
+
}
|
|
742
|
+
getHandle() {
|
|
743
|
+
return this.getLatest().__handle;
|
|
744
|
+
}
|
|
745
|
+
getDisplayName() {
|
|
746
|
+
return this.getLatest().__displayName;
|
|
747
|
+
}
|
|
748
|
+
static importJSON(serializedNode) {
|
|
749
|
+
return $createMentionNode(serializedNode.platform, serializedNode.handle, serializedNode.displayName);
|
|
750
|
+
}
|
|
751
|
+
exportJSON() {
|
|
752
|
+
return {
|
|
753
|
+
...super.exportJSON(),
|
|
754
|
+
type: "mention",
|
|
755
|
+
platform: this.__platform,
|
|
756
|
+
handle: this.__handle,
|
|
757
|
+
...this.__displayName ? { displayName: this.__displayName } : {},
|
|
758
|
+
version: 1
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
decorate(_editor, _config) {
|
|
762
|
+
return createRendererDecoration("Mention", MentionRenderer, {
|
|
763
|
+
platform: this.__platform,
|
|
764
|
+
handle: this.__handle,
|
|
765
|
+
displayName: this.__displayName
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
_defineProperty(MentionNode, "slashMenuItems", [{
|
|
770
|
+
title: "Mention",
|
|
771
|
+
icon: createElement("span", { style: {
|
|
772
|
+
fontSize: 16,
|
|
773
|
+
fontWeight: 700
|
|
774
|
+
} }, "@"),
|
|
775
|
+
description: "Mention a social account",
|
|
776
|
+
keywords: [
|
|
777
|
+
"mention",
|
|
778
|
+
"at",
|
|
779
|
+
"@",
|
|
780
|
+
"github",
|
|
781
|
+
"twitter"
|
|
782
|
+
],
|
|
783
|
+
section: "INLINE",
|
|
784
|
+
onSelect: (editor) => {
|
|
785
|
+
editor.update(() => {
|
|
786
|
+
const selection = $getSelection();
|
|
787
|
+
if ($isRangeSelection(selection)) selection.insertText("@");
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
}]);
|
|
791
|
+
function $createMentionNode(platform, handle, displayName) {
|
|
792
|
+
return new MentionNode(platform, handle, displayName);
|
|
793
|
+
}
|
|
794
|
+
function $isMentionNode(node) {
|
|
795
|
+
return node instanceof MentionNode;
|
|
796
|
+
}
|
|
797
|
+
//#endregion
|
|
798
|
+
//#region src/components/renderers/MermaidRenderer.tsx
|
|
799
|
+
function MermaidRenderer({ content }) {
|
|
800
|
+
return /* @__PURE__ */ jsx("div", {
|
|
801
|
+
className: "rich-mermaid-block",
|
|
802
|
+
children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: content }) })
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
//#endregion
|
|
806
|
+
//#region src/nodes/MermaidNode.ts
|
|
807
|
+
var MermaidNode = class MermaidNode extends DecoratorNode {
|
|
808
|
+
static getType() {
|
|
809
|
+
return "mermaid";
|
|
810
|
+
}
|
|
811
|
+
static clone(node) {
|
|
812
|
+
return new MermaidNode(node.__diagram, node.__key);
|
|
813
|
+
}
|
|
814
|
+
constructor(diagram, key) {
|
|
815
|
+
super(key);
|
|
816
|
+
_defineProperty(this, "__diagram", void 0);
|
|
817
|
+
this.__diagram = diagram;
|
|
818
|
+
}
|
|
819
|
+
createDOM(_config) {
|
|
820
|
+
const div = document.createElement("div");
|
|
821
|
+
div.className = "rich-mermaid-wrapper";
|
|
822
|
+
return div;
|
|
823
|
+
}
|
|
824
|
+
updateDOM() {
|
|
825
|
+
return false;
|
|
826
|
+
}
|
|
827
|
+
isInline() {
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
static importJSON(serializedNode) {
|
|
831
|
+
return $createMermaidNode(serializedNode.diagram);
|
|
832
|
+
}
|
|
833
|
+
exportJSON() {
|
|
834
|
+
return {
|
|
835
|
+
...super.exportJSON(),
|
|
836
|
+
type: "mermaid",
|
|
837
|
+
diagram: this.__diagram,
|
|
838
|
+
version: 1
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
getDiagram() {
|
|
842
|
+
return this.__diagram;
|
|
843
|
+
}
|
|
844
|
+
setDiagram(diagram) {
|
|
845
|
+
const writable = this.getWritable();
|
|
846
|
+
writable.__diagram = diagram;
|
|
847
|
+
}
|
|
848
|
+
decorate(editor, _config) {
|
|
849
|
+
const nodeKey = this.__key;
|
|
850
|
+
return createRendererDecoration("Mermaid", MermaidRenderer, {
|
|
851
|
+
content: this.__diagram,
|
|
852
|
+
onContentChange: (newDiagram) => {
|
|
853
|
+
editor.update(() => {
|
|
854
|
+
const node = $getNodeByKey(nodeKey);
|
|
855
|
+
if (node) node.setDiagram(newDiagram);
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
_defineProperty(MermaidNode, "commandItems", [{
|
|
862
|
+
title: "Mermaid Diagram",
|
|
863
|
+
icon: createElement(Workflow, { size: 20 }),
|
|
864
|
+
description: "Flowchart, sequence diagram",
|
|
865
|
+
keywords: [
|
|
866
|
+
"mermaid",
|
|
867
|
+
"diagram",
|
|
868
|
+
"chart",
|
|
869
|
+
"flowchart"
|
|
870
|
+
],
|
|
871
|
+
section: "MEDIA",
|
|
872
|
+
placement: ["slash", "toolbar"],
|
|
873
|
+
group: "insert",
|
|
874
|
+
onSelect: (editor) => {
|
|
875
|
+
editor.update(() => {
|
|
876
|
+
$insertNodes([$createMermaidNode("graph TD\n A[Start] --> B[End]")]);
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
}]);
|
|
880
|
+
function $createMermaidNode(diagram) {
|
|
881
|
+
return new MermaidNode(diagram);
|
|
882
|
+
}
|
|
883
|
+
function $isMermaidNode(node) {
|
|
884
|
+
return node instanceof MermaidNode;
|
|
885
|
+
}
|
|
886
|
+
//#endregion
|
|
887
|
+
//#region src/nodes/SpoilerNode.ts
|
|
888
|
+
var SpoilerNode = class SpoilerNode extends ElementNode {
|
|
889
|
+
static getType() {
|
|
890
|
+
return "spoiler";
|
|
891
|
+
}
|
|
892
|
+
static clone(node) {
|
|
893
|
+
return new SpoilerNode(node.__key);
|
|
894
|
+
}
|
|
895
|
+
constructor(key) {
|
|
896
|
+
super(key);
|
|
897
|
+
}
|
|
898
|
+
createDOM(_config) {
|
|
899
|
+
const span = document.createElement("span");
|
|
900
|
+
span.className = `${semanticClassNames.spoiler} ${sharedStyles.spoiler}`;
|
|
901
|
+
span.setAttribute("role", "button");
|
|
902
|
+
span.setAttribute("tabindex", "0");
|
|
903
|
+
span.setAttribute("aria-label", "Spoiler (click to reveal)");
|
|
904
|
+
const toggle = () => {
|
|
905
|
+
if (span.isContentEditable) return;
|
|
906
|
+
span.classList.toggle(semanticClassNames.spoilerRevealed);
|
|
907
|
+
const revealed = span.classList.toggle(sharedStyles.spoilerRevealed);
|
|
908
|
+
span.setAttribute("aria-label", revealed ? "Spoiler (revealed)" : "Spoiler (click to reveal)");
|
|
909
|
+
};
|
|
910
|
+
span.addEventListener("click", toggle);
|
|
911
|
+
span.addEventListener("keydown", (e) => {
|
|
912
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
913
|
+
e.preventDefault();
|
|
914
|
+
toggle();
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
return span;
|
|
918
|
+
}
|
|
919
|
+
updateDOM() {
|
|
920
|
+
return false;
|
|
921
|
+
}
|
|
922
|
+
static importJSON(_serializedNode) {
|
|
923
|
+
return $createSpoilerNode();
|
|
924
|
+
}
|
|
925
|
+
exportJSON() {
|
|
926
|
+
return {
|
|
927
|
+
...super.exportJSON(),
|
|
928
|
+
type: "spoiler",
|
|
929
|
+
version: 1
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
canInsertTextBefore() {
|
|
933
|
+
return true;
|
|
934
|
+
}
|
|
935
|
+
canInsertTextAfter() {
|
|
936
|
+
return true;
|
|
937
|
+
}
|
|
938
|
+
isInline() {
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
function $createSpoilerNode() {
|
|
943
|
+
return new SpoilerNode();
|
|
944
|
+
}
|
|
945
|
+
function $isSpoilerNode(node) {
|
|
946
|
+
return node instanceof SpoilerNode;
|
|
947
|
+
}
|
|
948
|
+
//#endregion
|
|
949
|
+
//#region src/utils/tag-color.ts
|
|
950
|
+
function stringToHue(str) {
|
|
951
|
+
let hash = 0;
|
|
952
|
+
for (let i = 0; i < str.length; i++) hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
953
|
+
const hue = hash % 360;
|
|
954
|
+
return hue < 0 ? hue + 360 : hue;
|
|
955
|
+
}
|
|
956
|
+
function getTagBgColor(text) {
|
|
957
|
+
const hue = stringToHue(text);
|
|
958
|
+
const sat = 70 + hue % 21;
|
|
959
|
+
const light = 40 + hue % 31;
|
|
960
|
+
return `hsla(${hue}, ${sat > 30 ? sat - 30 : 0}%, ${light < 80 ? light + 20 : 100}%, 0.7)`;
|
|
961
|
+
}
|
|
962
|
+
//#endregion
|
|
963
|
+
//#region src/nodes/TagNode.ts
|
|
964
|
+
var tagClassName = `${semanticClassNames.tag} ${sharedStyles.tag}`;
|
|
965
|
+
var TagNode = class TagNode extends TextNode {
|
|
966
|
+
static getType() {
|
|
967
|
+
return "tag";
|
|
968
|
+
}
|
|
969
|
+
static clone(node) {
|
|
970
|
+
return new TagNode(node.__text, node.__key);
|
|
971
|
+
}
|
|
972
|
+
static importDOM() {
|
|
973
|
+
return { span: () => ({
|
|
974
|
+
conversion: (domNode) => {
|
|
975
|
+
if (!(domNode instanceof HTMLElement)) return null;
|
|
976
|
+
if (!domNode.classList.contains(semanticClassNames.tag)) return null;
|
|
977
|
+
return { node: $createTagNode(domNode.textContent ?? "") };
|
|
978
|
+
},
|
|
979
|
+
priority: 2
|
|
980
|
+
}) };
|
|
981
|
+
}
|
|
982
|
+
constructor(text, key) {
|
|
983
|
+
super(text, key);
|
|
984
|
+
}
|
|
985
|
+
createDOM(config) {
|
|
986
|
+
const element = super.createDOM(config);
|
|
987
|
+
element.classList.add(semanticClassNames.tag, sharedStyles.tag);
|
|
988
|
+
element.style.backgroundColor = getTagBgColor(this.getTextContent());
|
|
989
|
+
return element;
|
|
990
|
+
}
|
|
991
|
+
updateDOM(prevNode, dom, config) {
|
|
992
|
+
const updated = super.updateDOM(prevNode, dom, config);
|
|
993
|
+
dom.classList.add(semanticClassNames.tag, sharedStyles.tag);
|
|
994
|
+
if (prevNode.__text !== this.__text) dom.style.backgroundColor = getTagBgColor(this.__text);
|
|
995
|
+
return updated;
|
|
996
|
+
}
|
|
997
|
+
exportDOM(_editor) {
|
|
998
|
+
const element = document.createElement("span");
|
|
999
|
+
element.className = tagClassName;
|
|
1000
|
+
element.style.backgroundColor = getTagBgColor(this.getTextContent());
|
|
1001
|
+
element.textContent = this.getTextContent();
|
|
1002
|
+
return { element };
|
|
1003
|
+
}
|
|
1004
|
+
getText() {
|
|
1005
|
+
return this.getTextContent();
|
|
1006
|
+
}
|
|
1007
|
+
canInsertTextBefore() {
|
|
1008
|
+
return false;
|
|
1009
|
+
}
|
|
1010
|
+
canInsertTextAfter() {
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
isTextEntity() {
|
|
1014
|
+
return true;
|
|
1015
|
+
}
|
|
1016
|
+
static importJSON(serializedNode) {
|
|
1017
|
+
const node = $createTagNode(serializedNode.text ?? "");
|
|
1018
|
+
node.setFormat(serializedNode.format ?? 0);
|
|
1019
|
+
node.setDetail(serializedNode.detail ?? 0);
|
|
1020
|
+
node.setMode(serializedNode.mode ?? "normal");
|
|
1021
|
+
node.setStyle(serializedNode.style ?? "");
|
|
1022
|
+
return node;
|
|
1023
|
+
}
|
|
1024
|
+
exportJSON() {
|
|
1025
|
+
return {
|
|
1026
|
+
...super.exportJSON(),
|
|
1027
|
+
type: "tag",
|
|
1028
|
+
version: 1
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
_defineProperty(TagNode, "commandItems", [{
|
|
1033
|
+
title: "Tag",
|
|
1034
|
+
icon: createElement(Tag, { size: 20 }),
|
|
1035
|
+
description: "Insert a tag",
|
|
1036
|
+
keywords: [
|
|
1037
|
+
"tag",
|
|
1038
|
+
"label",
|
|
1039
|
+
"badge"
|
|
1040
|
+
],
|
|
1041
|
+
section: "INLINE",
|
|
1042
|
+
placement: ["slash", "toolbar"],
|
|
1043
|
+
group: "insert",
|
|
1044
|
+
onSelect: (editor, queryString) => {
|
|
1045
|
+
editor.update(() => {
|
|
1046
|
+
$insertNodes([$createTagNode(queryString || "tag")]);
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
}]);
|
|
1050
|
+
function $createTagNode(text) {
|
|
1051
|
+
return new TagNode(text);
|
|
1052
|
+
}
|
|
1053
|
+
function $isTagNode(node) {
|
|
1054
|
+
return node instanceof TagNode;
|
|
1055
|
+
}
|
|
1056
|
+
//#endregion
|
|
1057
|
+
//#region src/styles/theme.ts
|
|
1058
|
+
var shared = (key) => `${semanticClassNames[key]} ${sharedStyles[key]}`;
|
|
1059
|
+
var editorTheme = {
|
|
1060
|
+
text: {
|
|
1061
|
+
bold: shared("textBold"),
|
|
1062
|
+
italic: shared("textItalic"),
|
|
1063
|
+
underline: shared("textUnderline"),
|
|
1064
|
+
strikethrough: shared("textStrikethrough"),
|
|
1065
|
+
superscript: shared("textSuperscript"),
|
|
1066
|
+
subscript: shared("textSubscript"),
|
|
1067
|
+
code: shared("textCode"),
|
|
1068
|
+
highlight: shared("textHighlight")
|
|
1069
|
+
},
|
|
1070
|
+
heading: {
|
|
1071
|
+
h1: shared("headingH1"),
|
|
1072
|
+
h2: shared("headingH2"),
|
|
1073
|
+
h3: shared("headingH3"),
|
|
1074
|
+
h4: shared("headingH4"),
|
|
1075
|
+
h5: shared("headingH5"),
|
|
1076
|
+
h6: shared("headingH6")
|
|
1077
|
+
},
|
|
1078
|
+
list: {
|
|
1079
|
+
ol: shared("listOl"),
|
|
1080
|
+
ul: shared("listUl"),
|
|
1081
|
+
listitem: shared("listItem"),
|
|
1082
|
+
listitemChecked: shared("listItemChecked"),
|
|
1083
|
+
listitemUnchecked: shared("listItemUnchecked"),
|
|
1084
|
+
checklist: shared("checklist"),
|
|
1085
|
+
nested: { listitem: shared("listNestedItem") }
|
|
1086
|
+
},
|
|
1087
|
+
quote: shared("quote"),
|
|
1088
|
+
link: shared("link"),
|
|
1089
|
+
paragraph: shared("paragraph"),
|
|
1090
|
+
code: "rich-code-block",
|
|
1091
|
+
table: shared("table"),
|
|
1092
|
+
tableCell: shared("tableCell"),
|
|
1093
|
+
tableCellHeader: shared("tableCellHeader"),
|
|
1094
|
+
tableScrollableWrapper: shared("tableScrollableWrapper"),
|
|
1095
|
+
/** Used by @lexical/extension HorizontalRuleNode */
|
|
1096
|
+
hr: shared("hr")
|
|
1097
|
+
};
|
|
1098
|
+
//#endregion
|
|
1099
|
+
export { AlertQuoteNode as A, ImageNode as C, $isAlertQuoteNode as D, FootnoteNode as E, useNestedContentRenderer as F, useOptionalNestedContentRenderer as I, extractTextContent as M, AlertRenderer as N, ALERT_LABELS as O, NestedContentRendererProvider as P, $isImageNode as S, $createFootnoteNode as T, KaTeXInlineNode as _, getTagBgColor as a, KaTeXBlockNode as b, SpoilerNode as c, MermaidNode as d, $createMentionNode as f, $isKaTeXInlineNode as g, $createKaTeXInlineNode as h, TagNode as i, _defineProperty as j, ALERT_TYPES as k, $createMermaidNode as l, MentionNode as m, $createTagNode as n, $createSpoilerNode as o, $isMentionNode as p, $isTagNode as r, $isSpoilerNode as s, editorTheme as t, $isMermaidNode as u, $createKaTeXBlockNode as v, OPEN_IMAGE_UPLOAD_DIALOG_COMMAND as w, $createImageNode as x, $isKaTeXBlockNode as y };
|