111 lines
5.2 KiB
TypeScript
111 lines
5.2 KiB
TypeScript
import {hasClosestByHeadings} from "../util/hasClosestByHeadings";
|
|
import {mathRender} from "./mathRender";
|
|
|
|
export const outlineRender = (contentElement: HTMLElement, targetElement: Element, vditor?: IVditor) => {
|
|
let tocHTML = "";
|
|
const ids: string[] = [];
|
|
Array.from(contentElement.children).forEach((item: HTMLElement, index: number) => {
|
|
if (hasClosestByHeadings(item)) {
|
|
if (vditor) {
|
|
const lastIndex = item.id.lastIndexOf("_");
|
|
item.id = item.id.substring(0, lastIndex === -1 ? undefined : lastIndex) + "_" + index;
|
|
}
|
|
ids.push(item.id);
|
|
tocHTML += item.outerHTML.replace("<wbr>", "");
|
|
}
|
|
});
|
|
if (tocHTML === "") {
|
|
targetElement.innerHTML = "";
|
|
return "";
|
|
}
|
|
const tempElement = document.createElement("div");
|
|
if (vditor) {
|
|
vditor.lute.SetToC(true);
|
|
if (vditor.currentMode === "wysiwyg" && !vditor.preview.element.contains(contentElement)) {
|
|
tempElement.innerHTML = vditor.lute.SpinVditorDOM("<p>[ToC]</p>" + tocHTML);
|
|
} else if (vditor.currentMode === "ir" && !vditor.preview.element.contains(contentElement)) {
|
|
tempElement.innerHTML = vditor.lute.SpinVditorIRDOM("<p>[ToC]</p>" + tocHTML);
|
|
} else {
|
|
tempElement.innerHTML = vditor.lute.HTML2VditorDOM("<p>[ToC]</p>" + tocHTML);
|
|
}
|
|
vditor.lute.SetToC(vditor.options.preview.markdown.toc);
|
|
} else {
|
|
targetElement.classList.add("vditor-outline");
|
|
const lute = Lute.New();
|
|
lute.SetToC(true);
|
|
tempElement.innerHTML = lute.HTML2VditorDOM("<p>[ToC]</p>" + tocHTML);
|
|
}
|
|
const headingsElement = tempElement.firstElementChild.querySelectorAll("li > span[data-target-id]");
|
|
headingsElement.forEach((item, index) => {
|
|
if (item.nextElementSibling && item.nextElementSibling.tagName === "UL") {
|
|
let iconHTML = "<svg class='vditor-outline__action'><use xlink:href='#vditor-icon-down'></use></svg>";
|
|
if (!document.getElementById("vditorIconScript")) {
|
|
iconHTML = '<svg class="vditor-outline__action" viewBox="0 0 32 32"><path d="M3.76 6.12l12.24 12.213 12.24-12.213 3.76 3.76-16 16-16-16 3.76-3.76z"></path></svg>';
|
|
}
|
|
item.innerHTML = `${iconHTML}<span>${item.innerHTML}</span>`;
|
|
} else {
|
|
item.innerHTML = `<svg></svg><span>${item.innerHTML}</span>`;
|
|
}
|
|
item.setAttribute("data-target-id", ids[index]);
|
|
});
|
|
tocHTML = tempElement.firstElementChild.innerHTML;
|
|
if (headingsElement.length === 0) {
|
|
targetElement.innerHTML = "";
|
|
return tocHTML;
|
|
}
|
|
targetElement.innerHTML = tocHTML;
|
|
if (vditor) {
|
|
mathRender(targetElement as HTMLElement, {
|
|
cdn: vditor.options.cdn,
|
|
math: vditor.options.preview.math,
|
|
});
|
|
}
|
|
targetElement.firstElementChild.addEventListener("click", (event: Event) => {
|
|
let target = event.target as HTMLElement;
|
|
while (target && !target.isEqualNode(targetElement)) {
|
|
if (target.classList.contains("vditor-outline__action")) {
|
|
if (target.classList.contains("vditor-outline__action--close")) {
|
|
target.classList.remove("vditor-outline__action--close");
|
|
target.parentElement.nextElementSibling.setAttribute("style", "display:block");
|
|
} else {
|
|
target.classList.add("vditor-outline__action--close");
|
|
target.parentElement.nextElementSibling.setAttribute("style", "display:none");
|
|
}
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
break;
|
|
} else if (target.getAttribute("data-target-id")) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
const idElement = document.getElementById(target.getAttribute("data-target-id"));
|
|
if (!idElement) {
|
|
return;
|
|
}
|
|
if (vditor) {
|
|
if (vditor.options.height === "auto") {
|
|
let windowScrollY = idElement.offsetTop + vditor.element.offsetTop;
|
|
if (!vditor.options.toolbarConfig.pin) {
|
|
windowScrollY += vditor.toolbar.element.offsetHeight;
|
|
}
|
|
window.scrollTo(window.scrollX, windowScrollY);
|
|
} else {
|
|
if (vditor.element.offsetTop < window.scrollY) {
|
|
window.scrollTo(window.scrollX, vditor.element.offsetTop);
|
|
}
|
|
if (vditor.preview.element.contains(contentElement)) {
|
|
contentElement.parentElement.scrollTop = idElement.offsetTop;
|
|
} else {
|
|
contentElement.scrollTop = idElement.offsetTop;
|
|
}
|
|
}
|
|
} else {
|
|
window.scrollTo(window.scrollX, idElement.offsetTop);
|
|
}
|
|
break;
|
|
}
|
|
target = target.parentElement;
|
|
}
|
|
});
|
|
return tocHTML;
|
|
};
|