vue-stream-markdown 0.0.0-alpha.0 → 0.1.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/README.md +18 -19
- package/dist/{button-D8xx1WIP.js → button-DRLfKbvc.js} +1 -1
- package/dist/button-DYIERZf1.js +5 -0
- package/dist/{code-CP6mPwkq.js → code-D5-TPyJ2.js} +7 -7
- package/dist/code-block-Cs17aZ52.js +9 -0
- package/dist/{code-block-C4D_QNTq.js → code-block-fsdBN3mX.js} +5 -5
- package/dist/{composables-qhB1h_ed.js → composables-5Y9QWb9D.js} +97 -13
- package/dist/dropdown-BegRJmej.js +5 -0
- package/dist/error-component-BkdZ6n2L.js +4 -0
- package/dist/{error-component-CzarUjhh.js → error-component-DftqHZwH.js} +1 -1
- package/dist/{image-heJSlrNv.js → image-dNQ1WKcM.js} +53 -49
- package/dist/index.d.ts +45 -33
- package/dist/index.js +23 -324
- package/dist/{inline-math-B4XO1wMP.js → inline-math-D8LY9Xgq.js} +2 -2
- package/dist/{link-DOtoFtxu.js → link-Dkfv0bTE.js} +2 -2
- package/dist/{math-Byka28HI.js → math-G8p5HNSV.js} +2 -2
- package/dist/{mermaid-X0AFRzfF.js → mermaid-BAFHxaTS.js} +12 -8
- package/dist/{previewers-Drlf7IQF.js → previewers-CZxK6T54.js} +1 -1
- package/dist/{segmented-BEtO1eyl.js → segmented-CpwUFPie.js} +1 -1
- package/dist/segmented-DQFlS2_3.js +6 -0
- package/dist/{shiki-vToM7Pz1.js → shiki-CxPfBPEr.js} +1 -1
- package/dist/{table-DjkiVd9L.js → table-BSGtENN1.js} +9 -4
- package/dist/{tooltip-RiXixMIt.js → tooltip-CTUn3Ask.js} +1 -1
- package/dist/tooltip-TCy0JVGe.js +4 -0
- package/dist/{zoom-container-BfUO3Ocp.js → zoom-container-BR9gRA9_.js} +2 -2
- package/dist/zoom-container-qe4wO3zY.js +6 -0
- package/package.json +13 -9
- package/dist/button-BClRCjnc.js +0 -5
- package/dist/code-block-Dzw63Lki.js +0 -9
- package/dist/dropdown-Ca_PKF_d.js +0 -5
- package/dist/error-component-CLEJmPmM.js +0 -4
- package/dist/segmented-CWoQcX-H.js +0 -6
- package/dist/tooltip-Ac_2x9ps.js +0 -4
- package/dist/zoom-container-BDEP09K9.js +0 -6
package/README.md
CHANGED
|
@@ -5,40 +5,38 @@
|
|
|
5
5
|
|
|
6
6
|
A markdown renderer specially optimized for streaming scenarios, inspired by [streamdown](https://streamdown.ai/). Designed to achieve smoother streaming rendering through syntax inference and highly customizable rendering elements.
|
|
7
7
|
|
|
8
|
+
```sh
|
|
9
|
+
pnpm add vue-stream-markdown
|
|
10
|
+
```
|
|
11
|
+
|
|
8
12
|
<br>
|
|
9
13
|
|
|
10
14
|
<p align="center">
|
|
11
|
-
<a href="
|
|
12
|
-
<a href="
|
|
15
|
+
<a href="https://docs-vue-stream-markdown.netlify.app/">📚 Documentation</a> |
|
|
16
|
+
<a href="https://play-vue-stream-markdown.netlify.app/">🤹♂️ Playground</a>
|
|
13
17
|
</p>
|
|
14
18
|
|
|
15
19
|
<br>
|
|
16
20
|
|
|
17
|
-
```sh
|
|
18
|
-
pnpm add vue-stream-markdown
|
|
19
|
-
```
|
|
20
|
-
|
|
21
21
|
<p align='center'>
|
|
22
22
|
<img src='./assets/screenshot.png' />
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
## Features
|
|
26
26
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
- 🛡️ **Content hardening & security** - Built-in protection against malicious Markdown with URL validation and protocol blocking
|
|
37
|
-
- 🔒 **TypeScript type safety** - Comprehensive type definitions with full IntelliSense support
|
|
27
|
+
- **Streaming-optimized rendering** - Incomplete node completion with loading states for images, tables, and code blocks to prevent visual jitter
|
|
28
|
+
- **Incremental rendering** - Leverages [Shiki](https://shiki.style/)'s `codeToTokens` API for token-level updates, reducing DOM recreation overhead
|
|
29
|
+
- **Progressive Mermaid rendering** - Throttled, streaming-friendly diagram rendering with loading states
|
|
30
|
+
- **Streaming LaTeX rendering** - Progressive math equation rendering with KaTeX support
|
|
31
|
+
- **Interactive controls** - Copy and download buttons for images, tables, and code blocks
|
|
32
|
+
- **Fully customizable** - Replace any AST node with your own Vue components
|
|
33
|
+
- **Theme-aware scoped styles** - Scoped styles under `.stream-markdown` with semantic `data-stream-markdown` attributes, following [shadcn/ui](https://ui.shadcn.com/) design system
|
|
34
|
+
- **Beautiful built-in typography** - No atomic CSS required (Tailwind/UnoCSS), self-contained styles
|
|
35
|
+
- **Content hardening & security** - Built-in protection against malicious Markdown with URL validation and protocol blocking
|
|
38
36
|
|
|
39
37
|
## Usage
|
|
40
38
|
|
|
41
|
-
For detailed usage and API documentation, please refer to the [Documentation](
|
|
39
|
+
For detailed usage and API documentation, please refer to the [Documentation](https://docs-vue-stream-markdown.netlify.app/).
|
|
42
40
|
|
|
43
41
|
```vue
|
|
44
42
|
<script setup lang="ts">
|
|
@@ -57,7 +55,7 @@ const content = ref('# Hello World\n\nThis is a markdown content.')
|
|
|
57
55
|
|
|
58
56
|
## Credit
|
|
59
57
|
|
|
60
|
-
This project is inspired by [streamdown](https://streamdown.ai/) and even uses
|
|
58
|
+
This project is inspired by [streamdown](https://streamdown.ai/) and even uses some source code from it.
|
|
61
59
|
|
|
62
60
|
This project also uses and benefits from:
|
|
63
61
|
|
|
@@ -65,6 +63,7 @@ This project also uses and benefits from:
|
|
|
65
63
|
- [Shiki](https://shiki.style/) - Beautiful syntax highlighting
|
|
66
64
|
- [Mermaid](https://mermaid.js.org/) - Diagramming and charting tool
|
|
67
65
|
- [KaTeX](https://katex.org/) - Fast math typesetting library for the web
|
|
66
|
+
- [Remend](https://github.com/vercel/streamdown/tree/main/packages/remend) - Intelligently parses and styles incomplete Markdown blocks
|
|
68
67
|
|
|
69
68
|
## Troubleshooting
|
|
70
69
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as tooltip_default } from "./tooltip-
|
|
1
|
+
import { t as tooltip_default } from "./tooltip-CTUn3Ask.js";
|
|
2
2
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, h, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, withCtx } from "vue";
|
|
3
3
|
|
|
4
4
|
//#region src/components/dropdown.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./previewers-
|
|
2
|
-
import {
|
|
3
|
-
import "./tooltip-
|
|
4
|
-
import "./button-
|
|
1
|
+
import "./previewers-CZxK6T54.js";
|
|
2
|
+
import { i as useShiki } from "./composables-5Y9QWb9D.js";
|
|
3
|
+
import "./tooltip-CTUn3Ask.js";
|
|
4
|
+
import "./button-DRLfKbvc.js";
|
|
5
5
|
import "./modal-CuQR21UD.js";
|
|
6
|
-
import { t as code_block_default } from "./code-block-
|
|
7
|
-
import "./segmented-
|
|
6
|
+
import { t as code_block_default } from "./code-block-fsdBN3mX.js";
|
|
7
|
+
import "./segmented-CpwUFPie.js";
|
|
8
8
|
import { computed, createBlock, createCommentVNode, defineAsyncComponent, defineComponent, mergeProps, normalizeProps, openBlock, resolveDynamicComponent, withCtx } from "vue";
|
|
9
9
|
|
|
10
10
|
//#region src/components/renderers/code/index.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -83,7 +83,7 @@ var index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
|
|
|
83
83
|
const { installed: hasShiki } = useShiki();
|
|
84
84
|
const components = {
|
|
85
85
|
vanilla: defineAsyncComponent(() => import("./vanilla-CA9QO96X.js")),
|
|
86
|
-
shiki: defineAsyncComponent(() => import("./shiki-
|
|
86
|
+
shiki: defineAsyncComponent(() => import("./shiki-CxPfBPEr.js"))
|
|
87
87
|
};
|
|
88
88
|
const component = computed(() => {
|
|
89
89
|
if (hasShiki.value) return components.shiki;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "./previewers-CZxK6T54.js";
|
|
2
|
+
import "./composables-5Y9QWb9D.js";
|
|
3
|
+
import "./tooltip-CTUn3Ask.js";
|
|
4
|
+
import "./button-DRLfKbvc.js";
|
|
5
|
+
import "./modal-CuQR21UD.js";
|
|
6
|
+
import { t as code_block_default } from "./code-block-fsdBN3mX.js";
|
|
7
|
+
import "./segmented-CpwUFPie.js";
|
|
8
|
+
|
|
9
|
+
export { code_block_default as default };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CODE_PREVIEWERS } from "./previewers-
|
|
2
|
-
import {
|
|
3
|
-
import { t as button_default } from "./button-
|
|
1
|
+
import { t as CODE_PREVIEWERS } from "./previewers-CZxK6T54.js";
|
|
2
|
+
import { B as useContext, I as LANGUAGE_ALIAS, L as LANGUAGE_EXTENSIONS, M as ICONS, O as save, R as LANGUAGE_ICONS, a as useMermaid, u as useI18n, z as useControls } from "./composables-5Y9QWb9D.js";
|
|
3
|
+
import { t as button_default } from "./button-DRLfKbvc.js";
|
|
4
4
|
import { t as modal_default } from "./modal-CuQR21UD.js";
|
|
5
|
-
import { t as segmented_default } from "./segmented-
|
|
5
|
+
import { t as segmented_default } from "./segmented-CpwUFPie.js";
|
|
6
6
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineAsyncComponent, defineComponent, mergeProps, normalizeClass, normalizeProps, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, toRefs, unref, useModel, vShow, watch, withCtx, withDirectives } from "vue";
|
|
7
7
|
import { useClipboard } from "@vueuse/core";
|
|
8
8
|
|
|
@@ -208,7 +208,7 @@ var index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
|
|
|
208
208
|
const { t } = useI18n();
|
|
209
209
|
const { isControlEnabled } = useControls({ controls });
|
|
210
210
|
const { installed: hasMermaid } = useMermaid();
|
|
211
|
-
const CodeNode = defineAsyncComponent(() => import("./code-
|
|
211
|
+
const CodeNode = defineAsyncComponent(() => import("./code-D5-TPyJ2.js"));
|
|
212
212
|
const { onCopied } = useContext();
|
|
213
213
|
const { copy, copied } = useClipboard({ legacy: true });
|
|
214
214
|
const { saveMermaid } = useMermaid();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { computed, defineAsyncComponent, inject, provide, ref, unref, watch, watchEffect } from "vue";
|
|
1
|
+
import { computed, defineAsyncComponent, inject, onBeforeUnmount, provide, ref, toValue, unref, watch, watchEffect } from "vue";
|
|
2
|
+
import { useStyleTag } from "@vueuse/core";
|
|
2
3
|
import { setDefaultProps } from "vue-tippy";
|
|
3
4
|
import "tippy.js/dist/tippy.css";
|
|
4
5
|
import "tippy.js/themes/light.css";
|
|
@@ -38,22 +39,31 @@ function useContext() {
|
|
|
38
39
|
function useControls(options) {
|
|
39
40
|
const controls = computed(() => unref(options.controls) ?? true);
|
|
40
41
|
function isControlEnabled(key) {
|
|
42
|
+
try {
|
|
43
|
+
return getControlValue(key) !== false;
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function getControlValue(key) {
|
|
41
49
|
try {
|
|
42
50
|
const config = controls.value;
|
|
43
51
|
if (typeof config === "boolean") return config;
|
|
44
52
|
const path = key.split(".");
|
|
45
53
|
let current = config;
|
|
46
54
|
for (const part of path) {
|
|
47
|
-
if (current === void 0 || current === null || typeof current !== "object") return
|
|
55
|
+
if (current === void 0 || current === null || typeof current !== "object") return void 0;
|
|
48
56
|
current = current[part];
|
|
49
|
-
if (typeof current === "boolean") return current;
|
|
50
57
|
}
|
|
51
|
-
return current
|
|
58
|
+
return current;
|
|
52
59
|
} catch {
|
|
53
|
-
return
|
|
60
|
+
return;
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
|
-
return {
|
|
63
|
+
return {
|
|
64
|
+
isControlEnabled,
|
|
65
|
+
getControlValue
|
|
66
|
+
};
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
//#endregion
|
|
@@ -64,7 +74,6 @@ const LANGUAGE_ALIAS = {};
|
|
|
64
74
|
const LANGUAGE_EXTENSIONS = {
|
|
65
75
|
"1c-query": "1cq",
|
|
66
76
|
"1c": "1c",
|
|
67
|
-
"文言": "wy",
|
|
68
77
|
"abap": "abap",
|
|
69
78
|
"actionscript-3": "as",
|
|
70
79
|
"ada": "ada",
|
|
@@ -367,7 +376,8 @@ const LANGUAGE_EXTENSIONS = {
|
|
|
367
376
|
"yml": "yml",
|
|
368
377
|
"zenscript": "zs",
|
|
369
378
|
"zig": "zig",
|
|
370
|
-
"zsh": "zsh"
|
|
379
|
+
"zsh": "zsh",
|
|
380
|
+
"文言": "wy"
|
|
371
381
|
};
|
|
372
382
|
const LANGUAGE_ICONS = {
|
|
373
383
|
"adoc": defineAsyncComponent(() => import("./asciidoc-BabXBDAL.js")),
|
|
@@ -576,6 +586,42 @@ const ICONS = {
|
|
|
576
586
|
zoomOut: defineAsyncComponent(() => import("./zoomOut-qlzQyQli.js"))
|
|
577
587
|
};
|
|
578
588
|
|
|
589
|
+
//#endregion
|
|
590
|
+
//#region src/constants/theme.ts
|
|
591
|
+
const SHADCN_SCHEMAS = [
|
|
592
|
+
"background",
|
|
593
|
+
"foreground",
|
|
594
|
+
"card",
|
|
595
|
+
"card-foreground",
|
|
596
|
+
"popover",
|
|
597
|
+
"popover-foreground",
|
|
598
|
+
"primary",
|
|
599
|
+
"primary-foreground",
|
|
600
|
+
"secondary",
|
|
601
|
+
"secondary-foreground",
|
|
602
|
+
"muted",
|
|
603
|
+
"muted-foreground",
|
|
604
|
+
"accent",
|
|
605
|
+
"accent-foreground",
|
|
606
|
+
"destructive",
|
|
607
|
+
"border",
|
|
608
|
+
"input",
|
|
609
|
+
"ring",
|
|
610
|
+
"chart-1",
|
|
611
|
+
"chart-2",
|
|
612
|
+
"chart-3",
|
|
613
|
+
"chart-4",
|
|
614
|
+
"chart-5",
|
|
615
|
+
"sidebar",
|
|
616
|
+
"sidebar-foreground",
|
|
617
|
+
"sidebar-primary",
|
|
618
|
+
"sidebar-primary-foreground",
|
|
619
|
+
"sidebar-accent",
|
|
620
|
+
"sidebar-accent-foreground",
|
|
621
|
+
"sidebar-border",
|
|
622
|
+
"sidebar-ring"
|
|
623
|
+
];
|
|
624
|
+
|
|
579
625
|
//#endregion
|
|
580
626
|
//#region src/utils/harden.ts
|
|
581
627
|
const safeProtocols = new Set([
|
|
@@ -916,10 +962,6 @@ function useHardenSanitizers(options) {
|
|
|
916
962
|
};
|
|
917
963
|
}
|
|
918
964
|
|
|
919
|
-
//#endregion
|
|
920
|
-
//#region src/composables/use-hsl-theme.ts
|
|
921
|
-
function useHslTheme() {}
|
|
922
|
-
|
|
923
965
|
//#endregion
|
|
924
966
|
//#region src/locales/index.ts
|
|
925
967
|
const SUPPORT_LANGUAGES = ["en-US", "zh-CN"];
|
|
@@ -1434,6 +1476,48 @@ function useShiki(options) {
|
|
|
1434
1476
|
};
|
|
1435
1477
|
}
|
|
1436
1478
|
|
|
1479
|
+
//#endregion
|
|
1480
|
+
//#region src/composables/use-tailwind-v3-theme.ts
|
|
1481
|
+
const reg = /^(?:hsl|rgb|oklch|lab|lch)\(/;
|
|
1482
|
+
function useTailwindV3Theme(options) {
|
|
1483
|
+
const { id, css, load, unload, isLoaded } = useStyleTag("", {
|
|
1484
|
+
id: "stream-markdown-tailwind-v3-theme",
|
|
1485
|
+
immediate: false
|
|
1486
|
+
});
|
|
1487
|
+
const styleScope = computed(() => unref(options.styleScope) || ".stream-markdown");
|
|
1488
|
+
const element = computed(() => {
|
|
1489
|
+
return toValue(options.element) || (typeof window !== "undefined" ? document.body : void 0);
|
|
1490
|
+
});
|
|
1491
|
+
function generateCSS() {
|
|
1492
|
+
if (!element.value || typeof window === "undefined") return;
|
|
1493
|
+
const computedStyle = window.getComputedStyle(element.value);
|
|
1494
|
+
const cssVariables = [];
|
|
1495
|
+
for (const schema of SHADCN_SCHEMAS) {
|
|
1496
|
+
const name = `--${schema}`;
|
|
1497
|
+
const value = computedStyle.getPropertyValue(name).trim();
|
|
1498
|
+
if (value && !reg.test(value)) cssVariables.push(` ${name}: hsl(${value});`);
|
|
1499
|
+
}
|
|
1500
|
+
if (cssVariables.length > 0) {
|
|
1501
|
+
css.value = `${styleScope.value} {\n${cssVariables.join("\n")}\n}`;
|
|
1502
|
+
load();
|
|
1503
|
+
} else {
|
|
1504
|
+
css.value = "";
|
|
1505
|
+
unload();
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
watchEffect(generateCSS);
|
|
1509
|
+
onBeforeUnmount(unload);
|
|
1510
|
+
return {
|
|
1511
|
+
element,
|
|
1512
|
+
id,
|
|
1513
|
+
css,
|
|
1514
|
+
load,
|
|
1515
|
+
unload,
|
|
1516
|
+
isLoaded,
|
|
1517
|
+
generateCSS
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1437
1521
|
//#endregion
|
|
1438
1522
|
//#region src/composables/use-tippy.ts
|
|
1439
1523
|
function useTippy(options) {
|
|
@@ -1564,4 +1648,4 @@ function useZoom(options = {}) {
|
|
|
1564
1648
|
}
|
|
1565
1649
|
|
|
1566
1650
|
//#endregion
|
|
1567
|
-
export { transformUrl as A, findNodeParent as C, flow as D, hasShiki as E,
|
|
1651
|
+
export { transformUrl as A, useContext as B, findNodeParent as C, flow as D, hasShiki as E, DEFAULT_LIGHT_THEME as F, LANGUAGE_ALIAS as I, LANGUAGE_EXTENSIONS as L, ICONS as M, DEFAULT_HARDEN_OPTIONS as N, save as O, DEFAULT_DARK_THEME as P, LANGUAGE_ICONS as R, findLastLeafNode as S, hasMermaid as T, escapeMarkdownTableCell as _, useMermaid as a, tableDataToMarkdown as b, _defineProperty as c, SUPPORT_LANGUAGES as d, currentLocale as f, useHardenSanitizers as g, localesGlob as h, useShiki as i, SHADCN_SCHEMAS as j, svgToPngBlob as k, useKatex as l, localeMessages as m, useTippy as n, useMathRenderer as o, loadLocaleMessages as p, useTailwindV3Theme as r, throttle as s, useZoom as t, useI18n as u, extractTableDataFromElement as v, hasKatex as w, tableDataToTSV as x, tableDataToCSV as y, useControls as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { M as ICONS, u as useI18n } from "./composables-5Y9QWb9D.js";
|
|
2
2
|
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, openBlock, renderSlot, resolveDynamicComponent, toDisplayString } from "vue";
|
|
3
3
|
|
|
4
4
|
//#region src/components/error-component.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./tooltip-
|
|
3
|
-
import { t as button_default } from "./button-
|
|
4
|
-
import { t as error_component_default } from "./error-component-
|
|
1
|
+
import { M as ICONS, O as save, g as useHardenSanitizers, u as useI18n, z as useControls } from "./composables-5Y9QWb9D.js";
|
|
2
|
+
import "./tooltip-CTUn3Ask.js";
|
|
3
|
+
import { t as button_default } from "./button-DRLfKbvc.js";
|
|
4
|
+
import { t as error_component_default } from "./error-component-DftqHZwH.js";
|
|
5
5
|
import { t as spin_default } from "./spin-Ds5W7qC_.js";
|
|
6
6
|
import { Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeStyle, openBlock, ref, resolveDynamicComponent, toDisplayString, toRefs, unref, withCtx } from "vue";
|
|
7
7
|
|
|
@@ -97,7 +97,7 @@ var image_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
|
|
|
97
97
|
var _props$imageOptions;
|
|
98
98
|
return ((_props$imageOptions = props.imageOptions) === null || _props$imageOptions === void 0 ? void 0 : _props$imageOptions.fallback) ?? "";
|
|
99
99
|
});
|
|
100
|
-
const imageSrc = computed(() =>
|
|
100
|
+
const imageSrc = computed(() => fallbackAttempted.value && fallback.value ? fallback.value : props.node.url);
|
|
101
101
|
const { transformedUrl, isHardenUrl } = useHardenSanitizers({
|
|
102
102
|
url: imageSrc,
|
|
103
103
|
hardenOptions,
|
|
@@ -158,51 +158,55 @@ var image_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
|
|
|
158
158
|
style: normalizeStyle({ width: isLoading.value || !imageLoaded.value ? "100%" : "auto" }),
|
|
159
159
|
onMouseenter: handleMouseEnter,
|
|
160
160
|
onMouseleave: handleMouseLeave
|
|
161
|
-
}, [createElementVNode("div", _hoisted_1, [
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
name: "
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
161
|
+
}, [createElementVNode("div", _hoisted_1, [
|
|
162
|
+
!unref(isHardenUrl) ? (openBlock(), createElementBlock("div", {
|
|
163
|
+
key: 0,
|
|
164
|
+
ref_key: "maskRef",
|
|
165
|
+
ref: maskRef,
|
|
166
|
+
"data-stream-markdown": "image-mask"
|
|
167
|
+
}, [!isLoading.value && showDownload.value ? (openBlock(), createBlock(button_default, {
|
|
168
|
+
key: 0,
|
|
169
|
+
"data-stream-markdown": "image-download-button",
|
|
170
|
+
icon: unref(ICONS).download,
|
|
171
|
+
name: unref(t)("button.download"),
|
|
172
|
+
"icon-class": "test",
|
|
173
|
+
"icon-width": 16,
|
|
174
|
+
"icon-height": 16,
|
|
175
|
+
"button-style": { backgroundColor: "color-mix(in oklab, var(--background) 90%, transparent)" },
|
|
176
|
+
onClick: handleDownload
|
|
177
|
+
}, null, 8, ["icon", "name"])) : createCommentVNode("v-if", true)], 512)) : createCommentVNode("v-if", true),
|
|
178
|
+
(isLoading.value || !imageLoaded.value) && !unref(isHardenUrl) ? (openBlock(), createBlock(spin_default, { key: 1 })) : createCommentVNode("v-if", true),
|
|
179
|
+
createVNode(Transition, {
|
|
180
|
+
name: "img-switch",
|
|
181
|
+
mode: "out-in"
|
|
182
|
+
}, {
|
|
183
|
+
default: withCtx(() => [!isLoading.value && !unref(isHardenUrl) && typeof unref(transformedUrl) === "string" ? (openBlock(), createElementBlock("img", {
|
|
184
|
+
ref_key: "imgRef",
|
|
185
|
+
ref: imgRef,
|
|
186
|
+
key: unref(transformedUrl),
|
|
187
|
+
"data-stream-markdown": "image",
|
|
188
|
+
src: unref(transformedUrl),
|
|
189
|
+
alt: alt.value,
|
|
190
|
+
title: title.value,
|
|
191
|
+
style: normalizeStyle({
|
|
192
|
+
opacity: isLoading.value ? 0 : 1,
|
|
193
|
+
cursor: isLoading.value ? "default" : "pointer"
|
|
194
|
+
}),
|
|
195
|
+
loading: "lazy",
|
|
196
|
+
decoding: "async",
|
|
197
|
+
"data-zoomable": "",
|
|
198
|
+
onLoad: handleLoaded,
|
|
199
|
+
onError: handleError
|
|
200
|
+
}, null, 44, _hoisted_2)) : unref(isHardenUrl) || loadError.value ? (openBlock(), createBlock(resolveDynamicComponent(Error.value), mergeProps({
|
|
201
|
+
key: 1,
|
|
202
|
+
variant: unref(isHardenUrl) ? "harden-image" : "image"
|
|
203
|
+
}, props), {
|
|
204
|
+
default: withCtx(() => [createTextVNode(toDisplayString(title.value), 1)]),
|
|
205
|
+
_: 1
|
|
206
|
+
}, 16, ["variant"])) : createCommentVNode("v-if", true)]),
|
|
202
207
|
_: 1
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
})]), showCaption.value && title.value ? (openBlock(), createElementBlock("figcaption", _hoisted_3, toDisplayString(title.value), 1)) : createCommentVNode("v-if", true)], 36);
|
|
208
|
+
})
|
|
209
|
+
]), showCaption.value && title.value ? (openBlock(), createElementBlock("figcaption", _hoisted_3, toDisplayString(title.value), 1)) : createCommentVNode("v-if", true)], 36);
|
|
206
210
|
};
|
|
207
211
|
}
|
|
208
212
|
});
|