mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-05 20:39:59 -08:00
[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>
This commit is contained in:
8
Doxyfile
8
Doxyfile
@@ -1375,7 +1375,7 @@ HTML_FILE_EXTENSION = .html
|
||||
# of the possible markers and block names see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_HEADER =
|
||||
HTML_HEADER = doc/doxygen/html/header.html
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||
# generated HTML page. If the tag is left blank Doxygen will generate a standard
|
||||
@@ -1385,7 +1385,7 @@ HTML_HEADER =
|
||||
# that Doxygen normally uses.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FOOTER =
|
||||
HTML_FOOTER = doc/doxygen/html/footer.html
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||
@@ -1415,7 +1415,7 @@ HTML_STYLESHEET =
|
||||
# documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_STYLESHEET = doxygen_style.css
|
||||
HTML_EXTRA_STYLESHEET = doc/doxygen/css/doxygen_style.css
|
||||
|
||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the HTML output directory. Note
|
||||
@@ -1425,7 +1425,7 @@ HTML_EXTRA_STYLESHEET = doxygen_style.css
|
||||
# files will be copied as-is; there are no commands or markers available.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_EXTRA_FILES = doc/doxygen/js/graph_toggle.js
|
||||
|
||||
# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
|
||||
# should be rendered with a dark or light theme.
|
||||
|
||||
88
doc/doxygen/css/doxygen_style.css
Normal file
88
doc/doxygen/css/doxygen_style.css
Normal file
@@ -0,0 +1,88 @@
|
||||
/* === Accent Tuning for Doxygen Dark Mode === */
|
||||
|
||||
/* Main accent color */
|
||||
:root {
|
||||
--main-accent: #33a946;
|
||||
}
|
||||
|
||||
/* Links */
|
||||
a, a:visited {
|
||||
color: var(--main-accent) !important;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #4fd467 !important; /* lighter green */
|
||||
}
|
||||
|
||||
/* Project title */
|
||||
#projectname {
|
||||
color: var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Current sidebar item */
|
||||
#side-nav .selected {
|
||||
border-left: 3px solid var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.tablist li.current {
|
||||
background: var(--main-accent) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* Search box focus */
|
||||
#MSearchField:focus {
|
||||
outline: 1px solid var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Code block border highlight */
|
||||
pre, code {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border-color: var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Graph toggle (caller / callee two-button) */
|
||||
.graph-toggle {
|
||||
display: inline-flex;
|
||||
margin: 0.5em 0;
|
||||
border: 1px solid #444;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.graph-toggle button {
|
||||
flex: 1 1 50%;
|
||||
padding: 0.35em 0.8em;
|
||||
background: transparent;
|
||||
color: #aaa;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.graph-toggle button:hover:not(:disabled) {
|
||||
background: #222;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.graph-toggle button.active {
|
||||
background: var(--main-accent);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.graph-toggle button:disabled,
|
||||
.graph-toggle button.disabled {
|
||||
opacity: 0.45;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* small accessibility focus ring */
|
||||
.graph-toggle button:focus {
|
||||
outline: 2px solid rgba(51, 169, 70, 0.3);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
27
doc/doxygen/html/footer.html
Normal file
27
doc/doxygen/html/footer.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!-- HTML footer for doxygen 1.14.0-->
|
||||
<!-- start footer part -->
|
||||
<script src="$relpath^graph_toggle.js"></script>
|
||||
<!--BEGIN GENERATE_TREEVIEW-->
|
||||
<div class="navpath" id="nav-path"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
$navpath
|
||||
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img alt="doxygen"
|
||||
class="footer"
|
||||
height="31" src="$relpath^doxygen.svg"
|
||||
width="104"/></a>
|
||||
$doxygenversion
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--END GENERATE_TREEVIEW-->
|
||||
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||
<hr class="footer"/>
|
||||
<address class="footer"><small>
|
||||
$generatedby <a href="https://www.doxygen.org/index.html"><img alt="doxygen" class="footer"
|
||||
height="31" src="$relpath^doxygen.svg" width="104"/></a>
|
||||
$doxygenversion
|
||||
</small></address>
|
||||
</div><!-- doc-content -->
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
</body>
|
||||
</html>
|
||||
81
doc/doxygen/html/header.html
Normal file
81
doc/doxygen/html/header.html
Normal file
@@ -0,0 +1,81 @@
|
||||
<!-- HTML header for doxygen 1.14.0-->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html lang="$langISO" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta content="text/xhtml;charset=UTF-8" http-equiv="Content-Type"/>
|
||||
<meta content="IE=11" http-equiv="X-UA-Compatible"/>
|
||||
<meta content="Doxygen $doxygenversion" name="generator"/>
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport"/>
|
||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||
<!--BEGIN PROJECT_ICON-->
|
||||
<link href="$relpath^$projecticon" rel="icon" type="image/x-icon"/>
|
||||
<!--END PROJECT_ICON-->
|
||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<!--BEGIN FULL_SIDEBAR-->
|
||||
<script type="text/javascript">var page_layout = 1;</script>
|
||||
<!--END FULL_SIDEBAR-->
|
||||
<script src="$relpath^jquery.js" type="text/javascript"></script>
|
||||
<script src="$relpath^dynsections.js" type="text/javascript"></script>
|
||||
<!--BEGIN COPY_CLIPBOARD-->
|
||||
<script src="$relpath^clipboard.js" type="text/javascript"></script>
|
||||
<!--END COPY_CLIPBOARD-->
|
||||
$treeview
|
||||
$search
|
||||
$mathjax
|
||||
$darkmode
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css"/>
|
||||
$extrastylesheet
|
||||
</head>
|
||||
<body>
|
||||
<!--BEGIN FULL_SIDEBAR-->
|
||||
<div class="ui-resizable side-nav-resizable" id="side-nav"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<!--END FULL_SIDEBAR-->
|
||||
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
|
||||
<!--BEGIN TITLEAREA-->
|
||||
<div id="titlearea">
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr id="projectrow">
|
||||
<!--BEGIN PROJECT_LOGO-->
|
||||
<td id="projectlogo"><img $logosize alt="Logo" src="$relpath^$projectlogo"/></td>
|
||||
<!--END PROJECT_LOGO-->
|
||||
<!--BEGIN PROJECT_NAME-->
|
||||
<td id="projectalign">
|
||||
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber"> $projectnumber</span>
|
||||
<!--END PROJECT_NUMBER-->
|
||||
</div>
|
||||
<!--BEGIN PROJECT_BRIEF-->
|
||||
<div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
||||
</td>
|
||||
<!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME-->
|
||||
<!--BEGIN PROJECT_BRIEF-->
|
||||
<td>
|
||||
<div id="projectbrief">$projectbrief</div>
|
||||
</td>
|
||||
<!--END PROJECT_BRIEF-->
|
||||
<!--END !PROJECT_NAME-->
|
||||
<!--BEGIN DISABLE_INDEX-->
|
||||
<!--BEGIN SEARCHENGINE-->
|
||||
<!--BEGIN !FULL_SIDEBAR-->
|
||||
<td>$searchbox</td>
|
||||
<!--END !FULL_SIDEBAR-->
|
||||
<!--END SEARCHENGINE-->
|
||||
<!--END DISABLE_INDEX-->
|
||||
</tr>
|
||||
<!--BEGIN SEARCHENGINE-->
|
||||
<!--BEGIN FULL_SIDEBAR-->
|
||||
<tr>
|
||||
<td colspan="2">$searchbox</td>
|
||||
</tr>
|
||||
<!--END FULL_SIDEBAR-->
|
||||
<!--END SEARCHENGINE-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--END TITLEAREA-->
|
||||
<!-- end header part -->
|
||||
147
doc/doxygen/js/graph_toggle.js
Normal file
147
doc/doxygen/js/graph_toggle.js
Normal file
@@ -0,0 +1,147 @@
|
||||
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");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
/* === Accent Tuning for Doxygen Dark Mode === */
|
||||
|
||||
/* Main accent color */
|
||||
:root {
|
||||
--main-accent: #33a946;
|
||||
}
|
||||
|
||||
/* Links */
|
||||
a, a:visited {
|
||||
color: var(--main-accent) !important;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #4fd467 !important; /* lighter green */
|
||||
}
|
||||
|
||||
/* Project title */
|
||||
#projectname {
|
||||
color: var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Current sidebar item */
|
||||
#side-nav .selected {
|
||||
border-left: 3px solid var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.tablist li.current {
|
||||
background: var(--main-accent) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* Search box focus */
|
||||
#MSearchField:focus {
|
||||
outline: 1px solid var(--main-accent) !important;
|
||||
}
|
||||
|
||||
/* Code block border highlight */
|
||||
pre, code {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border-color: var(--main-accent) !important;
|
||||
}
|
||||
Reference in New Issue
Block a user