@meowdown/react 0.82.3 → 0.83.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/index.js +110 -102
- package/dist/pele-chunk-Sqn5D2fk.js +30 -0
- package/dist/style.css +9 -0
- package/package.json +5 -4
- package/dist/beautiful-mermaid-chunk-Cc6FHgAa.js +0 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c } from "react/compiler-runtime";
|
|
2
2
|
import { clsx } from "clsx/lite";
|
|
3
|
-
import { Fragment, ViewTransition, cloneElement, createContext, createElement, memo, startTransition, use, useDeferredValue, useEffect, useImperativeHandle, useLayoutEffect, useReducer, useRef, useState } from "react";
|
|
3
|
+
import { Fragment, ViewTransition, cloneElement, createContext, createElement, memo, startTransition, use, useDeferredValue, useEffect, useId, useImperativeHandle, useLayoutEffect, useReducer, useRef, useState } from "react";
|
|
4
4
|
import { buildFileMarkdown, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defaultResolveXPost, defaultResolveYouTubeVideo, defineCodeBlockPreviewPlugin, defineEditorExtension, defineLinkEditKeymap, defineLinkHoverHandler, definePendingReplacementHandler, defineSearchStatusHandler, defineVirtualCaret, defineWikilinkHoverHandler, dismissLinkHover, docToMarkdown, docToParagraphMarkdown, formatFileSize, getCodeTokens, getFileKind, getLinkText, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunksWithContext, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, loadKaTeX, markdownToDoc, normalizeHref, paragraphMarkdownToDoc, parsePostEmbedSnapshot, renderMathInto, updateEditorConfig } from "@meowdown/core";
|
|
5
5
|
import { clamp } from "@ocavue/utils";
|
|
6
6
|
import { canUseRegexLookbehind, createEditor, defineDocChangeHandler, defineUpdateHandler, isTextSelection, union } from "@prosekit/core";
|
|
@@ -24,34 +24,30 @@ import { Mark } from "@prosekit/pm/model";
|
|
|
24
24
|
import { BOOLEAN, OVERLOADED_BOOLEAN, getPropertyInfo, possibleStandardNames } from "react-property";
|
|
25
25
|
import { PreviewCard } from "@base-ui/react/preview-card";
|
|
26
26
|
|
|
27
|
-
// src/hooks/use-
|
|
28
|
-
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
34
|
-
return beautifulMermaidPromise;
|
|
35
|
-
}
|
|
36
|
-
function useBeautifulMermaid(enabled) {
|
|
27
|
+
// src/hooks/use-katex.ts
|
|
28
|
+
/**
|
|
29
|
+
* The lazily loaded KaTeX render function, or `undefined` while it loads (or when
|
|
30
|
+
* `enabled` is false, so a document without math never loads it).
|
|
31
|
+
*/
|
|
32
|
+
function useKaTeX(enabled) {
|
|
37
33
|
const $ = c(4);
|
|
38
|
-
const [
|
|
34
|
+
const [katex, setKaTeX] = useState(void 0);
|
|
39
35
|
let t0;
|
|
40
36
|
let t1;
|
|
41
|
-
if ($[0] !== enabled || $[1] !==
|
|
37
|
+
if ($[0] !== enabled || $[1] !== katex) {
|
|
42
38
|
t0 = () => {
|
|
43
|
-
if (!enabled ||
|
|
39
|
+
if (!enabled || katex) return;
|
|
44
40
|
let cancelled = false;
|
|
45
|
-
|
|
46
|
-
if (!cancelled)
|
|
41
|
+
loadKaTeX().then((render) => {
|
|
42
|
+
if (!cancelled) setKaTeX(() => render);
|
|
47
43
|
});
|
|
48
44
|
return () => {
|
|
49
45
|
cancelled = true;
|
|
50
46
|
};
|
|
51
47
|
};
|
|
52
|
-
t1 = [enabled,
|
|
48
|
+
t1 = [enabled, katex];
|
|
53
49
|
$[0] = enabled;
|
|
54
|
-
$[1] =
|
|
50
|
+
$[1] = katex;
|
|
55
51
|
$[2] = t0;
|
|
56
52
|
$[3] = t1;
|
|
57
53
|
} else {
|
|
@@ -59,33 +55,37 @@ function useBeautifulMermaid(enabled) {
|
|
|
59
55
|
t1 = $[3];
|
|
60
56
|
}
|
|
61
57
|
useEffect(t0, t1);
|
|
62
|
-
return
|
|
58
|
+
return katex;
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
// src/hooks/use-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
// src/hooks/use-pele.ts
|
|
62
|
+
let pelePromise;
|
|
63
|
+
function loadPele() {
|
|
64
|
+
pelePromise ??= import("./pele-chunk-Sqn5D2fk.js").then((module) => module.renderMermaid).catch((error) => {
|
|
65
|
+
console.error("[meowdown] Failed to load pele.", error);
|
|
66
|
+
throw error;
|
|
67
|
+
});
|
|
68
|
+
return pelePromise;
|
|
69
|
+
}
|
|
70
|
+
function usePele(enabled) {
|
|
71
71
|
const $ = c(4);
|
|
72
|
-
const [
|
|
72
|
+
const [renderer, setRenderer] = useState(void 0);
|
|
73
73
|
let t0;
|
|
74
74
|
let t1;
|
|
75
|
-
if ($[0] !== enabled || $[1] !==
|
|
75
|
+
if ($[0] !== enabled || $[1] !== renderer) {
|
|
76
76
|
t0 = () => {
|
|
77
|
-
if (!enabled ||
|
|
77
|
+
if (!enabled || renderer) return;
|
|
78
78
|
let cancelled = false;
|
|
79
|
-
|
|
80
|
-
if (!cancelled)
|
|
79
|
+
loadPele().then((loadedRenderer) => {
|
|
80
|
+
if (!cancelled) setRenderer(() => loadedRenderer);
|
|
81
81
|
});
|
|
82
82
|
return () => {
|
|
83
83
|
cancelled = true;
|
|
84
84
|
};
|
|
85
85
|
};
|
|
86
|
-
t1 = [enabled,
|
|
86
|
+
t1 = [enabled, renderer];
|
|
87
87
|
$[0] = enabled;
|
|
88
|
-
$[1] =
|
|
88
|
+
$[1] = renderer;
|
|
89
89
|
$[2] = t0;
|
|
90
90
|
$[3] = t1;
|
|
91
91
|
} else {
|
|
@@ -93,7 +93,7 @@ function useKaTeX(enabled) {
|
|
|
93
93
|
t1 = $[3];
|
|
94
94
|
}
|
|
95
95
|
useEffect(t0, t1);
|
|
96
|
-
return
|
|
96
|
+
return renderer;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// src/utils/non-prose-props.ts
|
|
@@ -278,99 +278,107 @@ function MathRender(props) {
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
// src/components/mermaid-render.tsx
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
muted: "var(--meowdown-mermaid-muted)",
|
|
287
|
-
surface: "var(--meowdown-mermaid-surface)",
|
|
288
|
-
border: "var(--meowdown-mermaid-border)",
|
|
289
|
-
transparent: true,
|
|
290
|
-
interactive: false
|
|
281
|
+
const PELE_OPTIONS = {
|
|
282
|
+
links: false,
|
|
283
|
+
images: false,
|
|
284
|
+
responsive: false,
|
|
285
|
+
autoDirection: false
|
|
291
286
|
};
|
|
292
|
-
function
|
|
287
|
+
function getMermaidOutput(renderer, source, idPrefix) {
|
|
293
288
|
try {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return { element };
|
|
289
|
+
return { element: renderer(source, {
|
|
290
|
+
...PELE_OPTIONS,
|
|
291
|
+
idPrefix
|
|
292
|
+
}) };
|
|
299
293
|
} catch (error) {
|
|
300
294
|
return { error: error instanceof Error ? error.message : String(error) };
|
|
301
295
|
}
|
|
302
296
|
}
|
|
303
297
|
function MermaidRender(props) {
|
|
304
|
-
const $ = c(
|
|
298
|
+
const $ = c(22);
|
|
305
299
|
const { renderer, source, className, onMouseDown } = props;
|
|
306
|
-
|
|
307
|
-
if ($[0] !== renderer || $[1] !== source) {
|
|
308
|
-
t0 = renderMermaid(renderer, source);
|
|
309
|
-
$[0] = renderer;
|
|
310
|
-
$[1] = source;
|
|
311
|
-
$[2] = t0;
|
|
312
|
-
} else t0 = $[2];
|
|
313
|
-
const output = t0;
|
|
314
|
-
const ref = useRef(null);
|
|
300
|
+
const t0 = useId();
|
|
315
301
|
let t1;
|
|
316
|
-
if ($[
|
|
317
|
-
|
|
302
|
+
if ($[0] !== t0) {
|
|
303
|
+
let t2;
|
|
304
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
305
|
+
t2 = /[^\w-]/g;
|
|
306
|
+
$[2] = t2;
|
|
307
|
+
} else t2 = $[2];
|
|
308
|
+
t1 = t0.replaceAll(t2, "");
|
|
309
|
+
$[0] = t0;
|
|
310
|
+
$[1] = t1;
|
|
311
|
+
} else t1 = $[1];
|
|
312
|
+
const idPrefix = `meowdown-mermaid-${t1}`;
|
|
313
|
+
let t2;
|
|
314
|
+
if ($[3] !== idPrefix || $[4] !== renderer || $[5] !== source) {
|
|
315
|
+
t2 = getMermaidOutput(renderer, source, idPrefix);
|
|
316
|
+
$[3] = idPrefix;
|
|
317
|
+
$[4] = renderer;
|
|
318
|
+
$[5] = source;
|
|
319
|
+
$[6] = t2;
|
|
320
|
+
} else t2 = $[6];
|
|
321
|
+
const output = t2;
|
|
322
|
+
const ref = useRef(null);
|
|
323
|
+
let t3;
|
|
324
|
+
if ($[7] !== output.element) {
|
|
325
|
+
t3 = () => {
|
|
318
326
|
const host = ref.current;
|
|
319
327
|
if (!host || !output.element) return;
|
|
320
328
|
host.replaceChildren(window.document.importNode(output.element, true));
|
|
321
329
|
};
|
|
322
|
-
$[
|
|
323
|
-
$[
|
|
324
|
-
} else
|
|
325
|
-
let
|
|
326
|
-
if ($[
|
|
327
|
-
|
|
328
|
-
$[
|
|
329
|
-
$[
|
|
330
|
-
} else
|
|
331
|
-
useLayoutEffect(
|
|
330
|
+
$[7] = output.element;
|
|
331
|
+
$[8] = t3;
|
|
332
|
+
} else t3 = $[8];
|
|
333
|
+
let t4;
|
|
334
|
+
if ($[9] !== output) {
|
|
335
|
+
t4 = [output];
|
|
336
|
+
$[9] = output;
|
|
337
|
+
$[10] = t4;
|
|
338
|
+
} else t4 = $[10];
|
|
339
|
+
useLayoutEffect(t3, t4);
|
|
332
340
|
if (output.error) {
|
|
333
|
-
const
|
|
334
|
-
const
|
|
335
|
-
let
|
|
336
|
-
if ($[
|
|
337
|
-
|
|
341
|
+
const t5 = props["data-testid"];
|
|
342
|
+
const t6 = props["data-scroll-x"];
|
|
343
|
+
let t7;
|
|
344
|
+
if ($[11] !== className || $[12] !== onMouseDown || $[13] !== output.error || $[14] !== t5 || $[15] !== t6) {
|
|
345
|
+
t7 = /* @__PURE__ */ jsx("span", {
|
|
338
346
|
className,
|
|
339
347
|
contentEditable: false,
|
|
340
348
|
"data-error": true,
|
|
341
|
-
"data-testid":
|
|
342
|
-
"data-scroll-x":
|
|
349
|
+
"data-testid": t5,
|
|
350
|
+
"data-scroll-x": t6,
|
|
343
351
|
onMouseDown,
|
|
344
352
|
children: output.error
|
|
345
353
|
}, "error");
|
|
346
|
-
$[
|
|
347
|
-
$[
|
|
348
|
-
$[
|
|
349
|
-
$[
|
|
350
|
-
$[
|
|
351
|
-
$[
|
|
352
|
-
} else
|
|
353
|
-
return
|
|
354
|
+
$[11] = className;
|
|
355
|
+
$[12] = onMouseDown;
|
|
356
|
+
$[13] = output.error;
|
|
357
|
+
$[14] = t5;
|
|
358
|
+
$[15] = t6;
|
|
359
|
+
$[16] = t7;
|
|
360
|
+
} else t7 = $[16];
|
|
361
|
+
return t7;
|
|
354
362
|
}
|
|
355
|
-
const
|
|
356
|
-
const
|
|
357
|
-
let
|
|
358
|
-
if ($[
|
|
359
|
-
|
|
363
|
+
const t5 = props["data-testid"];
|
|
364
|
+
const t6 = props["data-scroll-x"];
|
|
365
|
+
let t7;
|
|
366
|
+
if ($[17] !== className || $[18] !== onMouseDown || $[19] !== t5 || $[20] !== t6) {
|
|
367
|
+
t7 = /* @__PURE__ */ jsx("span", {
|
|
360
368
|
ref,
|
|
361
369
|
className,
|
|
362
370
|
contentEditable: false,
|
|
363
|
-
"data-testid":
|
|
364
|
-
"data-scroll-x":
|
|
371
|
+
"data-testid": t5,
|
|
372
|
+
"data-scroll-x": t6,
|
|
365
373
|
onMouseDown
|
|
366
374
|
}, "svg");
|
|
367
|
-
$[
|
|
368
|
-
$[
|
|
369
|
-
$[
|
|
370
|
-
$[
|
|
371
|
-
$[
|
|
372
|
-
} else
|
|
373
|
-
return
|
|
375
|
+
$[17] = className;
|
|
376
|
+
$[18] = onMouseDown;
|
|
377
|
+
$[19] = t5;
|
|
378
|
+
$[20] = t6;
|
|
379
|
+
$[21] = t7;
|
|
380
|
+
} else t7 = $[21];
|
|
381
|
+
return t7;
|
|
374
382
|
}
|
|
375
383
|
|
|
376
384
|
// src/components/code-block-view.tsx
|
|
@@ -389,7 +397,7 @@ function CodeBlockView(props) {
|
|
|
389
397
|
} else t0 = $[1];
|
|
390
398
|
const caretInside = t0;
|
|
391
399
|
const katex = useKaTeX(isMath);
|
|
392
|
-
const mermaid =
|
|
400
|
+
const mermaid = usePele(isMermaid);
|
|
393
401
|
const showMathPreview = isMath && katex != null;
|
|
394
402
|
const showMermaidPreview = isMermaid && mermaid != null;
|
|
395
403
|
const showPreview = showMathPreview || showMermaidPreview;
|
|
@@ -5322,7 +5330,7 @@ function MathCodeBlock(t0) {
|
|
|
5322
5330
|
function MermaidCodeBlock(t0) {
|
|
5323
5331
|
const $ = c(5);
|
|
5324
5332
|
const { code } = t0;
|
|
5325
|
-
const renderer =
|
|
5333
|
+
const renderer = usePele(true);
|
|
5326
5334
|
if (!renderer || code.trim() === "") {
|
|
5327
5335
|
let t1;
|
|
5328
5336
|
if ($[0] !== code) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { render } from "pele";
|
|
2
|
+
import DOMPurify from "dompurify";
|
|
3
|
+
|
|
4
|
+
// src/utils/sanitize-svg.ts
|
|
5
|
+
/**
|
|
6
|
+
* Parses an SVG string and removes anything that can run script. Returns
|
|
7
|
+
* `undefined` when no single `<svg>` root remains.
|
|
8
|
+
*/
|
|
9
|
+
function sanitizeSvg(svg) {
|
|
10
|
+
const fragment = DOMPurify.sanitize(svg, {
|
|
11
|
+
USE_PROFILES: {
|
|
12
|
+
svg: true,
|
|
13
|
+
svgFilters: true
|
|
14
|
+
},
|
|
15
|
+
ADD_ATTR: ["role"],
|
|
16
|
+
RETURN_DOM_FRAGMENT: true
|
|
17
|
+
});
|
|
18
|
+
const element = fragment.firstElementChild;
|
|
19
|
+
if (fragment.childElementCount !== 1 || element?.localName !== "svg") return;
|
|
20
|
+
return element;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/hooks/pele-chunk.ts
|
|
24
|
+
function renderMermaid(source, options) {
|
|
25
|
+
const element = sanitizeSvg(render(source, options).svg);
|
|
26
|
+
if (!element) throw new Error("Invalid SVG output.");
|
|
27
|
+
return element;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { renderMermaid };
|
package/dist/style.css
CHANGED
|
@@ -27,6 +27,15 @@
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.meow_MermaidPreview_D3j_9q {
|
|
30
|
+
--pele-bg: var(--meowdown-mermaid-bg);
|
|
31
|
+
--pele-fg: var(--meowdown-mermaid-fg);
|
|
32
|
+
--pele-muted: var(--meowdown-mermaid-muted);
|
|
33
|
+
--pele-line: var(--meowdown-mermaid-line);
|
|
34
|
+
--pele-surface: var(--meowdown-mermaid-surface);
|
|
35
|
+
--pele-surface-alt: var(--meowdown-mermaid-surface-alt);
|
|
36
|
+
--pele-border: var(--meowdown-mermaid-border);
|
|
37
|
+
--pele-accent: var(--meowdown-mermaid-accent);
|
|
38
|
+
--pele-critical: var(--meowdown-mermaid-critical);
|
|
30
39
|
text-align: initial;
|
|
31
40
|
|
|
32
41
|
&[data-error] {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meowdown/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.83.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -25,16 +25,17 @@
|
|
|
25
25
|
"@meowdown/core": "0.83.0",
|
|
26
26
|
"@meowdown/embed": "0.3.1",
|
|
27
27
|
"@meowdown/markdown": "0.78.0",
|
|
28
|
-
"@ocavue/utils": "^1.
|
|
28
|
+
"@ocavue/utils": "^1.11.0",
|
|
29
29
|
"@post-embed/types": "^0.5.0",
|
|
30
30
|
"@prosekit/core": "^0.13.4",
|
|
31
31
|
"@prosekit/pm": "^0.1.21",
|
|
32
32
|
"@prosekit/react": "^0.9.0",
|
|
33
33
|
"@prosekit/web": "^0.10.0",
|
|
34
|
-
"beautiful-mermaid": "^1.1.3",
|
|
35
34
|
"clsx": "^2.1.1",
|
|
35
|
+
"dompurify": "^3.4.17",
|
|
36
36
|
"github-slugger": "^2.0.0",
|
|
37
37
|
"lucide-react": "^1.47.0",
|
|
38
|
+
"pele": "^1.13.0",
|
|
38
39
|
"react-property": "^2.0.2"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
}
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
|
-
"@css-modules-kit/codegen": "^1.4.
|
|
54
|
+
"@css-modules-kit/codegen": "^1.4.1",
|
|
54
55
|
"@meowdown/vitest": "0.0.0",
|
|
55
56
|
"@ocavue/tsconfig": "^0.7.1",
|
|
56
57
|
"@tsdown/css": "^0.23.3",
|