Skip to content

Commit

Permalink
feat: support title navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
YangFong committed Mar 8, 2025
1 parent b0ab984 commit f459881
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 15 deletions.
29 changes: 29 additions & 0 deletions src/stores/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ export const useStore = defineStore(`store`, () => {

const readingTime = ref<ReadTimeResults | null>(null)

// 文章标题
const titleList = ref<{
url: string
title: string
level: number
}[]>([])

// 更新编辑器
const editorRefresh = () => {
codeThemeChange()
Expand All @@ -192,6 +199,26 @@ export const useStore = defineStore(`store`, () => {
const { markdownContent, readingTime: readingTimeResult } = renderer.parseFrontMatterAndContent(editor.value!.getValue())
readingTime.value = readingTimeResult
let outputTemp = marked.parse(markdownContent) as string

// 提取标题
const div = document.createElement('div')
div.innerHTML = outputTemp
const list = div.querySelectorAll<HTMLElement>(`[data-heading]`)

titleList.value = []
let i = 0
for (const item of list) {
item.setAttribute(`id`, `${i}`)
titleList.value.push({
url: `#${i}`,
title: `${item.innerText}`,
level: Number(item.tagName.slice(1))
})
i++
}

outputTemp = div.innerHTML

outputTemp = DOMPurify.sanitize(outputTemp)

// 阅读时间及字数统计
Expand Down Expand Up @@ -501,6 +528,8 @@ export const useStore = defineStore(`store`, () => {
delPost,
isOpenPostSlider,
isOpenRightSlider,

titleList,
}
})

Expand Down
3 changes: 2 additions & 1 deletion src/utils/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ export function initRenderer(opts: IOpts) {

function styledContent(styleLabel: string, content: string, tagName?: string): string {
const tag = tagName ?? styleLabel
return `<${tag} ${styles(styleLabel)}>${content}</${tag}>`

return `<${tag} ${/^h\d$/.test(tag) ? `data-heading="true"` : ``} ${styles(styleLabel)}>${content}</${tag}>`
}

function addFootnote(title: string, link: string): number {
Expand Down
37 changes: 23 additions & 14 deletions src/views/CodemirrorEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -418,24 +418,33 @@ onMounted(() => {
</ContextMenuContent>
</ContextMenu>
</div>
<div
id="preview"
ref="preview"
class="preview-wrapper flex-1 p-5"
>
<div id="output-wrapper" :class="{ output_night: !backLight }">
<div class="preview border-x-1 shadow-xl">
<section id="output" v-html="output" />
<div v-if="isCoping" class="loading-mask">
<div class="loading-mask-box">
<div class="loading__img" />
<span>正在生成</span>
<div class="relative flex-1">
<div
id="preview"
ref="preview"
class="preview-wrapper p-5"
>
<div id="output-wrapper" :class="{ output_night: !backLight }">
<div class="preview border-x-1 shadow-xl">
<section id="output" v-html="output" />
<div v-if="isCoping" class="loading-mask">
<div class="loading-mask-box">
<div class="loading__img" />
<span>正在生成</span>
</div>
</div>
</div>
</div>
</div>

<BackTop target="preview" :right="40" :bottom="40" />
<BackTop target="preview" :right="40" :bottom="40" />
</div>
<ul class="bg-background absolute left-0 top-0 max-h-100 w-60 overflow-auto border rounded-2 p-2 text-sm shadow">
<li v-for="(item, index) in store.titleList" :key="index" class="line-clamp-1 py-1 leading-6 hover:bg-gray-300 dark:hover:bg-gray-600" :style="{paddingLeft: item.level - 0.5 + 'em'}">
<a :href="item.url">
{{ item.title }}
</a>
</li>
</ul>
</div>
<CssEditor class="order-2 flex-1" />
<RightSlider class="order-2" />
Expand Down

0 comments on commit f459881

Please sign in to comment.