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 isExternal = href.startsWith('http') || href.startsWith('https');
|
||||||
const attrs = isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
|
const attrs = isExternal ? ' target="_blank" rel="noopener noreferrer"' : '';
|
||||||
const link = originalLink(href, title, text);
|
const link = originalLink(href, title, text);
|
||||||
|
if (!isExternal && href.startsWith('?')) {
|
||||||
|
return link.replace(/^<a /, '<a data-internal="true" ');
|
||||||
|
}
|
||||||
return link.replace(/^<a /, `<a${attrs} `);
|
return link.replace(/^<a /, `<a${attrs} `);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -327,6 +330,7 @@ async function loadDocument(path) {
|
|||||||
|
|
||||||
documentOutline.innerHTML = '';
|
documentOutline.innerHTML = '';
|
||||||
const headings = documentContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
const headings = documentContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||||
|
const headingLinks = new Map();
|
||||||
|
|
||||||
headings.forEach(heading => {
|
headings.forEach(heading => {
|
||||||
if (!heading.id) {
|
if (!heading.id) {
|
||||||
@@ -338,34 +342,50 @@ async function loadDocument(path) {
|
|||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = `${window.location.pathname}${window.location.search}#${heading.id}`;
|
link.href = `${window.location.pathname}${window.location.search}#${heading.id}`;
|
||||||
link.textContent = heading.textContent;
|
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) => {
|
link.onclick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
history.pushState(null, '', link.href);
|
history.pushState(null, '', link.href);
|
||||||
|
if (heading) {
|
||||||
document.querySelectorAll('.highlight').forEach(el => {
|
heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
el.classList.remove('highlight');
|
heading.classList.remove('highlight');
|
||||||
});
|
void heading.offsetWidth;
|
||||||
|
|
||||||
heading.classList.add('highlight');
|
heading.classList.add('highlight');
|
||||||
|
} else {
|
||||||
heading.scrollIntoView({ behavior: 'smooth' });
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
documentOutline.appendChild(link);
|
documentOutline.appendChild(link);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (window.location.hash) {
|
// Replace the existing observer with this refined version
|
||||||
const id = window.location.hash.substring(1);
|
const observer = new IntersectionObserver((entries) => {
|
||||||
const heading = document.getElementById(id);
|
const visibleHeadings = entries
|
||||||
if (heading) {
|
.filter(entry => entry.isIntersecting)
|
||||||
heading.classList.add('highlight');
|
.sort((a, b) => a.target.offsetTop - b.target.offsetTop);
|
||||||
heading.scrollIntoView({ behavior: 'smooth' });
|
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) {
|
} catch (error) {
|
||||||
console.error('Error loading document:', error);
|
console.error('Error loading document:', error);
|
||||||
document.getElementById('document-content').innerHTML =
|
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>';
|
'<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;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: var(--doc-outline-width);
|
width: var(--doc-outline-width);
|
||||||
background: var(--ifm-background-color);
|
background: var(--ifm-background-color); /* Change to match main content */
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
border-left: none; /* Explicitly remove border */
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
@@ -81,15 +82,17 @@ body {
|
|||||||
#file-index {
|
#file-index {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
padding-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
@media (max-width: 1000px) {
|
||||||
.menu-button {
|
.menu-button {
|
||||||
display: flex;
|
display: flex !important; /* Force display on mobile */
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-sidebar {
|
.left-sidebar {
|
||||||
left: -100%;
|
left: -100%;
|
||||||
|
width: min(var(--doc-sidebar-width), 80vw); /* Limit width on mobile */
|
||||||
transition: left 0.3s ease; /* Change to left transition */
|
transition: left 0.3s ease; /* Change to left transition */
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
@@ -108,19 +111,35 @@ body {
|
|||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
padding: 1rem;
|
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 {
|
.menu-button {
|
||||||
display: none;
|
display: none; /* Initially hidden */
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
color: var(--ifm-color-content);
|
color: var(--ifm-color-content);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.2rem;
|
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
@@ -134,7 +153,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
background-color: var(--ifm-background-surface-color);
|
|
||||||
color: var(--ifm-color-content);
|
color: var(--ifm-color-content);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
border-color: var(--ifm-border-color);
|
border-color: var(--ifm-border-color);
|
||||||
@@ -145,7 +163,7 @@ body {
|
|||||||
color: var(--ifm-color-content);
|
color: var(--ifm-color-content);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.4rem 1.2rem;
|
padding: 0.6rem 1.2rem; /* Increased vertical padding */
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
border-left: 2px solid transparent;
|
border-left: 2px solid transparent;
|
||||||
}
|
}
|
||||||
@@ -198,7 +216,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.social-links {
|
.social-links {
|
||||||
padding: 1rem 1rem 0.5rem;
|
padding: 0.5rem 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
@@ -219,7 +237,7 @@ social-links a:hover {
|
|||||||
.subtitle {
|
.subtitle {
|
||||||
margin-top: auto; /* Push to bottom of flex container */
|
margin-top: auto; /* Push to bottom of flex container */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0 1rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: var(--ifm-color-content-secondary);
|
color: var(--ifm-color-content-secondary);
|
||||||
border-top: 1px solid var(--ifm-border-color);
|
border-top: 1px solid var(--ifm-border-color);
|
||||||
@@ -240,7 +258,6 @@ social-links a:hover {
|
|||||||
.content {
|
.content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: var(--ifm-background-color);
|
background-color: var(--ifm-background-color);
|
||||||
padding: 2rem 3rem;
|
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
min-width: 0; /* Fix flexbox content overflow */
|
min-width: 0; /* Fix flexbox content overflow */
|
||||||
color: var(--ifm-color-content);
|
color: var(--ifm-color-content);
|
||||||
@@ -262,17 +279,23 @@ social-links a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#document-outline {
|
#document-outline {
|
||||||
padding: 0 1rem; /* Add horizontal padding */
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#document-outline a {
|
#document-outline a {
|
||||||
color: var(--ifm-color-content-secondary);
|
color: var(--ifm-color-content-secondary);
|
||||||
border-left: 2px solid transparent;
|
border-left: 2px solid transparent;
|
||||||
margin: 2px 0;
|
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 {
|
.markdown-content {
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@@ -477,3 +500,10 @@ social-links a:hover {
|
|||||||
.title-text .page-title {
|
.title-text .page-title {
|
||||||
font-size: 0.9rem;
|
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