fix: TOC scroll navigation in published articles
Browse files- Add scroll-behavior: smooth and scroll-padding-top: 80px to html
- Add click handlers on TOC links with smooth scroll and proper offset
- Guard lightbox JS against missing elements to prevent script crash
that could block TOC initialization
Made-with: Cursor
backend/src/publisher/html-renderer.ts
CHANGED
|
@@ -111,7 +111,7 @@ ${css.reset}
|
|
| 111 |
|
| 112 |
/* Published page global reset (not needed in editor where MUI handles body) */
|
| 113 |
body { font-family: var(--default-font-family); color: var(--text-color); }
|
| 114 |
-
html { font-size: 16px; line-height: 1.6; background-color: var(--page-bg); overflow-x: hidden; }
|
| 115 |
|
| 116 |
${css.editorTokens}
|
| 117 |
${css.base}
|
|
@@ -618,11 +618,14 @@ dialog.lightbox img { max-width: 95vw; max-height: 90vh; object-fit: contain; bo
|
|
| 618 |
document.querySelectorAll('.tiptap img').forEach(function(img) {
|
| 619 |
img.style.cursor = 'zoom-in';
|
| 620 |
img.addEventListener('click', function() {
|
| 621 |
-
document.getElementById('lightbox-img')
|
| 622 |
-
document.getElementById('lightbox')
|
|
|
|
|
|
|
| 623 |
});
|
| 624 |
});
|
| 625 |
-
document.getElementById('lightbox')
|
|
|
|
| 626 |
|
| 627 |
// Glossary
|
| 628 |
document.querySelectorAll('[data-type="glossary"]').forEach(function(el) { el.setAttribute('tabindex', '0'); });
|
|
@@ -678,6 +681,21 @@ dialog.lightbox img { max-width: 95vw; max-height: 90vh; object-fit: contain; bo
|
|
| 678 |
holderMobile ? Array.from(holderMobile.querySelectorAll('a')) : []
|
| 679 |
);
|
| 680 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 681 |
// ---- Auto-collapse logic ----
|
| 682 |
var isMobile = window.matchMedia('(max-width: 1100px)');
|
| 683 |
|
|
|
|
| 111 |
|
| 112 |
/* Published page global reset (not needed in editor where MUI handles body) */
|
| 113 |
body { font-family: var(--default-font-family); color: var(--text-color); }
|
| 114 |
+
html { font-size: 16px; line-height: 1.6; background-color: var(--page-bg); overflow-x: hidden; scroll-behavior: smooth; scroll-padding-top: 80px; }
|
| 115 |
|
| 116 |
${css.editorTokens}
|
| 117 |
${css.base}
|
|
|
|
| 618 |
document.querySelectorAll('.tiptap img').forEach(function(img) {
|
| 619 |
img.style.cursor = 'zoom-in';
|
| 620 |
img.addEventListener('click', function() {
|
| 621 |
+
var lbImg = document.getElementById('lightbox-img');
|
| 622 |
+
var lbDlg = document.getElementById('lightbox');
|
| 623 |
+
if (lbImg) lbImg.src = img.src;
|
| 624 |
+
if (lbDlg && lbDlg.showModal) lbDlg.showModal();
|
| 625 |
});
|
| 626 |
});
|
| 627 |
+
var lb = document.getElementById('lightbox');
|
| 628 |
+
if (lb) lb.addEventListener('click', function(e) { if (e.target === this) this.close(); });
|
| 629 |
|
| 630 |
// Glossary
|
| 631 |
document.querySelectorAll('[data-type="glossary"]').forEach(function(el) { el.setAttribute('tabindex', '0'); });
|
|
|
|
| 681 |
holderMobile ? Array.from(holderMobile.querySelectorAll('a')) : []
|
| 682 |
);
|
| 683 |
|
| 684 |
+
// Click handler for smooth scroll with offset
|
| 685 |
+
var SCROLL_OFFSET = 80;
|
| 686 |
+
allLinks.forEach(function(link) {
|
| 687 |
+
link.addEventListener('click', function(e) {
|
| 688 |
+
var href = link.getAttribute('href');
|
| 689 |
+
if (!href || href.charAt(0) !== '#') return;
|
| 690 |
+
var el = document.getElementById(href.slice(1));
|
| 691 |
+
if (!el) return;
|
| 692 |
+
e.preventDefault();
|
| 693 |
+
var top = el.getBoundingClientRect().top + window.scrollY - SCROLL_OFFSET;
|
| 694 |
+
window.scrollTo({ top: top, behavior: 'smooth' });
|
| 695 |
+
history.pushState(null, '', href);
|
| 696 |
+
});
|
| 697 |
+
});
|
| 698 |
+
|
| 699 |
// ---- Auto-collapse logic ----
|
| 700 |
var isMobile = window.matchMedia('(max-width: 1100px)');
|
| 701 |
|