fuc-new/doc/node_modules/@vuepress/helper/lib/client/utils/getHeaders.js
hellcat 6adbc04d4b 1
2025-10-03 17:17:08 +08:00

68 lines
2.1 KiB
JavaScript

const DEFAULT_HEADER_SELECTOR = [...new Array(6)]
.map((_, i) => `[vp-content] h${i + 1}`)
.join(',');
export const resolveHeaders = (headers, levels = 2) => {
if (levels === false) {
return [];
}
const [high, low] = typeof levels === 'number'
? [levels, levels]
: levels === 'deep'
? [2, 6]
: levels;
const allowedHeaders = headers.filter((header) => header.level >= high && header.level <= low);
const result = [];
// eslint-disable-next-line no-restricted-syntax
outer: for (let i = 0; i < allowedHeaders.length; i++) {
const current = allowedHeaders[i];
if (i === 0) {
result.push(current);
}
else {
for (let j = i - 1; j >= 0; j--) {
const prev = allowedHeaders[j];
if (prev.level < current.level) {
prev.children.push(current);
continue outer;
}
}
result.push(current);
}
}
return result;
};
const serializeHeader = (h, ignore = []) => {
let text;
if (ignore.length) {
const clone = h.cloneNode(true);
clone.querySelectorAll(ignore.join(',')).forEach((el) => {
el.remove();
});
text = clone.textContent || '';
}
else {
text = h.textContent || '';
}
return text.trim();
};
export const getHeadersFromDom = (selector = DEFAULT_HEADER_SELECTOR, ignore = []) => Array.from(document.querySelectorAll(selector))
.filter((el) => el.id && el.hasChildNodes())
.map((el) => ({
element: el,
title: serializeHeader(el, ignore),
link: `#${el.id}`,
slug: el.id,
level: Number(el.tagName[1]),
children: [],
}));
/**
* Get headers of current page.
*
* 获取当前页面的标题
*
* @param options - Options for getting headers / 获取标题的选项
*
* @returns Array of header items / 标题项数组
*/
export const getHeaders = ({ selector = DEFAULT_HEADER_SELECTOR, levels = 2, ignore = [], } = {}) => resolveHeaders(getHeadersFromDom(selector, ignore), levels);