@eternalheart/vue-file-preview 1.5.3 → 1.5.5
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/lib/chunks/{index-duC8sfdn.mjs → index-BJbdyQqO.mjs} +3 -3
- package/lib/chunks/{index-duC8sfdn.mjs.map → index-BJbdyQqO.mjs.map} +1 -1
- package/lib/chunks/{index-Cn1as7Is.mjs → index-BsVt01B9.mjs} +2 -2
- package/lib/chunks/{index-Cn1as7Is.mjs.map → index-BsVt01B9.mjs.map} +1 -1
- package/lib/chunks/{index-C3NmDdG0.mjs → index-BxF1PDtG.mjs} +56 -51
- package/lib/chunks/index-BxF1PDtG.mjs.map +1 -0
- package/lib/chunks/{index-82HR-dnq.mjs → index-C8i_4_NE.mjs} +2 -2
- package/lib/chunks/{index-82HR-dnq.mjs.map → index-C8i_4_NE.mjs.map} +1 -1
- package/lib/chunks/{index-CUiPNLNl.mjs → index-CJYg9ACZ.mjs} +2 -2
- package/lib/chunks/{index-CUiPNLNl.mjs.map → index-CJYg9ACZ.mjs.map} +1 -1
- package/lib/chunks/{index-But-Ggqm.mjs → index-COMgYrS1.mjs} +2 -2
- package/lib/chunks/{index-But-Ggqm.mjs.map → index-COMgYrS1.mjs.map} +1 -1
- package/lib/chunks/{index-DL4ieuqH.mjs → index-CQVxJAl0.mjs} +2 -2
- package/lib/chunks/{index-DL4ieuqH.mjs.map → index-CQVxJAl0.mjs.map} +1 -1
- package/lib/chunks/{index-gy4zs_NW.mjs → index-Chqo2Z52.mjs} +3 -3
- package/lib/chunks/{index-gy4zs_NW.mjs.map → index-Chqo2Z52.mjs.map} +1 -1
- package/lib/chunks/{index-CfYG4AUI.mjs → index-CnXnrnL_.mjs} +2 -2
- package/lib/chunks/{index-CfYG4AUI.mjs.map → index-CnXnrnL_.mjs.map} +1 -1
- package/lib/chunks/{index-CLp2sbPk.mjs → index-CoEcTV_x.mjs} +2 -2
- package/lib/chunks/{index-CLp2sbPk.mjs.map → index-CoEcTV_x.mjs.map} +1 -1
- package/lib/chunks/{index-C0QTgRKZ.mjs → index-Cr-fvO3k.mjs} +2 -2
- package/lib/chunks/{index-C0QTgRKZ.mjs.map → index-Cr-fvO3k.mjs.map} +1 -1
- package/lib/chunks/{index-BYRlg6sV.mjs → index-Cv1O0WV1.mjs} +2 -2
- package/lib/chunks/{index-BYRlg6sV.mjs.map → index-Cv1O0WV1.mjs.map} +1 -1
- package/lib/chunks/{index-ChJ2_eOf.mjs → index-D0oivtF0.mjs} +2 -2
- package/lib/chunks/{index-ChJ2_eOf.mjs.map → index-D0oivtF0.mjs.map} +1 -1
- package/lib/chunks/{index-DTF4d3wF.mjs → index-DJ_PJObW.mjs} +2 -2
- package/lib/chunks/{index-DTF4d3wF.mjs.map → index-DJ_PJObW.mjs.map} +1 -1
- package/lib/chunks/{index-BN-_TZEq.mjs → index-DfiSvjY8.mjs} +3 -3
- package/lib/chunks/{index-BN-_TZEq.mjs.map → index-DfiSvjY8.mjs.map} +1 -1
- package/lib/chunks/{index-BL5vaK1j.mjs → index-DjR_nHvi.mjs} +2 -2
- package/lib/chunks/{index-BL5vaK1j.mjs.map → index-DjR_nHvi.mjs.map} +1 -1
- package/lib/chunks/{index-D8AbjDtI.mjs → index-G8BJ1r6n.mjs} +2 -2
- package/lib/chunks/{index-D8AbjDtI.mjs.map → index-G8BJ1r6n.mjs.map} +1 -1
- package/lib/chunks/{index-CFo0aAyF.mjs → index-NvGZmS6T.mjs} +2 -2
- package/lib/chunks/{index-CFo0aAyF.mjs.map → index-NvGZmS6T.mjs.map} +1 -1
- package/lib/chunks/{index-6XBcUPmD.mjs → index-wS-r1RZP.mjs} +3 -3
- package/lib/chunks/{index-6XBcUPmD.mjs.map → index-wS-r1RZP.mjs.map} +1 -1
- package/lib/chunks/{useShikiHighlight-BMzS0Ypl.mjs → useShikiHighlight-BAigk1ec.mjs} +2 -2
- package/lib/chunks/{useShikiHighlight-BMzS0Ypl.mjs.map → useShikiHighlight-BAigk1ec.mjs.map} +1 -1
- package/lib/index.cjs +21 -18
- package/lib/index.cjs.map +1 -1
- package/lib/index.mjs +1 -1
- package/lib/renderers/Pdf/index.vue.d.ts.map +1 -1
- package/package.json +1 -1
- package/lib/chunks/index-C3NmDdG0.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent as L, ref as c, watch as M, computed as D, openBlock as n, createElementBlock as a, createElementVNode as r, createBlock as H, unref as h, toDisplayString as w, normalizeStyle as B, Fragment as y, renderList as F } from "vue";
|
|
2
|
-
import { u as G, a as N, z as P } from "./index-
|
|
3
|
-
import { u as X } from "./useShikiHighlight-
|
|
2
|
+
import { u as G, a as N, z as P } from "./index-wS-r1RZP.mjs";
|
|
3
|
+
import { u as X } from "./useShikiHighlight-BAigk1ec.mjs";
|
|
4
4
|
import { _ as j } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
|
|
5
5
|
const E = {
|
|
6
6
|
key: 0,
|
|
@@ -85,4 +85,4 @@ $2$3`);
|
|
|
85
85
|
export {
|
|
86
86
|
W as default
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=index-
|
|
88
|
+
//# sourceMappingURL=index-BJbdyQqO.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-BJbdyQqO.mjs","sources":["../../src/renderers/Xml/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nimport { ref, computed, watch } from 'vue';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\nimport { useShikiHighlight } from '../../composables/useShikiHighlight';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n fileName: string;\n}>();\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\n\nconst content = ref<string>('');\nconst loading = ref(true);\nconst error = ref<string | null>(null);\nconst xmlLang = ref('xml');\n\nconst { lineHtmls } = useShikiHighlight(content, xmlLang);\n\nconst indentXml = (xml: string): string => {\n const PADDING = ' ';\n const reg = /(>)(<)(\\/*)/g;\n const formatted = xml.replace(reg, '$1\\n$2$3');\n let pad = 0;\n return formatted\n .split('\\n')\n .map((line) => {\n let indent = 0;\n if (/^<\\/\\w/.test(line)) {\n pad = Math.max(pad - 1, 0);\n } else if (/^<\\w[^>]*[^/]>.*$/.test(line) && !/<.+<\\/.+>$/.test(line)) {\n indent = 1;\n }\n const padded = PADDING.repeat(pad) + line;\n pad += indent;\n return padded;\n })\n .join('\\n');\n};\n\nconst prettyPrintXml = (xml: string): string => {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'application/xml');\n if (doc.querySelector('parsererror')) return xml;\n const serializer = new XMLSerializer();\n const serialized = serializer.serializeToString(doc);\n return indentXml(serialized);\n } catch {\n return xml;\n }\n};\n\nconst load = async () => {\n loading.value = true;\n error.value = null;\n try {\n const raw = await fetchTextUtf8(props.url, { fetcher: fetcher.value });\n content.value = prettyPrintXml(raw);\n } catch (err) {\n console.error(err);\n error.value = t.value('xml.load_failed');\n } finally {\n loading.value = false;\n }\n};\n\nwatch(() => props.url, load, { immediate: true });\n\nconst lines = computed(() => content.value.split('\\n'));\n\nconst getToolbarGroups = (): ToolbarGroup[] => [];\n\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n});\n\n</script>\n\n<template>\n <div v-if=\"loading\" class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-else-if=\"error\" :message=\"error\" />\n\n <div v-else-if=\"lineHtmls.length === 0\" class=\"vfp-w-full vfp-h-full vfp-overflow-auto\" style=\"background: var(--fp-code-bg);\">\n <pre\n class=\"vfp-py-6 vfp-px-4 vfp-text-fg-primary vfp-font-mono vfp-text-sm vfp-whitespace-pre-wrap vfp-break-words\"\n >{{ content }}</pre\n >\n </div>\n\n <div v-else class=\"vfp-w-full vfp-h-full vfp-overflow-auto\" style=\"background: var(--fp-code-bg);\">\n <div class=\"vfp-code-block with-line-numbers vfp-w-full\" :style=\"{ gridTemplateRows: `repeat(${lines.length}, auto) minmax(1.5rem, 1fr)` }\">\n <template v-for=\"(_, i) in lines\" :key=\"i\">\n <span class=\"vfp-code-gutter\">{{ i + 1 }}</span>\n <span class=\"vfp-code-line\" v-html=\"lineHtmls[i] ?? ''\" />\n </template>\n <!-- 占位行:撑满剩余高度,让 gutter border 延伸到底部 -->\n <span class=\"vfp-code-gutter-filler\" />\n <span class=\"vfp-code-line-filler\" />\n </div>\n </div>\n</template>\n"],"names":["props","__props","t","useTranslator","fetcher","useFetcher","content","ref","loading","error","xmlLang","lineHtmls","useShikiHighlight","indentXml","xml","PADDING","reg","formatted","pad","line","indent","padded","prettyPrintXml","doc","serialized","watch","raw","fetchTextUtf8","err","lines","computed","__expose","_openBlock","_createElementBlock","_hoisted_1","_cache","_createElementVNode","_createBlock","RendererError","_unref","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_normalizeStyle","_Fragment","_renderList","_","i","_hoisted_5"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import z from "markdown-it";
|
|
|
3
3
|
import N from "@traptitech/markdown-it-katex";
|
|
4
4
|
import { codeToHtml as E } from "shiki";
|
|
5
5
|
import { Code as Y, Eye as F } from "lucide-vue-next";
|
|
6
|
-
import { u as W, a as J, c as Q, z as U, _ as X } from "./index-
|
|
6
|
+
import { u as W, a as J, c as Q, z as U, _ as X } from "./index-wS-r1RZP.mjs";
|
|
7
7
|
import { _ as Z } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
|
|
8
8
|
import { T as ee } from "./base.types-DaftHyg7.mjs";
|
|
9
9
|
const te = {
|
|
@@ -150,4 +150,4 @@ const te = {
|
|
|
150
150
|
export {
|
|
151
151
|
ke as default
|
|
152
152
|
};
|
|
153
|
-
//# sourceMappingURL=index-
|
|
153
|
+
//# sourceMappingURL=index-BsVt01B9.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-Cn1as7Is.mjs","sources":["../../src/renderers/Markdown/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue';\nimport MarkdownIt from 'markdown-it';\nimport MarkdownItKatex from '@traptitech/markdown-it-katex';\nimport { codeToHtml } from 'shiki';\nimport { Eye, Code } from 'lucide-vue-next';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\nimport { useResolvedTheme } from '../../composables/useResolvedTheme';\nimport RendererError from '../RendererError.vue';\nimport { ToolbarEventEmitter } from '../base.types';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport 'katex/dist/katex.min.css';\n\nconst props = defineProps<{\n url: string;\n}>();\n\nconst emitter = new ToolbarEventEmitter();\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\nconst resolvedTheme = useResolvedTheme();\nconst shikiTheme = computed(() => (resolvedTheme.value === 'light' ? 'github-light' : 'github-dark'));\n\n// 内部状态\nconst viewMode = ref<'preview' | 'source'>('preview');\n\nconst content = ref('');\nconst html = ref('');\nconst highlightedSource = ref('');\nconst loading = ref(true);\nconst error = ref<string | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\n\n// 监听状态变化,通知工具栏更新\nwatch([viewMode, loading], () => {\n emitter.notify();\n});\n\n// 工具栏配置(对齐 React:Code 图标、翻译 key)\nconst getToolbarGroups = (): ToolbarGroup[] => {\n const groups: ToolbarGroup[] = [];\n\n groups.push({\n items: [\n {\n type: 'button',\n icon: viewMode.value === 'preview' ? Code : Eye,\n tooltip: viewMode.value === 'preview' ? t.value('toolbar.source') : t.value('toolbar.preview'),\n action: () => { viewMode.value = viewMode.value === 'preview' ? 'source' : 'preview'; },\n active: viewMode.value === 'source',\n },\n ],\n });\n\n return groups;\n};\n\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n onToolbarChange: (listener) => emitter.subscribe(listener),\n});\n\n// 创建 markdown-it 实例(支持 GFM 表格、删除线、任务列表、HTML、数学公式)\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n typographer: false,\n breaks: false,\n});\nmd.use(MarkdownItKatex);\n\n// 自定义代码块渲染:包裹 code-block-wrapper + header(不含复制按钮,由 JS 动态注入)\nmd.renderer.rules.fence = (tokens, idx) => {\n const token = tokens[idx];\n const info = token.info ? token.info.trim() : '';\n const code = token.content;\n\n if (!info) {\n return `<div class=\"code-block-wrapper\">\n <pre class=\"no-lang-pre\"><code>${md.utils.escapeHtml(code)}</code></pre>\n </div>`;\n }\n\n return `<div class=\"code-block-wrapper\">\n <div class=\"code-block-header\">\n <span>${info}</span>\n </div>\n <pre data-shiki-pending=\"1\" data-lang=\"${info}\"><code>${md.utils.escapeHtml(code)}</code></pre>\n </div>`;\n};\n\n// 4-space 缩进代码块:同样包裹 code-block-wrapper(无头,注入浮动复制按钮)\nmd.renderer.rules.code_block = (tokens, idx) => {\n const code = tokens[idx].content;\n return `<div class=\"code-block-wrapper\">\n <pre class=\"no-lang-pre\"><code>${md.utils.escapeHtml(code)}</code></pre>\n </div>`;\n};\n\n// 表格添加包裹层(用于横向滚动)\nconst defaultTableOpen =\n md.renderer.rules.table_open ||\n ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));\nmd.renderer.rules.table_open = (tokens, idx, options, env, self) => {\n return '<div class=\"table-wrapper\">' + defaultTableOpen(tokens, idx, options, env, self);\n};\nconst defaultTableClose =\n md.renderer.rules.table_close ||\n ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));\nmd.renderer.rules.table_close = (tokens, idx, options, env, self) => {\n return defaultTableClose(tokens, idx, options, env, self) + '</div>';\n};\n\nconst loadMarkdown = async () => {\n loading.value = true;\n error.value = null;\n try {\n const text = await fetchTextUtf8(props.url, { fetcher: fetcher.value });\n content.value = text;\n html.value = md.render(text);\n loading.value = false;\n // 异步生成源码高亮(不阻塞预览渲染)\n try {\n highlightedSource.value = await codeToHtml(text, { lang: 'markdown', theme: shikiTheme.value });\n } catch {\n highlightedSource.value = '';\n }\n } catch (err) {\n console.error(err);\n error.value = t.value('markdown.load_failed');\n loading.value = false;\n }\n};\n\nconst COPY_SVG_SM = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg>`;\nconst COPY_SVG_MD = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg>`;\nconst CHECK_SVG_SM = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>`;\nconst CHECK_SVG_MD = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>`;\n\nconst createCopyButton = (code: string, inline: boolean): HTMLButtonElement => {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = inline ? 'code-copy-btn' : 'code-copy-btn code-copy-float';\n btn.title = t.value('markdown.copy_code');\n btn.innerHTML = inline ? COPY_SVG_SM : COPY_SVG_MD;\n btn.addEventListener('click', async (e) => {\n e.stopPropagation();\n try {\n await navigator.clipboard.writeText(code);\n } catch {\n const ta = document.createElement('textarea');\n ta.value = code;\n document.body.appendChild(ta);\n ta.select();\n document.execCommand('copy');\n document.body.removeChild(ta);\n }\n btn.innerHTML = inline ? CHECK_SVG_SM : CHECK_SVG_MD;\n btn.title = t.value('markdown.copied');\n setTimeout(() => {\n btn.innerHTML = inline ? COPY_SVG_SM : COPY_SVG_MD;\n btn.title = t.value('markdown.copy_code');\n }, 2000);\n });\n return btn;\n};\n\nconst highlightAndInjectCopyButtons = async () => {\n if (!containerRef.value) return;\n\n // 1. shiki 高亮有语言的代码块\n const pending = containerRef.value.querySelectorAll<HTMLPreElement>('pre[data-shiki-pending=\"1\"]');\n for (const pre of pending) {\n const lang = pre.getAttribute('data-lang') || 'text';\n const code = pre.querySelector('code')?.textContent || '';\n try {\n const highlighted = await codeToHtml(code, { lang, theme: shikiTheme.value });\n const tmp = document.createElement('div');\n tmp.innerHTML = highlighted;\n const newPre = tmp.firstElementChild as HTMLElement;\n if (newPre) pre.replaceWith(newPre);\n } catch {\n pre.style.backgroundColor = 'var(--fp-code-bg)';\n pre.removeAttribute('data-shiki-pending');\n }\n }\n\n // 2. 为所有代码块注入复制按钮(避免重复注入)\n const wrappers = containerRef.value.querySelectorAll<HTMLElement>('.code-block-wrapper');\n for (const wrapper of wrappers) {\n if (wrapper.querySelector('.code-copy-btn')) continue;\n const header = wrapper.querySelector('.code-block-header');\n const pre = wrapper.querySelector('pre');\n const code = pre?.querySelector('code')?.textContent ?? pre?.textContent ?? '';\n if (header) {\n // 有语言:按钮放入 header 右侧\n header.appendChild(createCopyButton(code, true));\n } else {\n // 无语言:浮动按钮\n wrapper.appendChild(createCopyButton(code, false));\n }\n }\n};\n\nwatch(() => props.url, loadMarkdown, { immediate: true });\n\nwatch(html, async () => {\n if (!html.value) return;\n await nextTick();\n highlightAndInjectCopyButtons();\n});\n\n// 主题切换时重新加载(让 shiki 用新主题重新高亮)\nwatch(shikiTheme, () => {\n if (content.value) loadMarkdown();\n});\n</script>\n\n<template>\n <div v-if=\"loading\" class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-else-if=\"error\" :message=\"error\" />\n\n <!-- 源码视图 -->\n <div v-else-if=\"viewMode === 'source'\" class=\"vfp-w-full vfp-h-full vfp-overflow-auto\" style=\"background: var(--fp-code-bg);\">\n <pre\n v-if=\"!highlightedSource\"\n class=\"vfp-p-6 vfp-text-fg-primary vfp-font-mono vfp-text-sm vfp-whitespace-pre-wrap vfp-break-words\"\n >{{ content }}</pre\n >\n <div v-else class=\"shiki-wrapper\" v-html=\"highlightedSource\" />\n </div>\n\n <!-- 预览视图 -->\n <div v-else class=\"vfp-w-full vfp-h-full vfp-overflow-auto vfp-py-6 vfp-px-4\">\n <div ref=\"containerRef\" class=\"markdown-body\" v-html=\"html\" />\n </div>\n</template>\n\n<style scoped>\n.markdown-body :deep(.table-wrapper) {\n overflow-x: auto;\n margin: 1rem 0;\n border-radius: 0.375rem;\n border: 1px solid var(--fp-surface-3);\n}\n.markdown-body :deep(.table-wrapper > table) {\n margin: 0;\n border: 0;\n border-radius: 0;\n}\n/* shiki 生成的 pre:修正在 code-block-wrapper 内的边距与圆角 */\n.markdown-body :deep(.code-block-wrapper pre.shiki) {\n margin: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-top: 0;\n}\n/* 无语言代码块:pre 不裁剪,让浮动按钮可见 */\n.markdown-body :deep(.code-block-wrapper) {\n overflow: visible;\n}\n.markdown-body :deep(.code-block-wrapper pre) {\n overflow: visible;\n}\n/* 无语言代码块纯文本样式 */\n.markdown-body :deep(.no-lang-pre) {\n margin: 0;\n padding: 1rem;\n background: var(--fp-code-bg);\n border-radius: 0.375rem;\n border: 1px solid var(--fp-line);\n}\n.markdown-body :deep(.no-lang-pre code) {\n display: block;\n font-size: 0.8125rem;\n line-height: 1.5;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n color: var(--fp-fg-primary);\n white-space: pre;\n overflow-x: auto;\n}\n/* shiki 生成的 code:补充 padding,使代码有适当内边距 */\n.markdown-body :deep(pre.shiki code) {\n display: block;\n padding: 1rem;\n font-size: 0.8125rem;\n line-height: 1.5;\n overflow-x: auto;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n/* KaTeX 公式颜色适配暗色背景 */\n.markdown-body :deep(.katex) {\n color: var(--fp-fg-primary);\n}\n.markdown-body :deep(.katex-display) {\n margin: 1.25rem 0;\n overflow-x: auto;\n overflow-y: hidden;\n}\n/* 源码视图 shiki */\n.shiki-wrapper :deep(pre) {\n margin: 0;\n padding: 1.5rem;\n background: transparent !important;\n font-size: 0.875rem;\n overflow-x: auto;\n}\n.shiki-wrapper :deep(code) {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n</style>\n"],"names":["COPY_SVG_SM","COPY_SVG_MD","CHECK_SVG_SM","CHECK_SVG_MD","props","__props","emitter","ToolbarEventEmitter","t","useTranslator","fetcher","useFetcher","resolvedTheme","useResolvedTheme","shikiTheme","computed","viewMode","ref","content","html","highlightedSource","loading","error","containerRef","watch","__expose","groups","Code","Eye","listener","md","MarkdownIt","MarkdownItKatex","tokens","idx","token","info","code","defaultTableOpen","options","_env","self","env","defaultTableClose","loadMarkdown","text","fetchTextUtf8","codeToHtml","err","createCopyButton","inline","btn","e","ta","highlightAndInjectCopyButtons","pending","pre","lang","_a","highlighted","tmp","newPre","wrappers","wrapper","header","_b","nextTick","_openBlock","_createElementBlock","_hoisted_1","_cache","_createElementVNode","_createBlock","RendererError","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_5"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-BsVt01B9.mjs","sources":["../../src/renderers/Markdown/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue';\nimport MarkdownIt from 'markdown-it';\nimport MarkdownItKatex from '@traptitech/markdown-it-katex';\nimport { codeToHtml } from 'shiki';\nimport { Eye, Code } from 'lucide-vue-next';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\nimport { useResolvedTheme } from '../../composables/useResolvedTheme';\nimport RendererError from '../RendererError.vue';\nimport { ToolbarEventEmitter } from '../base.types';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\nimport 'katex/dist/katex.min.css';\n\nconst props = defineProps<{\n url: string;\n}>();\n\nconst emitter = new ToolbarEventEmitter();\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\nconst resolvedTheme = useResolvedTheme();\nconst shikiTheme = computed(() => (resolvedTheme.value === 'light' ? 'github-light' : 'github-dark'));\n\n// 内部状态\nconst viewMode = ref<'preview' | 'source'>('preview');\n\nconst content = ref('');\nconst html = ref('');\nconst highlightedSource = ref('');\nconst loading = ref(true);\nconst error = ref<string | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\n\n// 监听状态变化,通知工具栏更新\nwatch([viewMode, loading], () => {\n emitter.notify();\n});\n\n// 工具栏配置(对齐 React:Code 图标、翻译 key)\nconst getToolbarGroups = (): ToolbarGroup[] => {\n const groups: ToolbarGroup[] = [];\n\n groups.push({\n items: [\n {\n type: 'button',\n icon: viewMode.value === 'preview' ? Code : Eye,\n tooltip: viewMode.value === 'preview' ? t.value('toolbar.source') : t.value('toolbar.preview'),\n action: () => { viewMode.value = viewMode.value === 'preview' ? 'source' : 'preview'; },\n active: viewMode.value === 'source',\n },\n ],\n });\n\n return groups;\n};\n\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n onToolbarChange: (listener) => emitter.subscribe(listener),\n});\n\n// 创建 markdown-it 实例(支持 GFM 表格、删除线、任务列表、HTML、数学公式)\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n typographer: false,\n breaks: false,\n});\nmd.use(MarkdownItKatex);\n\n// 自定义代码块渲染:包裹 code-block-wrapper + header(不含复制按钮,由 JS 动态注入)\nmd.renderer.rules.fence = (tokens, idx) => {\n const token = tokens[idx];\n const info = token.info ? token.info.trim() : '';\n const code = token.content;\n\n if (!info) {\n return `<div class=\"code-block-wrapper\">\n <pre class=\"no-lang-pre\"><code>${md.utils.escapeHtml(code)}</code></pre>\n </div>`;\n }\n\n return `<div class=\"code-block-wrapper\">\n <div class=\"code-block-header\">\n <span>${info}</span>\n </div>\n <pre data-shiki-pending=\"1\" data-lang=\"${info}\"><code>${md.utils.escapeHtml(code)}</code></pre>\n </div>`;\n};\n\n// 4-space 缩进代码块:同样包裹 code-block-wrapper(无头,注入浮动复制按钮)\nmd.renderer.rules.code_block = (tokens, idx) => {\n const code = tokens[idx].content;\n return `<div class=\"code-block-wrapper\">\n <pre class=\"no-lang-pre\"><code>${md.utils.escapeHtml(code)}</code></pre>\n </div>`;\n};\n\n// 表格添加包裹层(用于横向滚动)\nconst defaultTableOpen =\n md.renderer.rules.table_open ||\n ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));\nmd.renderer.rules.table_open = (tokens, idx, options, env, self) => {\n return '<div class=\"table-wrapper\">' + defaultTableOpen(tokens, idx, options, env, self);\n};\nconst defaultTableClose =\n md.renderer.rules.table_close ||\n ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));\nmd.renderer.rules.table_close = (tokens, idx, options, env, self) => {\n return defaultTableClose(tokens, idx, options, env, self) + '</div>';\n};\n\nconst loadMarkdown = async () => {\n loading.value = true;\n error.value = null;\n try {\n const text = await fetchTextUtf8(props.url, { fetcher: fetcher.value });\n content.value = text;\n html.value = md.render(text);\n loading.value = false;\n // 异步生成源码高亮(不阻塞预览渲染)\n try {\n highlightedSource.value = await codeToHtml(text, { lang: 'markdown', theme: shikiTheme.value });\n } catch {\n highlightedSource.value = '';\n }\n } catch (err) {\n console.error(err);\n error.value = t.value('markdown.load_failed');\n loading.value = false;\n }\n};\n\nconst COPY_SVG_SM = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg>`;\nconst COPY_SVG_MD = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg>`;\nconst CHECK_SVG_SM = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>`;\nconst CHECK_SVG_MD = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>`;\n\nconst createCopyButton = (code: string, inline: boolean): HTMLButtonElement => {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = inline ? 'code-copy-btn' : 'code-copy-btn code-copy-float';\n btn.title = t.value('markdown.copy_code');\n btn.innerHTML = inline ? COPY_SVG_SM : COPY_SVG_MD;\n btn.addEventListener('click', async (e) => {\n e.stopPropagation();\n try {\n await navigator.clipboard.writeText(code);\n } catch {\n const ta = document.createElement('textarea');\n ta.value = code;\n document.body.appendChild(ta);\n ta.select();\n document.execCommand('copy');\n document.body.removeChild(ta);\n }\n btn.innerHTML = inline ? CHECK_SVG_SM : CHECK_SVG_MD;\n btn.title = t.value('markdown.copied');\n setTimeout(() => {\n btn.innerHTML = inline ? COPY_SVG_SM : COPY_SVG_MD;\n btn.title = t.value('markdown.copy_code');\n }, 2000);\n });\n return btn;\n};\n\nconst highlightAndInjectCopyButtons = async () => {\n if (!containerRef.value) return;\n\n // 1. shiki 高亮有语言的代码块\n const pending = containerRef.value.querySelectorAll<HTMLPreElement>('pre[data-shiki-pending=\"1\"]');\n for (const pre of pending) {\n const lang = pre.getAttribute('data-lang') || 'text';\n const code = pre.querySelector('code')?.textContent || '';\n try {\n const highlighted = await codeToHtml(code, { lang, theme: shikiTheme.value });\n const tmp = document.createElement('div');\n tmp.innerHTML = highlighted;\n const newPre = tmp.firstElementChild as HTMLElement;\n if (newPre) pre.replaceWith(newPre);\n } catch {\n pre.style.backgroundColor = 'var(--fp-code-bg)';\n pre.removeAttribute('data-shiki-pending');\n }\n }\n\n // 2. 为所有代码块注入复制按钮(避免重复注入)\n const wrappers = containerRef.value.querySelectorAll<HTMLElement>('.code-block-wrapper');\n for (const wrapper of wrappers) {\n if (wrapper.querySelector('.code-copy-btn')) continue;\n const header = wrapper.querySelector('.code-block-header');\n const pre = wrapper.querySelector('pre');\n const code = pre?.querySelector('code')?.textContent ?? pre?.textContent ?? '';\n if (header) {\n // 有语言:按钮放入 header 右侧\n header.appendChild(createCopyButton(code, true));\n } else {\n // 无语言:浮动按钮\n wrapper.appendChild(createCopyButton(code, false));\n }\n }\n};\n\nwatch(() => props.url, loadMarkdown, { immediate: true });\n\nwatch(html, async () => {\n if (!html.value) return;\n await nextTick();\n highlightAndInjectCopyButtons();\n});\n\n// 主题切换时重新加载(让 shiki 用新主题重新高亮)\nwatch(shikiTheme, () => {\n if (content.value) loadMarkdown();\n});\n</script>\n\n<template>\n <div v-if=\"loading\" class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-else-if=\"error\" :message=\"error\" />\n\n <!-- 源码视图 -->\n <div v-else-if=\"viewMode === 'source'\" class=\"vfp-w-full vfp-h-full vfp-overflow-auto\" style=\"background: var(--fp-code-bg);\">\n <pre\n v-if=\"!highlightedSource\"\n class=\"vfp-p-6 vfp-text-fg-primary vfp-font-mono vfp-text-sm vfp-whitespace-pre-wrap vfp-break-words\"\n >{{ content }}</pre\n >\n <div v-else class=\"shiki-wrapper\" v-html=\"highlightedSource\" />\n </div>\n\n <!-- 预览视图 -->\n <div v-else class=\"vfp-w-full vfp-h-full vfp-overflow-auto vfp-py-6 vfp-px-4\">\n <div ref=\"containerRef\" class=\"markdown-body\" v-html=\"html\" />\n </div>\n</template>\n\n<style scoped>\n.markdown-body :deep(.table-wrapper) {\n overflow-x: auto;\n margin: 1rem 0;\n border-radius: 0.375rem;\n border: 1px solid var(--fp-surface-3);\n}\n.markdown-body :deep(.table-wrapper > table) {\n margin: 0;\n border: 0;\n border-radius: 0;\n}\n/* shiki 生成的 pre:修正在 code-block-wrapper 内的边距与圆角 */\n.markdown-body :deep(.code-block-wrapper pre.shiki) {\n margin: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-top: 0;\n}\n/* 无语言代码块:pre 不裁剪,让浮动按钮可见 */\n.markdown-body :deep(.code-block-wrapper) {\n overflow: visible;\n}\n.markdown-body :deep(.code-block-wrapper pre) {\n overflow: visible;\n}\n/* 无语言代码块纯文本样式 */\n.markdown-body :deep(.no-lang-pre) {\n margin: 0;\n padding: 1rem;\n background: var(--fp-code-bg);\n border-radius: 0.375rem;\n border: 1px solid var(--fp-line);\n}\n.markdown-body :deep(.no-lang-pre code) {\n display: block;\n font-size: 0.8125rem;\n line-height: 1.5;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n color: var(--fp-fg-primary);\n white-space: pre;\n overflow-x: auto;\n}\n/* shiki 生成的 code:补充 padding,使代码有适当内边距 */\n.markdown-body :deep(pre.shiki code) {\n display: block;\n padding: 1rem;\n font-size: 0.8125rem;\n line-height: 1.5;\n overflow-x: auto;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n/* KaTeX 公式颜色适配暗色背景 */\n.markdown-body :deep(.katex) {\n color: var(--fp-fg-primary);\n}\n.markdown-body :deep(.katex-display) {\n margin: 1.25rem 0;\n overflow-x: auto;\n overflow-y: hidden;\n}\n/* 源码视图 shiki */\n.shiki-wrapper :deep(pre) {\n margin: 0;\n padding: 1.5rem;\n background: transparent !important;\n font-size: 0.875rem;\n overflow-x: auto;\n}\n.shiki-wrapper :deep(code) {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}\n</style>\n"],"names":["COPY_SVG_SM","COPY_SVG_MD","CHECK_SVG_SM","CHECK_SVG_MD","props","__props","emitter","ToolbarEventEmitter","t","useTranslator","fetcher","useFetcher","resolvedTheme","useResolvedTheme","shikiTheme","computed","viewMode","ref","content","html","highlightedSource","loading","error","containerRef","watch","__expose","groups","Code","Eye","listener","md","MarkdownIt","MarkdownItKatex","tokens","idx","token","info","code","defaultTableOpen","options","_env","self","env","defaultTableClose","loadMarkdown","text","fetchTextUtf8","codeToHtml","err","createCopyButton","inline","btn","e","ta","highlightAndInjectCopyButtons","pending","pre","lang","_a","highlighted","tmp","newPre","wrappers","wrapper","header","_b","nextTick","_openBlock","_createElementBlock","_hoisted_1","_cache","_createElementVNode","_createBlock","RendererError","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_5"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineComponent as ae, ref as m, watch as C, nextTick as
|
|
2
|
-
import {
|
|
3
|
-
import * as
|
|
1
|
+
import { defineComponent as ae, ref as m, watch as C, nextTick as L, onMounted as le, onBeforeUnmount as re, openBlock as S, createElementBlock as O, normalizeStyle as N, createElementVNode as h, toDisplayString as oe, unref as B, createVNode as ie, createCommentVNode as A, createBlock as se } from "vue";
|
|
2
|
+
import { u as ue, W as ce } from "./index-wS-r1RZP.mjs";
|
|
3
|
+
import * as H from "pdfjs-dist/build/pdf.mjs";
|
|
4
4
|
import { _ as fe } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
|
|
5
5
|
import { X as ve, Menu as pe, ChevronLeft as de, ChevronRight as ge, ZoomOut as me, ZoomIn as he, RefreshCw as ye } from "lucide-vue-next";
|
|
6
6
|
import { T as be } from "./base.types-DaftHyg7.mjs";
|
|
@@ -15,20 +15,19 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
15
15
|
props: {
|
|
16
16
|
url: {}
|
|
17
17
|
},
|
|
18
|
-
setup(Z, { expose:
|
|
19
|
-
ue(
|
|
20
|
-
const R = Z, N = new be(), { t: y } = ce(), v = m(1), g = m(1), p = m(!1), b = m(0), P = m(null), S = m(!0), f = m([]), $ = m(null), M = m(null), s = m(null), I = /* @__PURE__ */ new Map();
|
|
18
|
+
setup(Z, { expose: F }) {
|
|
19
|
+
const j = Z, q = new be(), { t: y } = ue(), v = m(1), g = m(1), p = m(!1), b = m(0), P = m(null), _ = m(!0), f = m([]), $ = m(null), M = m(null), s = m(null), I = /* @__PURE__ */ new Map();
|
|
21
20
|
let o = null;
|
|
22
21
|
const d = /* @__PURE__ */ new Map();
|
|
23
22
|
let c = null;
|
|
24
23
|
C([v, g, b, p, () => f.value.length], () => {
|
|
25
|
-
|
|
24
|
+
q.notify();
|
|
26
25
|
});
|
|
27
|
-
const
|
|
26
|
+
const G = () => {
|
|
28
27
|
v.value = Math.min(3, v.value + 0.1);
|
|
29
|
-
},
|
|
28
|
+
}, K = () => {
|
|
30
29
|
v.value = Math.max(0.5, v.value - 0.1);
|
|
31
|
-
},
|
|
30
|
+
}, X = () => {
|
|
32
31
|
v.value = 1;
|
|
33
32
|
}, J = () => {
|
|
34
33
|
if (!s.value) return;
|
|
@@ -41,7 +40,7 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
41
40
|
}, Q = () => {
|
|
42
41
|
p.value = !p.value;
|
|
43
42
|
};
|
|
44
|
-
|
|
43
|
+
F({
|
|
45
44
|
getToolbarGroups: () => {
|
|
46
45
|
const t = [];
|
|
47
46
|
return b.value === 0 || (f.value.length > 0 && t.push({
|
|
@@ -82,7 +81,7 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
82
81
|
type: "button",
|
|
83
82
|
icon: me,
|
|
84
83
|
tooltip: y.value("toolbar.zoom_out"),
|
|
85
|
-
action:
|
|
84
|
+
action: K,
|
|
86
85
|
disabled: v.value <= 0.5
|
|
87
86
|
},
|
|
88
87
|
{
|
|
@@ -94,7 +93,7 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
94
93
|
type: "button",
|
|
95
94
|
icon: he,
|
|
96
95
|
tooltip: y.value("toolbar.zoom_in"),
|
|
97
|
-
action:
|
|
96
|
+
action: G,
|
|
98
97
|
disabled: v.value >= 3
|
|
99
98
|
}
|
|
100
99
|
]
|
|
@@ -104,12 +103,12 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
104
103
|
type: "button",
|
|
105
104
|
icon: ye,
|
|
106
105
|
tooltip: y.value("toolbar.reset"),
|
|
107
|
-
action:
|
|
106
|
+
action: X
|
|
108
107
|
}
|
|
109
108
|
]
|
|
110
109
|
})), t;
|
|
111
110
|
},
|
|
112
|
-
onToolbarChange: (t) =>
|
|
111
|
+
onToolbarChange: (t) => q.subscribe(t)
|
|
113
112
|
});
|
|
114
113
|
const V = async (t, e, n = 0) => {
|
|
115
114
|
var a, r, l;
|
|
@@ -187,7 +186,7 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
187
186
|
n.rendering = !1, n.renderTask = null;
|
|
188
187
|
}
|
|
189
188
|
}
|
|
190
|
-
},
|
|
189
|
+
}, W = (t) => {
|
|
191
190
|
const e = d.get(t);
|
|
192
191
|
if (!e) return;
|
|
193
192
|
e.renderTask && (e.renderTask.cancel(), e.renderTask = null);
|
|
@@ -213,7 +212,8 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
213
212
|
}
|
|
214
213
|
}
|
|
215
214
|
}, ne = async () => {
|
|
216
|
-
|
|
215
|
+
var t;
|
|
216
|
+
if (P.value = null, _.value = !0, b.value = 0, o) {
|
|
217
217
|
try {
|
|
218
218
|
o.destroy();
|
|
219
219
|
} catch {
|
|
@@ -221,18 +221,23 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
221
221
|
o = null;
|
|
222
222
|
}
|
|
223
223
|
try {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
H.GlobalWorkerOptions.workerSrc || (ce(H), typeof process < "u" && ((t = process.env) == null ? void 0 : t.NODE_ENV) === "development" && console.warn(
|
|
225
|
+
`[vue-file-preview] PDF worker 自动配置为 CDN。若环境存在 CSP 限制或加载失败,请配置同源本地文件:
|
|
226
|
+
import { configurePdfWorker } from '@eternalheart/vue-file-preview';
|
|
227
|
+
import * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs';
|
|
228
|
+
configurePdfWorker(pdfjsLib, { workerSrc: '/pdfjs/pdf.worker.min.mjs' });`
|
|
229
|
+
)), o = await H.getDocument({ url: j.url }).promise;
|
|
230
|
+
const n = o.numPages;
|
|
231
|
+
b.value = n, g.value = 1;
|
|
227
232
|
try {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
} catch (
|
|
231
|
-
console.warn("PDF 大纲提取失败:",
|
|
233
|
+
const a = await o.getOutline();
|
|
234
|
+
a && (f.value = a, I.clear(), await V(a, o));
|
|
235
|
+
} catch (a) {
|
|
236
|
+
console.warn("PDF 大纲提取失败:", a);
|
|
232
237
|
}
|
|
233
|
-
|
|
234
|
-
} catch (
|
|
235
|
-
console.error("PDF 加载错误:",
|
|
238
|
+
_.value = !1;
|
|
239
|
+
} catch (e) {
|
|
240
|
+
console.error("PDF 加载错误:", e), P.value = y.value("pdf.load_failed"), _.value = !1;
|
|
236
241
|
}
|
|
237
242
|
}, z = () => {
|
|
238
243
|
if (!s.value || d.size === 0) return;
|
|
@@ -242,8 +247,8 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
242
247
|
const x = u.element.getBoundingClientRect(), w = t.getBoundingClientRect(), k = x.top - w.top + x.height / 2 + e, T = Math.abs(a - k);
|
|
243
248
|
T < l && (l = T, r = i);
|
|
244
249
|
}), r !== g.value && (g.value = r);
|
|
245
|
-
},
|
|
246
|
-
|
|
250
|
+
}, R = () => {
|
|
251
|
+
L(() => {
|
|
247
252
|
var e;
|
|
248
253
|
const t = (e = M.value) == null ? void 0 : e.querySelector(".outline-items");
|
|
249
254
|
t && t.addEventListener("click", (n) => {
|
|
@@ -260,15 +265,15 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
260
265
|
});
|
|
261
266
|
});
|
|
262
267
|
};
|
|
263
|
-
return C(() =>
|
|
264
|
-
|
|
268
|
+
return C(() => j.url, () => {
|
|
269
|
+
j.url && ne();
|
|
265
270
|
}, { immediate: !0 }), C(b, (t) => {
|
|
266
|
-
t > 0 &&
|
|
271
|
+
t > 0 && L(() => {
|
|
267
272
|
te();
|
|
268
273
|
});
|
|
269
274
|
}), C(() => v.value, () => {
|
|
270
275
|
d.forEach((t, e) => {
|
|
271
|
-
t.rendered &&
|
|
276
|
+
t.rendered && W(e);
|
|
272
277
|
}), setTimeout(() => {
|
|
273
278
|
c && s.value && d.forEach((t) => {
|
|
274
279
|
c == null || c.unobserve(t.element), c == null || c.observe(t.element);
|
|
@@ -277,20 +282,20 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
277
282
|
}), C(() => g.value, (t) => {
|
|
278
283
|
t > 0 && I.size > 0 && Y(t);
|
|
279
284
|
}), C($, () => {
|
|
280
|
-
|
|
285
|
+
L(() => {
|
|
281
286
|
var e;
|
|
282
287
|
const t = (e = M.value) == null ? void 0 : e.querySelector(".outline-items");
|
|
283
|
-
t && f.value.length > 0 && (t.innerHTML = `<ul>${E(f.value)}</ul>`,
|
|
288
|
+
t && f.value.length > 0 && (t.innerHTML = `<ul>${E(f.value)}</ul>`, R());
|
|
284
289
|
});
|
|
285
290
|
}), C(f, () => {
|
|
286
|
-
|
|
291
|
+
L(() => {
|
|
287
292
|
var e;
|
|
288
293
|
const t = (e = M.value) == null ? void 0 : e.querySelector(".outline-items");
|
|
289
294
|
!t && f.value.length > 0 ? setTimeout(() => {
|
|
290
295
|
var a;
|
|
291
296
|
const n = (a = M.value) == null ? void 0 : a.querySelector(".outline-items");
|
|
292
|
-
n && (n.innerHTML = `<ul>${E(f.value)}</ul>`,
|
|
293
|
-
}, 100) : t && f.value.length > 0 && (t.innerHTML = `<ul>${E(f.value)}</ul>`,
|
|
297
|
+
n && (n.innerHTML = `<ul>${E(f.value)}</ul>`, R());
|
|
298
|
+
}, 100) : t && f.value.length > 0 && (t.innerHTML = `<ul>${E(f.value)}</ul>`, R());
|
|
294
299
|
});
|
|
295
300
|
}, { deep: !0 }), le(() => {
|
|
296
301
|
c = new IntersectionObserver(
|
|
@@ -302,7 +307,7 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
302
307
|
ee(a, v.value);
|
|
303
308
|
else {
|
|
304
309
|
const r = d.get(a);
|
|
305
|
-
r && r.rendered &&
|
|
310
|
+
r && r.rendered && W(a);
|
|
306
311
|
}
|
|
307
312
|
});
|
|
308
313
|
},
|
|
@@ -326,22 +331,22 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
326
331
|
}
|
|
327
332
|
o = null;
|
|
328
333
|
}
|
|
329
|
-
}), (t, e) => (
|
|
334
|
+
}), (t, e) => (S(), O("div", {
|
|
330
335
|
ref_key: "containerRef",
|
|
331
336
|
ref: M,
|
|
332
337
|
class: "vfp-relative vfp-w-full vfp-h-full"
|
|
333
338
|
}, [
|
|
334
|
-
f.value.length > 0 ? (
|
|
339
|
+
f.value.length > 0 ? (S(), O("div", {
|
|
335
340
|
key: 0,
|
|
336
341
|
class: "vfp-absolute vfp-inset-0 vfp-z-20 vfp-flex vfp-transition-opacity vfp-duration-300",
|
|
337
|
-
style:
|
|
342
|
+
style: N({
|
|
338
343
|
opacity: p.value ? 1 : 0,
|
|
339
344
|
pointerEvents: p.value ? "auto" : "none"
|
|
340
345
|
})
|
|
341
346
|
}, [
|
|
342
347
|
h("div", {
|
|
343
348
|
class: "vfp-w-72 vfp-max-w-[80%] vfp-h-full vfp-bg-surface-overlay vfp-backdrop-blur-xl vfp-border-r vfp-border-line-weak vfp-flex vfp-flex-col vfp-shadow-2xl vfp-transition-transform vfp-duration-300",
|
|
344
|
-
style:
|
|
349
|
+
style: N({ transform: p.value ? "translateX(0)" : "translateX(-100%)" })
|
|
345
350
|
}, [
|
|
346
351
|
h("div", xe, [
|
|
347
352
|
h("span", we, oe(B(y)("toolbar.outline")), 1),
|
|
@@ -359,23 +364,23 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
359
364
|
], 4),
|
|
360
365
|
h("div", {
|
|
361
366
|
class: "vfp-flex-1 vfp-transition-opacity vfp-duration-300",
|
|
362
|
-
style:
|
|
367
|
+
style: N({ background: p.value ? "rgba(0,0,0,0.3)" : "transparent" }),
|
|
363
368
|
onClick: e[1] || (e[1] = (n) => p.value = !1)
|
|
364
369
|
}, null, 4)
|
|
365
|
-
], 4)) :
|
|
370
|
+
], 4)) : A("", !0),
|
|
366
371
|
h("div", {
|
|
367
372
|
ref_key: "scrollContainerRef",
|
|
368
373
|
ref: s,
|
|
369
374
|
class: "vfp-pdf-container vfp-w-full vfp-h-full vfp-overflow-auto"
|
|
370
375
|
}, [
|
|
371
|
-
P.value ? (
|
|
376
|
+
P.value ? (S(), se(fe, {
|
|
372
377
|
key: 0,
|
|
373
378
|
message: P.value
|
|
374
|
-
}, null, 8, ["message"])) :
|
|
375
|
-
!P.value &&
|
|
379
|
+
}, null, 8, ["message"])) : A("", !0),
|
|
380
|
+
!P.value && _.value ? (S(), O("div", Te, [...e[2] || (e[2] = [
|
|
376
381
|
h("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
|
|
377
|
-
])])) :
|
|
378
|
-
P.value ?
|
|
382
|
+
])])) : A("", !0),
|
|
383
|
+
P.value ? A("", !0) : (S(), O("div", Ce, [...e[3] || (e[3] = [
|
|
379
384
|
h("div", { class: "pdf-pages vfp-flex vfp-flex-col vfp-gap-4" }, null, -1)
|
|
380
385
|
])]))
|
|
381
386
|
], 512)
|
|
@@ -385,4 +390,4 @@ const xe = { class: "vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-
|
|
|
385
390
|
export {
|
|
386
391
|
Ie as default
|
|
387
392
|
};
|
|
388
|
-
//# sourceMappingURL=index-
|
|
393
|
+
//# sourceMappingURL=index-BxF1PDtG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BxF1PDtG.mjs","sources":["../../src/renderers/Pdf/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';\nimport { configurePdfWorker } from '@eternalheart/file-preview-core';\n// @ts-ignore - pdfjs-dist 类型路径\nimport * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\nimport { X, ZoomIn, ZoomOut, ChevronLeft, ChevronRight, Menu, RefreshCw } from 'lucide-vue-next';\nimport { ToolbarEventEmitter } from '../base.types';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\ninterface PdfOutlineItem {\n title: string;\n dest: any;\n items?: PdfOutlineItem[];\n}\n\ninterface PdfPageProxy {\n getViewport(opts: { scale: number }): { width: number; height: number };\n render(opts: { canvasContext: CanvasRenderingContext2D; viewport: { width: number; height: number } }): {\n promise: Promise<void>;\n cancel(): void;\n };\n}\n\ninterface PdfDocumentProxy {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfPageProxy>;\n getOutline(): Promise<PdfOutlineItem[] | null>;\n destroy(): void;\n}\n\ninterface PageState {\n element: HTMLDivElement;\n rendered: boolean;\n rendering: boolean;\n renderTask: any;\n}\n\nconst props = defineProps<{\n url: string;\n}>();\n\nconst emitter = new ToolbarEventEmitter();\n\nconst { t } = useTranslator();\n\n// 内部状态管理\nconst zoom = ref(1);\nconst currentPage = ref(1);\nconst showOutline = ref(false);\nconst numPages = ref(0);\nconst error = ref<string | null>(null);\nconst isLoading = ref(true);\nconst outline = ref<PdfOutlineItem[]>([]);\nconst activeOutlineItem = ref<string | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nconst scrollContainerRef = ref<HTMLDivElement | null>(null);\nconst outlinePageMap = new Map<string, number>();\nlet pdfDoc: PdfDocumentProxy | null = null;\nconst pageStates = new Map<number, PageState>();\nlet observer: IntersectionObserver | null = null;\n\n// 通知工具栏变化\nwatch([zoom, currentPage, numPages, showOutline, () => outline.value.length], () => {\n emitter.notify();\n});\n\n// 工具栏操作\nconst handleZoomIn = () => {\n zoom.value = Math.min(3, zoom.value + 0.1);\n};\nconst handleZoomOut = () => {\n zoom.value = Math.max(0.5, zoom.value - 0.1);\n};\nconst handleReset = () => {\n zoom.value = 1;\n};\nconst handlePrevPage = () => {\n if (!scrollContainerRef.value) return;\n const pages = scrollContainerRef.value.querySelectorAll('[data-page-number]');\n const targetPage = pages[Math.max(0, currentPage.value - 2)];\n if (targetPage) {\n targetPage.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n};\nconst handleNextPage = () => {\n if (!scrollContainerRef.value) return;\n const pages = scrollContainerRef.value.querySelectorAll('[data-page-number]');\n const targetPage = pages[Math.min(pages.length - 1, currentPage.value)];\n if (targetPage) {\n targetPage.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n};\nconst handleToggleOutline = () => {\n showOutline.value = !showOutline.value;\n};\n\n// 工具栏配置\nconst getToolbarGroups = (): ToolbarGroup[] => {\n const groups: ToolbarGroup[] = [];\n\n if (numPages.value === 0) return groups;\n\n if (outline.value.length > 0) {\n groups.push({\n items: [\n {\n type: 'button',\n icon: Menu,\n tooltip: t.value('toolbar.outline'),\n action: handleToggleOutline,\n active: showOutline.value,\n },\n ],\n });\n }\n\n groups.push({\n items: [\n {\n type: 'button',\n icon: ChevronLeft,\n tooltip: t.value('toolbar.prev_page'),\n action: handlePrevPage,\n disabled: currentPage.value <= 1,\n },\n {\n type: 'text',\n content: `${currentPage.value} / ${numPages.value}`,\n minWidth: '4rem',\n },\n {\n type: 'button',\n icon: ChevronRight,\n tooltip: t.value('toolbar.next_page'),\n action: handleNextPage,\n disabled: currentPage.value >= numPages.value,\n },\n ],\n });\n\n groups.push({\n items: [\n {\n type: 'button',\n icon: ZoomOut,\n tooltip: t.value('toolbar.zoom_out'),\n action: handleZoomOut,\n disabled: zoom.value <= 0.5,\n },\n {\n type: 'text',\n content: `${Math.round(zoom.value * 100)}%`,\n minWidth: '3rem',\n },\n {\n type: 'button',\n icon: ZoomIn,\n tooltip: t.value('toolbar.zoom_in'),\n action: handleZoomIn,\n disabled: zoom.value >= 3,\n },\n ],\n });\n\n groups.push({\n items: [\n {\n type: 'button',\n icon: RefreshCw,\n tooltip: t.value('toolbar.reset'),\n action: handleReset,\n },\n ],\n });\n\n return groups;\n};\n\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n onToolbarChange: (listener) => emitter.subscribe(listener),\n});\n\n// 构建大纲-页码映射\nconst buildOutlinePageMap = async (items: PdfOutlineItem[], pdfDocument: PdfDocumentProxy, depth = 0) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const itemKey = `${item.title}-${i}-${depth}`;\n\n try {\n let pageNumber: number | null = null;\n const dest = item.dest;\n\n if (typeof dest === 'string') {\n const namedDest = await (pdfDocument as any).getDestination?.(dest);\n if (namedDest && namedDest[0] && typeof namedDest[0] === 'object') {\n pageNumber = await (pdfDocument as any).getPageIndex?.(namedDest[0]) + 1;\n }\n } else if (Array.isArray(dest) && dest[0] && typeof dest[0] === 'object') {\n pageNumber = await (pdfDocument as any).getPageIndex?.(dest[0]) + 1;\n }\n\n if (pageNumber !== null && pageNumber > 0) {\n outlinePageMap.set(itemKey, pageNumber);\n }\n\n if (item.items && item.items.length > 0) {\n await buildOutlinePageMap(item.items, pdfDocument, depth + 1);\n }\n } catch (err) {\n // 静默失败\n }\n }\n};\n\n// 根据当前页码更新激活的大纲项\nconst updateActiveOutlineByPage = (page: number) => {\n let closestItem: string | null = null;\n let closestDistance = Infinity;\n\n outlinePageMap.forEach((itemPage, itemKey) => {\n if (itemPage <= page) {\n const distance = page - itemPage;\n if (distance < closestDistance) {\n closestDistance = distance;\n closestItem = itemKey;\n }\n }\n });\n\n if (closestItem !== activeOutlineItem.value) {\n activeOutlineItem.value = closestItem;\n }\n};\n\n// 处理大纲点击跳转\nconst handleOutlineClick = async (dest: any, itemKey: string) => {\n if (!pdfDoc || !scrollContainerRef.value) return;\n\n try {\n let pageNumber: number;\n\n if (typeof dest === 'string') {\n const namedDest = await (pdfDoc as any).getDestination?.(dest);\n if (namedDest && namedDest[0]) {\n pageNumber = await (pdfDoc as any).getPageIndex?.(namedDest[0]) + 1;\n } else {\n return;\n }\n } else if (Array.isArray(dest) && dest[0]) {\n pageNumber = await (pdfDoc as any).getPageIndex?.(dest[0]) + 1;\n } else {\n return;\n }\n\n // 设置激活项\n activeOutlineItem.value = itemKey;\n\n // 滚动到目标页面\n const pages = scrollContainerRef.value.querySelectorAll('[data-page-number]');\n const targetPage = pages[pageNumber - 1];\n if (targetPage) {\n targetPage.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n // 跳转后自动关闭侧边栏\n setTimeout(() => { showOutline.value = false; }, 300);\n } catch (err) {\n console.error('大纲跳转失败:', err);\n }\n};\n\n// 渲染大纲项(递归组件会更复杂,这里用简单的方式)\nconst renderOutlineItemsHtml = (items: PdfOutlineItem[], depth = 0): string => {\n return items.map((item, i) => {\n const itemKey = `${item.title}-${i}-${depth}`;\n const isActive = activeOutlineItem.value === itemKey;\n const activeClass = isActive\n ? 'vfp-bg-surface-2 vfp-text-fg-primary vfp-font-medium'\n : 'vfp-text-fg-secondary hover:vfp-text-fg-primary hover:vfp-bg-surface-2';\n\n let html = `<li style=\"margin-left: ${depth > 0 ? 16 : 0}px;\">\n <button\n data-outline-key=\"${itemKey}\"\n data-outline-dest=\"${JSON.stringify(item.dest).replace(/\"/g, '"')}\"\n class=\"vfp-w-full vfp-text-left vfp-py-2 vfp-px-3 vfp-text-sm vfp-rounded vfp-transition-all vfp-truncate ${activeClass}\"\n title=\"${item.title}\"\n >\n ${item.title}\n </button>`;\n\n if (item.items && item.items.length > 0) {\n html += `<ul>${renderOutlineItemsHtml(item.items, depth + 1)}</ul>`;\n }\n\n html += '</li>';\n return html;\n }).join('');\n};\n\nconst renderPage = async (pageNumber: number, scale: number) => {\n if (!pdfDoc) return;\n const state = pageStates.get(pageNumber);\n if (!state || state.rendering) return;\n\n state.rendering = true;\n\n try {\n const page = await pdfDoc.getPage(pageNumber);\n const viewport = page.getViewport({ scale });\n\n const canvas = document.createElement('canvas');\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n canvas.style.maxWidth = '100%';\n canvas.style.height = 'auto';\n canvas.style.borderRadius = '0';\n canvas.style.display = 'block';\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const renderTask = page.render({ canvasContext: ctx, viewport });\n state.renderTask = renderTask;\n await renderTask.promise;\n\n state.element.innerHTML = '';\n state.element.appendChild(canvas);\n\n state.rendered = true;\n } catch (err: any) {\n if (err?.name !== 'RenderingCancelledException') {\n console.error(`渲染页面 ${pageNumber} 失败:`, err);\n }\n } finally {\n state.rendering = false;\n state.renderTask = null;\n }\n};\n\nconst clearPageCanvas = (pageNumber: number) => {\n const state = pageStates.get(pageNumber);\n if (!state) return;\n\n if (state.renderTask) {\n state.renderTask.cancel();\n state.renderTask = null;\n }\n\n const canvas = state.element.querySelector('canvas');\n if (canvas) {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n }\n\n state.element.innerHTML = '';\n state.rendered = false;\n state.rendering = false;\n};\n\nconst initPagePlaceholders = () => {\n if (!pdfDoc || !scrollContainerRef.value) return;\n\n const wrapper = scrollContainerRef.value.querySelector('.pdf-pages') as HTMLDivElement | null;\n if (!wrapper) return;\n\n wrapper.innerHTML = '';\n pageStates.clear();\n\n for (let i = 1; i <= numPages.value; i++) {\n const pageDiv = document.createElement('div');\n pageDiv.className = 'vfp-pdf-page-placeholder vfp-relative vfp-flex vfp-justify-center';\n pageDiv.setAttribute('data-page-number', String(i));\n wrapper.appendChild(pageDiv);\n\n pageStates.set(i, {\n element: pageDiv,\n rendered: false,\n rendering: false,\n renderTask: null,\n });\n\n if (observer) {\n observer.observe(pageDiv);\n }\n }\n};\n\nconst loadPdf = async () => {\n error.value = null;\n isLoading.value = true;\n numPages.value = 0;\n\n if (pdfDoc) {\n try {\n pdfDoc.destroy();\n } catch {\n // ignore\n }\n pdfDoc = null;\n }\n\n try {\n // 确保 GlobalWorkerOptions 已配置(延迟初始化)\n if (!pdfjsLib.GlobalWorkerOptions.workerSrc) {\n // 自动配置:使用 CDN 作为默认值(不覆盖用户已配置的值)\n configurePdfWorker(pdfjsLib);\n\n // 开发环境提示\n const isDev = typeof process !== 'undefined' && process.env?.NODE_ENV === 'development';\n if (isDev) {\n console.warn(\n '[vue-file-preview] PDF worker 自动配置为 CDN。若环境存在 CSP 限制或加载失败,请配置同源本地文件:\\n' +\n `import { configurePdfWorker } from '@eternalheart/vue-file-preview';\\n` +\n `import * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs';\\n` +\n `configurePdfWorker(pdfjsLib, { workerSrc: '/pdfjs/pdf.worker.min.mjs' });`\n );\n }\n }\n\n const loadingTask = pdfjsLib.getDocument({ url: props.url });\n pdfDoc = (await loadingTask.promise) as PdfDocumentProxy;\n const total = pdfDoc.numPages;\n\n numPages.value = total;\n currentPage.value = 1;\n\n // 提取大纲\n try {\n const outlineData = await pdfDoc.getOutline();\n if (outlineData) {\n outline.value = outlineData;\n // 构建大纲-页码映射\n outlinePageMap.clear();\n await buildOutlinePageMap(outlineData, pdfDoc);\n }\n } catch (err) {\n console.warn('PDF 大纲提取失败:', err);\n }\n\n isLoading.value = false;\n } catch (err) {\n console.error('PDF 加载错误:', err);\n error.value = t.value('pdf.load_failed');\n isLoading.value = false;\n }\n};\n\nconst handleScroll = () => {\n if (!scrollContainerRef.value || pageStates.size === 0) return;\n\n const container = scrollContainerRef.value;\n const scrollTop = container.scrollTop;\n const containerHeight = container.clientHeight;\n const scrollCenter = scrollTop + containerHeight / 2;\n\n let currentVisiblePage = 1;\n let minDistance = Infinity;\n\n pageStates.forEach((state, pageNumber) => {\n const rect = state.element.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const pageCenter = rect.top - containerRect.top + rect.height / 2 + scrollTop;\n\n const distance = Math.abs(scrollCenter - pageCenter);\n if (distance < minDistance) {\n minDistance = distance;\n currentVisiblePage = pageNumber;\n }\n });\n\n if (currentVisiblePage !== currentPage.value) {\n currentPage.value = currentVisiblePage;\n }\n};\n\n// 设置大纲点击事件代理\nconst setupOutlineEventDelegation = () => {\n nextTick(() => {\n const outlineContainer = containerRef.value?.querySelector('.outline-items');\n if (!outlineContainer) return;\n\n outlineContainer.addEventListener('click', (e: Event) => {\n const target = e.target as HTMLElement;\n const button = target.closest('[data-outline-key]');\n if (!button) return;\n\n const itemKey = button.getAttribute('data-outline-key');\n const destStr = button.getAttribute('data-outline-dest');\n if (!itemKey || !destStr) return;\n\n try {\n const dest = JSON.parse(destStr);\n handleOutlineClick(dest, itemKey);\n } catch (err) {\n console.error('解析大纲目标失败:', err);\n }\n });\n });\n};\n\n// 监听 URL 变化\nwatch(() => props.url, () => {\n if (props.url) {\n loadPdf();\n }\n}, { immediate: true });\n\n// 监听 numPages 变化,初始化占位符\nwatch(numPages, (val) => {\n if (val > 0) {\n nextTick(() => {\n initPagePlaceholders();\n });\n }\n});\n\n// 监听 zoom 变化\nwatch(() => zoom.value, () => {\n pageStates.forEach((state, pageNumber) => {\n if (state.rendered) {\n clearPageCanvas(pageNumber);\n }\n });\n\n setTimeout(() => {\n if (observer && scrollContainerRef.value) {\n pageStates.forEach((state) => {\n observer?.unobserve(state.element);\n observer?.observe(state.element);\n });\n }\n }, 150);\n});\n\n// 监听 currentPage 变化,更新大纲高亮\nwatch(() => currentPage.value, (page) => {\n if (page > 0 && outlinePageMap.size > 0) {\n updateActiveOutlineByPage(page);\n }\n});\n\n// 监听 activeOutlineItem 变化,更新大纲 UI\nwatch(activeOutlineItem, () => {\n nextTick(() => {\n const outlineContainer = containerRef.value?.querySelector('.outline-items');\n if (!outlineContainer) return;\n\n // 重新渲染大纲项\n if (outline.value.length > 0) {\n outlineContainer.innerHTML = `<ul>${renderOutlineItemsHtml(outline.value)}</ul>`;\n // 重新绑定事件\n setupOutlineEventDelegation();\n }\n });\n});\n\n// 监听 outline 变化,渲染大纲\nwatch(outline, () => {\n nextTick(() => {\n const outlineContainer = containerRef.value?.querySelector('.outline-items');\n if (!outlineContainer && outline.value.length > 0) {\n // 容器还没准备好,等待下一次\n setTimeout(() => {\n const container = containerRef.value?.querySelector('.outline-items');\n if (container) {\n container.innerHTML = `<ul>${renderOutlineItemsHtml(outline.value)}</ul>`;\n setupOutlineEventDelegation();\n }\n }, 100);\n } else if (outlineContainer && outline.value.length > 0) {\n outlineContainer.innerHTML = `<ul>${renderOutlineItemsHtml(outline.value)}</ul>`;\n setupOutlineEventDelegation();\n }\n });\n}, { deep: true });\n\nonMounted(() => {\n // 设置 IntersectionObserver\n observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n const pageNumber = Number(entry.target.getAttribute('data-page-number'));\n if (!pageNumber) return;\n\n if (entry.isIntersecting) {\n renderPage(pageNumber, zoom.value);\n } else {\n const state = pageStates.get(pageNumber);\n if (state && state.rendered) {\n clearPageCanvas(pageNumber);\n }\n }\n });\n },\n {\n root: scrollContainerRef.value,\n rootMargin: '500px 0px',\n threshold: 0,\n }\n );\n\n // 监听滚动\n const container = scrollContainerRef.value;\n if (container) {\n container.addEventListener('scroll', handleScroll);\n }\n});\n\nonBeforeUnmount(() => {\n // 清理\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n\n const container = scrollContainerRef.value;\n if (container) {\n container.removeEventListener('scroll', handleScroll);\n }\n\n pageStates.forEach((state) => {\n if (state.renderTask) {\n state.renderTask.cancel();\n }\n });\n pageStates.clear();\n\n if (pdfDoc) {\n try {\n pdfDoc.destroy();\n } catch {\n // ignore\n }\n pdfDoc = null;\n }\n});\n</script>\n\n<template>\n <div ref=\"containerRef\" class=\"vfp-relative vfp-w-full vfp-h-full\">\n <!-- 大纲侧边栏 -->\n <div\n v-if=\"outline.length > 0\"\n class=\"vfp-absolute vfp-inset-0 vfp-z-20 vfp-flex vfp-transition-opacity vfp-duration-300\"\n :style=\"{\n opacity: showOutline ? 1 : 0,\n pointerEvents: showOutline ? 'auto' : 'none',\n }\"\n >\n <div\n class=\"vfp-w-72 vfp-max-w-[80%] vfp-h-full vfp-bg-surface-overlay vfp-backdrop-blur-xl vfp-border-r vfp-border-line-weak vfp-flex vfp-flex-col vfp-shadow-2xl vfp-transition-transform vfp-duration-300\"\n :style=\"{ transform: showOutline ? 'translateX(0)' : 'translateX(-100%)' }\"\n >\n <div class=\"vfp-flex vfp-items-center vfp-justify-between vfp-px-4 vfp-py-3 vfp-border-b vfp-border-line-weak vfp-flex-shrink-0\">\n <span class=\"vfp-text-fg-primary vfp-font-medium vfp-text-sm\">{{ t('toolbar.outline') }}</span>\n <button\n @click=\"showOutline = false\"\n class=\"vfp-text-fg-tertiary hover:vfp-text-fg-primary vfp-transition-colors\"\n >\n <X class=\"vfp-w-4 vfp-h-4\" />\n </button>\n </div>\n <div class=\"vfp-flex-1 vfp-overflow-y-auto vfp-py-4 vfp-px-1 outline-items\" v-html=\"renderOutlineItemsHtml(outline)\" />\n </div>\n <div\n class=\"vfp-flex-1 vfp-transition-opacity vfp-duration-300\"\n :style=\"{ background: showOutline ? 'rgba(0,0,0,0.3)' : 'transparent' }\"\n @click=\"showOutline = false\"\n />\n </div>\n\n <div\n ref=\"scrollContainerRef\"\n class=\"vfp-pdf-container vfp-w-full vfp-h-full vfp-overflow-auto\"\n >\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <div v-if=\"!error && isLoading\" class=\"vfp-flex vfp-items-center vfp-justify-center vfp-min-h-screen\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <div v-if=\"!error\" class=\"vfp-flex vfp-flex-col vfp-items-center\">\n <div class=\"pdf-pages vfp-flex vfp-flex-col vfp-gap-4\" />\n </div>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emitter","ToolbarEventEmitter","t","useTranslator","zoom","ref","currentPage","showOutline","numPages","error","isLoading","outline","activeOutlineItem","containerRef","scrollContainerRef","outlinePageMap","pdfDoc","pageStates","observer","watch","handleZoomIn","handleZoomOut","handleReset","handlePrevPage","targetPage","handleNextPage","pages","handleToggleOutline","__expose","groups","Menu","ChevronLeft","ChevronRight","ZoomOut","ZoomIn","RefreshCw","listener","buildOutlinePageMap","items","pdfDocument","depth","i","item","itemKey","pageNumber","dest","namedDest","_a","_b","_c","updateActiveOutlineByPage","page","closestItem","closestDistance","itemPage","distance","handleOutlineClick","err","renderOutlineItemsHtml","activeClass","html","renderPage","scale","state","viewport","canvas","ctx","renderTask","clearPageCanvas","initPagePlaceholders","wrapper","pageDiv","loadPdf","pdfjsLib","configurePdfWorker","total","outlineData","handleScroll","container","scrollTop","containerHeight","scrollCenter","currentVisiblePage","minDistance","rect","containerRect","pageCenter","setupOutlineEventDelegation","nextTick","outlineContainer","e","button","destStr","val","onMounted","entries","entry","onBeforeUnmount","_createElementBlock","_normalizeStyle","_createElementVNode","_hoisted_1","_hoisted_2","_toDisplayString","_unref","_createVNode","X","_createBlock","RendererError","_openBlock","_hoisted_4","_cache","_hoisted_5"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComponent as Os, ref as Ie, onMounted as ws, onBeforeUnmount as Es, watch as Mr, openBlock as ge, createElementBlock as ke, normalizeStyle as Pr, toDisplayString as K, computed as mt, createElementVNode as P, unref as ae, createBlock as Br, Fragment as Dn, createCommentVNode as Wt, withDirectives as Nr, vModelText as _r, renderList as Gr, createVNode as qt } from "vue";
|
|
2
|
-
import { u as Hr, a as Vr, c as zr } from "./index-
|
|
2
|
+
import { u as Hr, a as Vr, c as zr } from "./index-wS-r1RZP.mjs";
|
|
3
3
|
import { _ as jr } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
|
|
4
4
|
var mn = 0, Rs = -3;
|
|
5
5
|
function at() {
|
|
@@ -12349,4 +12349,4 @@ abcdefghijklmnopqrstuvwxyz
|
|
|
12349
12349
|
export {
|
|
12350
12350
|
Lf as default
|
|
12351
12351
|
};
|
|
12352
|
-
//# sourceMappingURL=index-
|
|
12352
|
+
//# sourceMappingURL=index-C8i_4_NE.mjs.map
|