diff --git a/console/src/components/editor/DefaultEditor.vue b/console/src/components/editor/DefaultEditor.vue index 20be95be2..a4002674b 100644 --- a/console/src/components/editor/DefaultEditor.vue +++ b/console/src/components/editor/DefaultEditor.vue @@ -87,6 +87,7 @@ import { usePluginModuleStore } from "@/stores/plugin"; import type { PluginModule } from "@halo-dev/console-shared"; import { useDebounceFn } from "@vueuse/core"; import { onBeforeUnmount } from "vue"; +import { generateAnchor } from "@/utils/anchor"; const { t } = useI18n(); @@ -436,7 +437,7 @@ const handleGenerateTableOfContent = () => { editor.value.state.doc.descendants((node, pos) => { if (node.type.name === "heading") { - const id = `heading-${headings.length + 1}`; + const id = generateAnchor(node.textContent); if (node.attrs.id !== id) { transaction?.setNodeMarkup(pos, undefined, { diff --git a/console/src/utils/__tests__/anchor.spec.ts b/console/src/utils/__tests__/anchor.spec.ts new file mode 100644 index 000000000..4d9f63492 --- /dev/null +++ b/console/src/utils/__tests__/anchor.spec.ts @@ -0,0 +1,28 @@ +import { describe, it, expect } from "vitest"; +import { generateAnchor } from "../anchor"; + +describe("generateAnchor", () => { + it("should handle basic text", () => { + expect(generateAnchor("Hello World")).toBe("hello-world"); + }); + + it("should trim whitespace", () => { + expect(generateAnchor(" Hello World ")).toBe("hello-world"); + }); + + it("should replace multiple spaces with a single dash", () => { + expect(generateAnchor("Hello World")).toBe("hello-world"); + }); + + it("should handle Chinese characters", () => { + expect(generateAnchor("你好")).toBe("%E4%BD%A0%E5%A5%BD"); + }); + + it("should handle special characters", () => { + expect(generateAnchor("Hello@#World$")).toBe("hello%40%23world%24"); + }); + + it("should handle empty string", () => { + expect(generateAnchor("")).toBe(""); + }); +}); diff --git a/console/src/utils/anchor.ts b/console/src/utils/anchor.ts new file mode 100644 index 000000000..3845a5ac4 --- /dev/null +++ b/console/src/utils/anchor.ts @@ -0,0 +1,5 @@ +export function generateAnchor(text: string) { + return encodeURIComponent( + String(text).trim().toLowerCase().replace(/\s+/g, "-") + ); +}