import {Constants} from "../constants";
import {addScript} from "../util/addScript";
import {addStyle} from "../util/addStyle";
declare const hljs: {
highlightBlock(element: Element): void;
};
export const highlightRender = (hljsOption?: IHljs, element: HTMLElement | Document = document,
cdn = Constants.CDN) => {
let style = hljsOption.style;
if (!Constants.CODE_THEME.includes(style)) {
style = "github";
}
const vditorHljsStyle = document.getElementById("vditorHljsStyle") as HTMLLinkElement;
const href = `${cdn}/dist/js/highlight.js/styles/${style}.css`;
if (vditorHljsStyle && vditorHljsStyle.href !== href) {
vditorHljsStyle.remove();
}
addStyle(`${cdn}/dist/js/highlight.js/styles/${style}.css`, "vditorHljsStyle");
if (hljsOption.enable === false) {
return;
}
const codes = element.querySelectorAll("pre > code");
if (codes.length === 0) {
return;
}
addScript(`${cdn}/dist/js/highlight.js/highlight.pack.js`, "vditorHljsScript").then(() => {
element.querySelectorAll("pre > code").forEach((block) => {
// ir & wysiwyg 区域不渲染
if (block.parentElement.classList.contains("vditor-ir__marker--pre") ||
block.parentElement.classList.contains("vditor-wysiwyg__pre")) {
return;
}
if (block.classList.contains("language-mermaid") || block.classList.contains("language-flowchart") ||
block.classList.contains("language-echarts") || block.classList.contains("language-mindmap") ||
block.classList.contains("language-plantuml") ||
block.classList.contains("language-abc") || block.classList.contains("language-graphviz") ||
block.classList.contains("language-math")) {
return;
}
hljs.highlightBlock(block);
if (!hljsOption.lineNumber) {
return;
}
block.classList.add("vditor-linenumber");
let linenNumberTemp: HTMLDivElement = block.querySelector(".vditor-linenumber__temp");
if (!linenNumberTemp) {
linenNumberTemp = document.createElement("div");
linenNumberTemp.className = "vditor-linenumber__temp";
block.insertAdjacentElement("beforeend", linenNumberTemp);
}
const whiteSpace = getComputedStyle(block).whiteSpace;
let isSoftWrap = false;
if (whiteSpace === "pre-wrap" || whiteSpace === "pre-line") {
isSoftWrap = true;
}
let lineNumberHTML = "";
const lineList = block.textContent.split(/\r\n|\r|\n/g);
lineList.pop();
lineList.map((line) => {
let lineHeight = "";
if (isSoftWrap) {
linenNumberTemp.textContent = line || "\n";
lineHeight = ` style="height:${linenNumberTemp.getBoundingClientRect().height}px"`;
}
lineNumberHTML += ``;
});
linenNumberTemp.style.display = "none";
lineNumberHTML = `${lineNumberHTML}`;
block.insertAdjacentHTML("beforeend", lineNumberHTML);
});
});
};