Skip to content

Commit d5452ca

Browse files
committed
fix(theme): 修复复制给 LLM 按钮渲染与链接复制体验
- 移除 Teleport 与内容更新时的目标节点探测,避免标题未就绪 或页面切换时按钮偶发不显示,降低对渲染时序的耦合。 - 复制“链接”时改为直接输出裸 URL,减少外部工具二次解析 Markdown 超链接的负担,更贴合 LLM 输入场景。
1 parent 503fde5 commit d5452ca

1 file changed

Lines changed: 77 additions & 124 deletions

File tree

course/.vitepress/theme/copyToLLM.ts

Lines changed: 77 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
1-
import {
2-
Teleport,
3-
computed,
4-
defineComponent,
5-
h,
6-
nextTick,
7-
onMounted,
8-
ref,
9-
} from "vue";
10-
import { onContentUpdated, useData, withBase } from "vitepress";
11-
12-
const targetId = "copy-llm-actions";
1+
import { computed, defineComponent, h, ref } from "vue";
2+
import { useData, withBase } from "vitepress";
133

144
const actionRowStyle = {
155
display: "flex",
@@ -61,36 +51,16 @@ const itemStyle = {
6151

6252
export default defineComponent({
6353
setup() {
64-
const { frontmatter, page, title } = useData();
54+
const { frontmatter, page } = useData();
6555
const open = ref(false);
6656
const copied = ref<"link" | "markdown" | "error" | null>(null);
67-
const targetReady = ref(false);
6857
const llmPath = computed(() => withBase(`/llms/${page.value.filePath}`));
6958
const llmUrl = computed(() =>
7059
typeof window === "undefined"
7160
? ""
7261
: new URL(llmPath.value, window.location.origin).href,
7362
);
7463

75-
function ensureTarget(): void {
76-
const title = document.querySelector(".vp-doc h1");
77-
if (!title) {
78-
targetReady.value = false;
79-
return;
80-
}
81-
82-
let target = document.getElementById(targetId);
83-
if (!target) {
84-
target = document.createElement("div");
85-
target.id = targetId;
86-
}
87-
88-
if (target.previousElementSibling !== title) {
89-
title.insertAdjacentElement("afterend", target);
90-
}
91-
targetReady.value = true;
92-
}
93-
9464
async function copyText(text: string): Promise<void> {
9565
if (navigator.clipboard) {
9666
await navigator.clipboard.writeText(text);
@@ -109,9 +79,10 @@ export default defineComponent({
10979

11080
async function copy(kind: "link" | "markdown"): Promise<void> {
11181
try {
82+
// 链接:直接复制裸 URL(不是 [标题](URL) 这种 Markdown 超链接格式)
11283
const text =
11384
kind === "link"
114-
? `[${title.value}](${llmUrl.value})`
85+
? llmUrl.value
11586
: await fetch(llmPath.value)
11687
.then((response) => {
11788
if (!response.ok) throw new Error(`HTTP ${response.status}`);
@@ -145,112 +116,94 @@ export default defineComponent({
145116
);
146117
}
147118

148-
onMounted(() => nextTick(ensureTarget));
149-
onContentUpdated(() => nextTick(ensureTarget));
150-
151119
return () => {
152-
if (
153-
frontmatter.value.copyToLLM === false ||
154-
page.value.isNotFound ||
155-
!targetReady.value
156-
) {
157-
return h("div");
120+
if (frontmatter.value.copyToLLM === false || page.value.isNotFound) {
121+
return null;
158122
}
159123

160-
return h(Teleport, { to: `#${targetId}` }, [
161-
h("div", { class: "copy_llm", style: actionRowStyle }, [
124+
return h("div", { class: "copy_llm", style: actionRowStyle }, [
125+
h("div", { style: { position: "relative", display: "inline-block" } }, [
162126
h(
163-
"div",
127+
"button",
164128
{
165-
style: {
166-
position: "relative",
167-
display: "inline-block",
129+
type: "button",
130+
style: triggerStyle,
131+
onClick: () => {
132+
open.value = !open.value;
168133
},
169134
},
170135
[
171136
h(
172-
"button",
137+
"svg",
173138
{
174-
type: "button",
175-
style: triggerStyle,
176-
onClick: () => {
177-
open.value = !open.value;
178-
},
139+
width: "18",
140+
height: "18",
141+
viewBox: "0 0 24 24",
142+
fill: "none",
143+
stroke: "currentColor",
144+
"stroke-width": "2",
145+
"stroke-linecap": "round",
146+
"stroke-linejoin": "round",
147+
"aria-hidden": "true",
179148
},
180149
[
181-
h(
182-
"svg",
183-
{
184-
width: "18",
185-
height: "18",
186-
viewBox: "0 0 24 24",
187-
fill: "none",
188-
stroke: "currentColor",
189-
"stroke-width": "2",
190-
"stroke-linecap": "round",
191-
"stroke-linejoin": "round",
192-
"aria-hidden": "true",
193-
},
194-
[
195-
h("rect", {
196-
x: "9",
197-
y: "9",
198-
width: "13",
199-
height: "13",
200-
rx: "2",
201-
ry: "2",
202-
}),
203-
h("path", {
204-
d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",
205-
}),
206-
],
207-
),
208-
copied.value === "error"
209-
? "复制失败"
210-
: copied.value
211-
? "已复制"
212-
: "复制给 LLM",
213-
h(
214-
"svg",
215-
{
216-
width: "14",
217-
height: "14",
218-
viewBox: "0 0 24 24",
219-
fill: "none",
220-
stroke: "currentColor",
221-
"stroke-width": "2",
222-
"stroke-linecap": "round",
223-
"stroke-linejoin": "round",
224-
"aria-hidden": "true",
225-
},
226-
[h("path", { d: "m6 9 6 6 6-6" })],
227-
),
150+
h("rect", {
151+
x: "9",
152+
y: "9",
153+
width: "13",
154+
height: "13",
155+
rx: "2",
156+
ry: "2",
157+
}),
158+
h("path", {
159+
d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",
160+
}),
228161
],
229162
),
230-
open.value
231-
? h("div", { style: menuStyle }, [
232-
h(
233-
"button",
234-
{
235-
type: "button",
236-
style: itemStyle,
237-
onClick: () => copy("link"),
238-
},
239-
"复制 Markdown 链接",
240-
),
241-
h(
242-
"button",
243-
{
244-
type: "button",
245-
style: itemStyle,
246-
onClick: () => copy("markdown"),
247-
},
248-
"复制 Markdown 正文",
249-
),
250-
])
251-
: null,
163+
copied.value === "error"
164+
? "复制失败"
165+
: copied.value
166+
? "已复制"
167+
: "复制给 LLM",
168+
h(
169+
"svg",
170+
{
171+
width: "14",
172+
height: "14",
173+
viewBox: "0 0 24 24",
174+
fill: "none",
175+
stroke: "currentColor",
176+
"stroke-width": "2",
177+
"stroke-linecap": "round",
178+
"stroke-linejoin": "round",
179+
"aria-hidden": "true",
180+
},
181+
[h("path", { d: "m6 9 6 6 6-6" })],
182+
),
252183
],
253184
),
185+
open.value
186+
? h("div", { style: menuStyle }, [
187+
h(
188+
"button",
189+
{
190+
type: "button",
191+
style: itemStyle,
192+
onClick: () => copy("link"),
193+
},
194+
"复制 Markdown 链接",
195+
),
196+
h(
197+
"button",
198+
{
199+
type: "button",
200+
style: itemStyle,
201+
onClick: () => copy("markdown"),
202+
},
203+
"复制 Markdown 正文",
204+
),
205+
])
206+
: null,
254207
]),
255208
]);
256209
};

0 commit comments

Comments
 (0)