docs: improve docs page
Some checks failed
Build and Deploy / build (push) Has been cancelled
Flake check / Check flake (push) Has been cancelled
Build and Deploy / deploy (push) Has been cancelled

This commit is contained in:
Leon Schwarzäugl 2026-01-05 05:07:17 +01:00
parent 5ff362e1ea
commit 98b2cb93e2
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84

View file

@ -212,6 +212,117 @@ I also add this javascript to add header pinning functionality to the site, usin
const body = document.body; const body = document.body;
if (!content || !pinnedList || !toggleBtn || !clearAllBtn || !toc) return; if (!content || !pinnedList || !toggleBtn || !clearAllBtn || !toc) return;
function injectSearch() {
// Check if already injected
if (document.getElementById('toc-search-input')) return;
const searchContainer = document.createElement('div');
searchContainer.id = 'toc-search-container';
const searchInput = document.createElement('input');
searchInput.id = 'toc-search-input';
searchInput.type = 'text';
searchInput.placeholder = 'Search TOC...';
searchInput.autocomplete = 'off';
const clearBtn = document.createElement('button');
clearBtn.id = 'toc-search-clear';
clearBtn.type = 'button';
clearBtn.textContent = 'Clear';
searchContainer.appendChild(searchInput);
searchContainer.appendChild(clearBtn);
toc.insertBefore(searchContainer, toc.firstChild);
function filterTOC(term) {
const allLinks = toc.querySelectorAll('a');
allLinks.forEach(link => {
const li = link.closest('li');
if (!li) return;
const text = link.textContent.toLowerCase();
const matches = text.includes(term);
if (matches) {
li.classList.remove('hidden-by-search');
let parent = li.parentElement;
while (parent && parent !== toc) {
if (parent.tagName === 'UL') {
parent.style.display = '';
}
if (parent.tagName === 'LI') {
parent.classList.remove('hidden-by-search');
}
parent = parent.parentElement;
}
} else {
li.classList.add('hidden-by-search');
}
});
if (term === '') {
const allLis = toc.querySelectorAll('li');
allLis.forEach(li => li.classList.remove('hidden-by-search'));
}
}
searchInput.addEventListener('input', function(e) {
const term = e.target.value.toLowerCase();
filterTOC(term);
});
clearBtn.addEventListener('click', function() {
searchInput.value = '';
filterTOC('');
searchInput.focus();
});
}
injectSearch();
function addHeadingLinks() {
const headers = content.querySelectorAll('h1, h2, h3, h4, h5, h6');
headers.forEach(header => {
const id = header.getAttribute('id');
if (!id) return;
if (header.querySelector('.heading-link')) return;
const link = document.createElement('a');
link.className = 'heading-link';
link.href = '#' + id;
link.textContent = '#';
link.title = 'Copy link to this heading';
const pinBtn = header.querySelector('.toc-pin-btn');
if (pinBtn) {
header.insertBefore(link, pinBtn);
} else {
header.appendChild(link);
}
link.addEventListener('click', function(e) {
e.preventDefault();
const url = window.location.origin + window.location.pathname + '#' + id;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(url).then(() => {
const originalText = link.textContent;
link.textContent = '✓';
setTimeout(() => {
link.textContent = originalText;
}, 1000);
}).catch(err => {
console.warn('Failed to copy to clipboard', err);
window.location.hash = id;
});
} else {
window.location.hash = id;
}
});
});
}
addHeadingLinks();
let mobileTocBtn = document.getElementById('mobile-toc-toggle'); let mobileTocBtn = document.getElementById('mobile-toc-toggle');
if (!mobileTocBtn) { if (!mobileTocBtn) {
@ -241,6 +352,31 @@ I also add this javascript to add header pinning functionality to the site, usin
else body.classList.remove('mobile-panel-open'); else body.classList.remove('mobile-panel-open');
} }
document.addEventListener('click', function(e) {
if (window.innerWidth > 1000) return;
if (!anyMobilePanelOpen()) return;
const clickedInsideToc = toc.contains(e.target);
const clickedInsidePinned = pinnedPanel.contains(e.target);
const clickedTocBtn = mobileTocBtn.contains(e.target);
const clickedPinnedBtn = mobilePinnedBtn.contains(e.target);
const clickedInteractive =
e.target.tagName === 'A' ||
e.target.tagName === 'BUTTON' ||
e.target.tagName === 'INPUT' ||
e.target.tagName === 'TEXTAREA' ||
e.target.closest('a') ||
e.target.closest('button');
if (!clickedInsideToc && !clickedInsidePinned && !clickedTocBtn && !clickedPinnedBtn && !clickedInteractive) {
toc.classList.remove('mobile-visible');
pinnedPanel.classList.remove('mobile-visible');
updateBodyMobilePanelState();
}
});
mobileTocBtn.addEventListener('click', function() { mobileTocBtn.addEventListener('click', function() {
const isOpen = toc.classList.toggle('mobile-visible'); const isOpen = toc.classList.toggle('mobile-visible');
if (isOpen) { if (isOpen) {
@ -511,7 +647,7 @@ I also add this javascript to add header pinning functionality to the site, usin
showBtn = document.createElement('button'); showBtn = document.createElement('button');
showBtn.id = 'show-pinned-btn'; showBtn.id = 'show-pinned-btn';
showBtn.type = 'button'; showBtn.type = 'button';
showBtn.textContent = 'Show Pinned'; showBtn.textContent = 'Pinned';
document.body.appendChild(showBtn); document.body.appendChild(showBtn);
} }
@ -725,7 +861,7 @@ I also add this javascript to add header pinning functionality to the site, usin
attachPinBehavior(pinBtn, href, text); attachPinBehavior(pinBtn, href, text);
}); });
const headers = content.querySelectorAll('h2, h3, h4, h5'); const headers = content.querySelectorAll('h2, h3, h4, h5, h6');
headers.forEach(header => { headers.forEach(header => {
const id = header.getAttribute('id'); const id = header.getAttribute('id');
if (!id) return; if (!id) return;
@ -32296,12 +32432,67 @@ This is the stylesheet used by the [[#h:12880c64-229c-4063-9eea-387a97490676][HT
background-color: #232b32; background-color: #232b32;
border-right: 1px solid #2f3b45; border-right: 1px solid #2f3b45;
font-size: 0.9rem; font-size: 0.9rem;
display: flex;
flex-direction: column;
} }
#table-of-contents h2 { #table-of-contents h2 {
display: none; display: none;
} }
#toc-search-container {
margin-bottom: 1rem;
position: sticky;
top: 0;
background-color: #232b32;
z-index: 10;
padding-bottom: 0.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
#toc-search-input {
flex: 1;
padding: 0.5rem;
background-color: #1d252c;
border: 1px solid #2f3b45;
color: #b7c5d3;
border-radius: 4px;
font-size: 0.9rem;
box-sizing: border-box;
}
#toc-search-input:focus {
outline: none;
border-color: #5ec4ff;
}
#toc-search-clear {
padding: 0.5rem 0.7rem;
background-color: #2f3b45;
border: 1px solid #3a4a56;
color: #b7c5d3;
cursor: pointer;
font-size: 0.85rem;
border-radius: 4px;
transition: background-color 0.2s, color 0.2s;
white-space: nowrap;
}
#toc-search-clear:hover {
background-color: #3a4a56;
color: #ff6b6b;
}
.hidden-by-search {
display: none !important;
}
#text-table-of-contents {
flex: 1;
}
#text-table-of-contents ul { #text-table-of-contents ul {
list-style: none; list-style: none;
padding-left: 0; padding-left: 0;
@ -32353,29 +32544,12 @@ This is the stylesheet used by the [[#h:12880c64-229c-4063-9eea-387a97490676][HT
margin-top: 2.2rem; margin-top: 2.2rem;
} }
h1 { h1 { font-size: 2rem; }
font-size: 2rem; h2 { font-size: 1.6rem; }
} h3 { font-size: 1.3rem; }
h4 { font-size: 1.2rem; }
h2 { h5 { font-size: 1.1rem; }
font-size: 1.6rem; h6 { font-size: 1.0rem; }
}
h3 {
font-size: 1.3rem;
}
h4 {
font-size: 1.2rem;
}
h5 {
font-size: 1.1rem;
}
h6 {
font-size: 1.0rem;
}
a { a {
color: #5ec4ff; color: #5ec4ff;
@ -32677,6 +32851,36 @@ This is the stylesheet used by the [[#h:12880c64-229c-4063-9eea-387a97490676][HT
max-width: 100%; max-width: 100%;
padding: 1.5rem 1.25rem; padding: 1.5rem 1.25rem;
} }
#toc-search-container {
top: 3rem;
margin-top: 2.5rem;
}
}
.heading-link {
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0.2s;
margin-left: 0.5rem;
color: #718ca1;
text-decoration: none;
font-size: 0.8em;
vertical-align: middle;
}
.heading-link:hover {
color: #5ec4ff;
text-decoration: none;
}
h1:hover .heading-link,
h2:hover .heading-link,
h3:hover .heading-link,
h4:hover .heading-link,
h5:hover .heading-link,
h6:hover .heading-link {
opacity: 1;
visibility: visible;
} }
@media (max-width: 700px) { @media (max-width: 700px) {