101 lines
2.6 KiB
TypeScript
101 lines
2.6 KiB
TypeScript
// 删除标题里面没用的内容
|
||
const pickTextNode = (el: HTMLElement) => {
|
||
const fragment = document.createDocumentFragment();
|
||
|
||
while (el.firstChild) {
|
||
// 检查当前子节点是否是文本节点
|
||
if (el.firstChild.nodeType === Node.TEXT_NODE) {
|
||
// 如果是文本节点,将其移动到 DocumentFragment 中
|
||
fragment.appendChild(el.firstChild);
|
||
}
|
||
else {
|
||
el.removeChild(el.firstChild);
|
||
}
|
||
}
|
||
|
||
return fragment.textContent;
|
||
}
|
||
|
||
// 删除里面的属性
|
||
const removeAttributes = (el: HTMLElement) => {
|
||
const attrs = el.attributes;
|
||
|
||
Array.from(attrs).forEach((attr) => {
|
||
el.removeAttribute(attr.name);
|
||
});
|
||
}
|
||
|
||
// 格式化 HTML 内容
|
||
export const formatHTML = (html: string, extraFormatter?: (doc: Document) => void) => {
|
||
const nextDocument = document.implementation.createHTMLDocument();
|
||
|
||
nextDocument.documentElement.innerHTML = html;
|
||
|
||
// 删除标题内无效元素
|
||
const titleEl = nextDocument.querySelectorAll("h2, h3, h4, h5, h6") as NodeListOf<HTMLElement>;
|
||
titleEl.forEach((el) => {
|
||
// 遍历并移除所有属性
|
||
removeAttributes(el);
|
||
|
||
el.innerHTML = pickTextNode(el);
|
||
});
|
||
|
||
// 优化 p 标签
|
||
const paraEl = nextDocument.querySelectorAll("p") as NodeListOf<HTMLElement>;
|
||
paraEl.forEach((el) => {
|
||
// 删除空的 p 标签
|
||
if (!el.innerHTML.trim()) {
|
||
el.remove();
|
||
}
|
||
|
||
// 遍历并移除所有属性
|
||
removeAttributes(el);
|
||
|
||
// 删除 p 里面的 span 替换成普通 Text,应该没用的
|
||
const spanEl = el.querySelectorAll("span");
|
||
spanEl.forEach((el) => {
|
||
el.parentNode.replaceChild(document.createTextNode(el.innerText), el);
|
||
});
|
||
});
|
||
|
||
// 删除 figure 标签
|
||
const figureEl = nextDocument.querySelectorAll("figure") as NodeListOf<HTMLElement>;
|
||
figureEl.forEach((el) => {
|
||
const img = el.querySelector("img");
|
||
|
||
if (img) {
|
||
el.innerHTML = "";
|
||
el.appendChild(img);
|
||
}
|
||
});
|
||
|
||
// 删除 style 标签
|
||
const stylesEl = nextDocument.querySelectorAll("style");
|
||
stylesEl.forEach((el) => {
|
||
el.remove();
|
||
});
|
||
|
||
// 提取 pre 下面的内容
|
||
const preEl = nextDocument.querySelectorAll("pre");
|
||
preEl.forEach((el) => {
|
||
removeAttributes(el);
|
||
|
||
// hljs / prism
|
||
const codeEl = el.querySelector("code") as HTMLElement;
|
||
|
||
if (codeEl) {
|
||
const nextCodeEl = document.createElement("code");
|
||
nextCodeEl.innerText = codeEl.innerText;
|
||
|
||
el.innerHTML = null;
|
||
el.appendChild(nextCodeEl);
|
||
}
|
||
});
|
||
|
||
if (extraFormatter) {
|
||
extraFormatter(nextDocument);
|
||
}
|
||
|
||
return nextDocument.documentElement.innerHTML;
|
||
}
|