mirror of
https://github.com/litruv/Docs-Viewer.git
synced 2026-07-24 02:36:07 +10:00
Enhance internal link handling and improve document loading logic; refine styles for better mobile experience
This commit is contained in:
69
index.js
69
index.js
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
56
styles.css
56
styles.css
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user