Enhance internal link handling and improve document loading logic; refine styles for better mobile experience

This commit is contained in:
2025-01-30 06:47:56 +11:00
parent df4efddcab
commit d33e470d15
2 changed files with 97 additions and 30 deletions

View File

@@ -20,6 +20,9 @@ async function initializeMarked() {
const isExternal = href.startsWith('http') || href.startsWith('https');
const attrs = isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
const link = originalLink(href, title, text);
if (!isExternal && href.startsWith('?')) {
return link.replace(/^<a /, '<a data-internal="true" ');
}
return link.replace(/^<a /, `<a${attrs} `);
};
@@ -327,6 +330,7 @@ async function loadDocument(path) {
documentOutline.innerHTML = '';
const headings = documentContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
const headingLinks = new Map();
headings.forEach(heading => {
if (!heading.id) {
@@ -338,34 +342,50 @@ async function loadDocument(path) {
const link = document.createElement('a');
link.href = `${window.location.pathname}${window.location.search}#${heading.id}`;
link.textContent = heading.textContent;
link.style.paddingLeft = (heading.tagName[1] - 1) * 15 + 'px';
// Add non-zero indentation
link.style.paddingLeft = (heading.tagName[1] * 15) + 'px';
headingLinks.set(heading, link);
// Add extra space to avoid scrolling beneath the header
heading.style.scrollMarginTop = 'var(--title-bar-height)';
link.onclick = (e) => {
e.preventDefault();
history.pushState(null, '', link.href);
document.querySelectorAll('.highlight').forEach(el => {
el.classList.remove('highlight');
});
if (heading) {
heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
heading.classList.remove('highlight');
void heading.offsetWidth;
heading.classList.add('highlight');
heading.scrollIntoView({ behavior: 'smooth' });
} else {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
};
documentOutline.appendChild(link);
});
if (window.location.hash) {
const id = window.location.hash.substring(1);
const heading = document.getElementById(id);
if (heading) {
heading.classList.add('highlight');
heading.scrollIntoView({ behavior: 'smooth' });
}
// Replace the existing observer with this refined version
const observer = new IntersectionObserver((entries) => {
const visibleHeadings = entries
.filter(entry => entry.isIntersecting)
.sort((a, b) => a.target.offsetTop - b.target.offsetTop);
if (visibleHeadings.length) {
documentOutline.querySelectorAll('a').forEach(a => a.classList.remove('active'));
const topHeading = visibleHeadings[0].target;
const link = headingLinks.get(topHeading);
if (link) link.classList.add('active');
}
}, {
rootMargin: '-48px 0px -60% 0px',
threshold: [0, 0.25, 0.5, 0.75, 1]
});
headings.forEach(heading => observer.observe(heading));
// Clean up observer when loading new document
return () => observer.disconnect();
Prism.highlightAll();
} catch (error) {
console.error('Error loading document:', error);
document.getElementById('document-content').innerHTML =
@@ -417,3 +437,20 @@ window.addEventListener('load', () => {
'<div class="error">Failed to load documentation. Please try refreshing the page.</div>';
});
});
// Globally intercept clicks on internal links
document.addEventListener('click', async (e) => {
const target = e.target.closest('a[data-internal="true"]');
if (target) {
e.preventDefault();
const slug = target.href.split('?').pop();
const indexData = await fetch('index.json').then(res => res.json());
const matchingDoc = findDocumentBySlug(indexData.documents, slug);
if (matchingDoc) {
await loadDocument(matchingDoc.path);
// Scroll to the top after loading
window.scrollTo({ top: 0, behavior: 'smooth' });
history.pushState(null, '', target.href);
}
}
});

View File

@@ -67,8 +67,9 @@ body {
right: 0;
bottom: 0;
width: var(--doc-outline-width);
background: var(--ifm-background-color);
background: var(--ifm-background-color); /* Change to match main content */
overflow-y: auto;
border-left: none; /* Explicitly remove border */
}
.content {
@@ -81,15 +82,17 @@ body {
#file-index {
flex: 1;
overflow-y: auto;
padding-top: 20px;
}
@media (max-width: 1000px) {
.menu-button {
display: flex;
display: flex !important; /* Force display on mobile */
}
.left-sidebar {
left: -100%;
width: min(var(--doc-sidebar-width), 80vw); /* Limit width on mobile */
transition: left 0.3s ease; /* Change to left transition */
box-shadow: none;
}
@@ -108,19 +111,35 @@ body {
margin-right: 0;
padding: 1rem;
}
.markdown-content {
padding: 0 0.5rem;
}
#file-index {
padding-top: 0.75rem; /* Add top padding to menu */
}
}
@media (max-width: 480px) {
.content {
padding: 0.75rem 0.5rem;
}
.markdown-content {
padding: 0 0.25rem;
}
}
.menu-button {
display: none;
display: none; /* Initially hidden */
background: none;
border: none;
color: var(--ifm-color-content);
padding: 8px;
cursor: pointer;
font-size: 1.2rem;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
@@ -134,7 +153,6 @@ body {
}
.sidebar {
background-color: var(--ifm-background-surface-color);
color: var(--ifm-color-content);
overflow-y: auto;
border-color: var(--ifm-border-color);
@@ -145,7 +163,7 @@ body {
color: var(--ifm-color-content);
text-decoration: none;
display: block;
padding: 0.4rem 1.2rem;
padding: 0.6rem 1.2rem; /* Increased vertical padding */
font-size: 0.875rem;
border-left: 2px solid transparent;
}
@@ -198,7 +216,7 @@ body {
}
.social-links {
padding: 1rem 1rem 0.5rem;
padding: 0.5rem 1rem;
display: flex;
justify-content: center;
gap: 1rem;
@@ -219,7 +237,7 @@ social-links a:hover {
.subtitle {
margin-top: auto; /* Push to bottom of flex container */
text-align: center;
padding: 0 1rem 1rem;
padding: 0.5rem 1rem;
font-size: 0.8rem;
color: var(--ifm-color-content-secondary);
border-top: 1px solid var(--ifm-border-color);
@@ -240,7 +258,6 @@ social-links a:hover {
.content {
flex: 1;
background-color: var(--ifm-background-color);
padding: 2rem 3rem;
overflow-y: scroll;
min-width: 0; /* Fix flexbox content overflow */
color: var(--ifm-color-content);
@@ -262,17 +279,23 @@ social-links a:hover {
}
#document-outline {
padding: 0 1rem; /* Add horizontal padding */
padding: 1rem;
}
#document-outline a {
color: var(--ifm-color-content-secondary);
border-left: 2px solid transparent;
margin: 2px 0;
padding: 0.4rem 1rem; /* Adjust padding to match */
padding: 0.25em 1rem; /* Adjust padding to match */
transition: all 0.2s ease;
}
#document-outline a.active {
color: var(--ifm-color-primary);
border-left-color: var(--ifm-color-primary);
background: rgba(33, 150, 243, 0.1);
}
/* Markdown content styling */
.markdown-content {
line-height: 1.7;
font-size: 1rem;
@@ -477,3 +500,10 @@ social-links a:hover {
.title-text .page-title {
font-size: 0.9rem;
}
#document-outline a.active {
/* Remove any forced padding-left: 0; here */
color: var(--ifm-color-primary);
border-left-color: var(--ifm-color-primary);
background: rgba(33, 150, 243, 0.1);
}