Files
Cockatrice/doc/doxygen/js/graph_toggle.js
BruebachL 0833f94502 [Doxygen] Add javascript to toggle call/caller graph visibility. (#6195)
Took 49 minutes

Took 26 seconds

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2025-09-28 21:22:37 +02:00

148 lines
5.8 KiB
JavaScript

document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".memdoc").forEach(memdoc => {
let callContent = null, callHeader = null;
let callerContent = null, callerHeader = null;
memdoc.querySelectorAll("div.dynheader").forEach(header => {
const text = (header.textContent || "").trim().toLowerCase();
let content = header.nextElementSibling;
let tries = 0;
while (content && !content.classList.contains("dyncontent") && tries < 8) {
content = content.nextElementSibling;
tries++;
}
if (!content) return;
if (text.includes("caller")) {
callerContent = content;
callerHeader = header;
} else if (text.includes("call graph") || text.includes("callgraph") || text.includes("call graph for")) {
callContent = content;
callHeader = header;
} else if (text.includes("call")) {
if (!callContent) {
callContent = content;
callHeader = header;
}
}
});
if (!callContent && !callerContent) return;
if (memdoc.querySelector(".graph-toggle")) return;
const toggle = document.createElement("div");
toggle.className = "graph-toggle";
const callerBtn = document.createElement("button");
callerBtn.type = "button";
callerBtn.textContent = "Caller Graph";
const callBtn = document.createElement("button");
callBtn.type = "button";
callBtn.textContent = "Call Graph";
toggle.appendChild(callerBtn);
toggle.appendChild(callBtn);
const firstHeader = memdoc.querySelector("div.dynheader");
memdoc.insertBefore(toggle, firstHeader || memdoc.firstChild);
// hide everything initially
if (callerContent) {
callerContent.style.display = "none";
callerHeader.style.display = "none";
}
if (callContent) {
callContent.style.display = "none";
callHeader.style.display = "none";
}
// disable missing buttons
if (!callerContent) {
callerBtn.disabled = true;
callerBtn.classList.add("disabled");
}
if (!callContent) {
callBtn.disabled = true;
callBtn.classList.add("disabled");
}
// track current state
let current = null; // "caller", "call", "both", null=hidden
function setActive(type) {
if (type === "caller") {
if (current === "caller") { // hide it
if (callerContent) {
callerContent.style.display = "none";
callerHeader.style.display = "none";
}
current = null;
} else if (current === "call") { // show both
if (callerContent) {
callerContent.style.display = "block";
callerHeader.style.display = "block";
}
current = "both";
} else if (current === "both") { // hide caller only → call only
if (callerContent) {
callerContent.style.display = "none";
callerHeader.style.display = "none";
}
current = "call";
} else { // nothing visible → show caller
if (callerContent) {
callerContent.style.display = "block";
callerHeader.style.display = "block";
}
if (callContent) {
callContent.style.display = "none";
callHeader.style.display = "none";
}
current = "caller";
}
} else if (type === "call") {
if (current === "call") { // hide it
if (callContent) {
callContent.style.display = "none";
callHeader.style.display = "none";
}
current = null;
} else if (current === "caller") { // show both
if (callContent) {
callContent.style.display = "block";
callHeader.style.display = "block";
}
current = "both";
} else if (current === "both") { // hide call only → caller only
if (callContent) {
callContent.style.display = "none";
callHeader.style.display = "none";
}
current = "caller";
} else { // nothing visible → show call only
if (callContent) {
callContent.style.display = "block";
callHeader.style.display = "block";
}
if (callerContent) {
callerContent.style.display = "none";
callerHeader.style.display = "none";
}
current = "call";
}
}
// update button styles
callerBtn.classList.toggle("active", current === "caller" || current === "both");
callBtn.classList.toggle("active", current === "call" || current === "both");
}
callerBtn.addEventListener("click", () => {
if (!callerBtn.disabled) setActive("caller");
});
callBtn.addEventListener("click", () => {
if (!callBtn.disabled) setActive("call");
});
});
});