162 lines
6.0 KiB
HTML

{% macro render_headings(headings, level=1) %}
<ul class="toctree-l{{ level }}" style="list-style: none; padding-left: 0; overflow-x: auto; white-space: nowrap;">
{% for item in headings %}
<li class="toctree-l{{ level }}{% if item.current %} current{% endif %}"
{% if item.children %}
x-data="{ expanded: {{ 'true' if item.current else 'false' }} }"
{% endif %}
style="white-space: nowrap;">
<div class="menu-item" style="display: inline-flex; align-items: center; justify-content: space-between; width: 100%; white-space: nowrap;">
<!-- Link and file open section -->
<div style="display: inline-flex; align-items: center; white-space: nowrap;">
<a class="reference internal{% if item.children %} expandable{% endif %}{% if item.current %} current{% endif %}"
href="{{ pathto(item.link).replace('#', '') }}{% if item.anchor %}#{{ item.anchor }}{% endif %}"
style="text-decoration: none; white-space: nowrap;">
{{ item.text }}
</a>
</div>
<!-- Expand-Toggle Button -->
{% if item.children %}
<button @click.prevent.stop="expanded = !expanded" type="button" class="toggle-button"
style="background: none; border: none; padding: 0; margin-left: auto;">
<span x-show="!expanded">
<svg fill="currentColor" height="18px" stroke="none" viewBox="0 0 24 24" width="18px"
xmlns="http://www.w3.org/2000/svg">
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path>
</svg>
</span>
<span x-show="expanded">&#9660;</span>
</button>
{% endif %}
</div>
{% if item.children %}
<div x-show="expanded">
{{ render_headings(item.children, level+1) }}
</div>
{% endif %}
</li>
{% endfor %}
</ul>
{% endmacro %}
{% if local_md_headings or local_subfolders %}
<div class="local-md-headings">
{% if local_md_headings %}
<div class="current-index" x-data x-init="initCurrentNav()">
<p class="caption" role="heading">
<span class="caption-text">Current Index</span>
</p>
{{ render_headings(local_md_headings) }}
<br />
</div>
{% endif %}
{% if local_subfolders %}
<div class="full-index">
<p class="caption" role="heading">
<span class="caption-text">Full Index</span>
</p>
{{ render_headings(local_subfolders) }}
<br />
</div>
{% endif %}
</div>
{% endif %}
<script>
// Initialize the current navigation
function initCurrentNav() {
// If Alpine is available, wait until the DOM is updated.
if (window.Alpine && typeof window.Alpine.nextTick === 'function') {
window.Alpine.nextTick(processNav);
} else {
processNav();
}
}
// Process all navigation links within the .current-index container.
function processNav() {
var currentHash = window.location.hash;
console.log("initCurrentNav: Current hash:", currentHash);
if (!currentHash) return;
var links = document.querySelectorAll('.current-index a.reference.internal');
links.forEach(function(link) {
var href = link.getAttribute("href");
console.log("initCurrentNav: Checking link:", href);
// If the link is hash-only (e.g. "#setup-guide")
if (href && href.trim().startsWith("#")) {
if (href.trim() === currentHash.trim()) {
console.log("initCurrentNav: Match found for hash-only link:", href);
markAsCurrent(link);
}
}
// Otherwise, if the link includes a file and a hash, compare only the hash part.
else if (href && href.indexOf('#') !== -1) {
var parts = href.split('#');
var linkHash = "#" + parts[1].trim();
console.log("initCurrentNav: Extracted link hash:", linkHash);
if (linkHash === currentHash.trim()) {
console.log("initCurrentNav: Match found for link with file and hash:", href);
markAsCurrent(link);
}
}
else {
console.log("initCurrentNav: No match for link:", href);
}
});
// After processing, open all submenus under current items.
openCurrentSubmenus();
}
// Mark the link's parent li and all ancestor li elements as current.
function markAsCurrent(link) {
var li = link.closest("li");
if (!li) {
console.log("markAsCurrent: No parent li found for link:", link);
return;
}
li.classList.add("current");
console.log("markAsCurrent: Marked li as current:", li);
// If Alpine.js is in use, set its "expanded" property to true.
if (li.__x && li.__x.$data) {
li.__x.$data.expanded = true;
console.log("markAsCurrent: Set Alpine expanded on li:", li);
}
// Propagate upward: mark all ancestor li elements as current.
var parentLi = li.parentElement.closest("li");
while (parentLi) {
parentLi.classList.add("current");
if (parentLi.__x && parentLi.__x.$data) {
parentLi.__x.$data.expanded = true;
}
console.log("markAsCurrent: Propagated current to ancestor li:", parentLi);
parentLi = parentLi.parentElement.closest("li");
}
}
// Open all submenu elements under list items marked as current.
function openCurrentSubmenus() {
document.querySelectorAll('.current-index li.current').forEach(function(li) {
li.querySelectorAll("[x-show]").forEach(function(elem) {
if (elem.style.display === "none") {
elem.style.display = "block";
console.log("openCurrentSubmenus: Opened submenu element:", elem);
}
});
});
}
// Re-trigger when the hash changes.
window.addEventListener("hashchange", function() {
console.log("Hash changed, reinitializing current nav...");
initCurrentNav();
});
// Wait until the window fully loads, then initialize the navigation.
window.addEventListener("load", function() {
console.log("Window loaded, initializing current nav...");
initCurrentNav();
});
</script>