Skip to content

Commit

Permalink
fix(helper): fix getHeaders function
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Jan 16, 2025
1 parent bcf4a89 commit 6143a5c
Showing 1 changed file with 29 additions and 54 deletions.
83 changes: 29 additions & 54 deletions tools/helper/src/client/utils/getHeaders.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,16 @@
export interface Header {
/**
* The level of the header
*
* `1` to `6` for `<h1>` to `<h6>`
*/
level: number
/**
* The title of the header
*/
title: string
/**
* The slug of the header
*
* Typically the `id` attr of the header anchor
*/
slug: string
/**
* Link of the header
*
* Typically using `#${slug}` as the anchor hash
*/
link: string
/**
* The children of the header
*/
children: Header[]
}
import type { PageHeader } from 'vuepress/shared'

export type HeaderLevels = number | 'deep' | false | [number, number]

export type MenuItem = Omit<Header, 'children' | 'slug'> & {
export type HeaderItem = Omit<PageHeader, 'children'> & {
element: HTMLHeadElement
children?: MenuItem[]
children?: HeaderItem[]
}

export const resolveHeaders = (
headers: MenuItem[],
headers: HeaderItem[],
levels: HeaderLevels = 2,
): MenuItem[] => {
): HeaderItem[] => {
if (levels === false) {
return []
}
Expand All @@ -52,26 +25,27 @@ export const resolveHeaders = (
(h) => h.level >= high && h.level <= low,
)

const res: MenuItem[] = []
const result: HeaderItem[] = []

// eslint-disable-next-line no-restricted-syntax
outer: for (let i = 0; i < allowedHeaders.length; i++) {
const cur = allowedHeaders[i]
const current = allowedHeaders[i]

if (i === 0) {
res.push(cur)
result.push(current)
} else {
for (let j = i - 1; j >= 0; j--) {
const prev = allowedHeaders[j]
if (prev.level < cur.level) {
;(prev.children ??= []).push(cur)
if (prev.level < current.level) {
;(prev.children ??= []).push(current)
continue outer
}
}
res.push(cur)
result.push(current)
}
}

return res
return result
}

const serializeHeader = (h: Element, ignore: string[] = []): string => {
Expand All @@ -92,6 +66,20 @@ const serializeHeader = (h: Element, ignore: string[] = []): string => {
return text.trim()
}

export const getHeadersFromDom = (
selector: string,
ignore: string[],
): HeaderItem[] =>
Array.from(document.querySelectorAll(selector))
.filter((el) => el.id && el.hasChildNodes())
.map((el) => ({
element: el as HTMLHeadingElement,
title: serializeHeader(el, ignore),
link: `#${el.id}`,
slug: el.id,
level: Number(el.tagName[1]),
}))

export interface GetHeadersOptions {
/**
* The selector of the headers.
Expand Down Expand Up @@ -134,18 +122,5 @@ export const getHeaders = ({
.join(','),
levels = 2,
ignore = [],
}: GetHeadersOptions = {}): MenuItem[] => {
const headers = Array.from(document.querySelectorAll(selector))
.filter((el) => el.id && el.hasChildNodes())
.map((el) => {
const level = Number(el.tagName[1])
return {
element: el as HTMLHeadElement,
title: serializeHeader(el, ignore),
link: `#${el.id}`,
slug: el.id,
level,
}
})
return resolveHeaders(headers, levels)
}
}: GetHeadersOptions = {}): HeaderItem[] =>
resolveHeaders(getHeadersFromDom(selector, ignore), levels)

0 comments on commit 6143a5c

Please sign in to comment.