@@ -1048,24 +1048,71 @@ def render_message(log_type, message_json, timestamp):
10481048"""
10491049
10501050# JavaScript to fix relative URLs when served via gistpreview.github.io
1051+ # Fixes issue #26: Pagination links broken on gistpreview.github.io
10511052GIST_PREVIEW_JS = r"""
10521053(function() {
10531054 if (window.location.hostname !== 'gistpreview.github.io') return;
10541055 // URL format: https://gistpreview.github.io/?GIST_ID/filename.html
10551056 var match = window.location.search.match(/^\?([^/]+)/);
10561057 if (!match) return;
10571058 var gistId = match[1];
1058- document.querySelectorAll('a[href]').forEach(function(link) {
1059- var href = link.getAttribute('href');
1060- // Skip external links and anchors
1061- if (href.startsWith('http') || href.startsWith('#') || href.startsWith('//')) return;
1062- // Handle anchor in relative URL (e.g., page-001.html#msg-123)
1063- var parts = href.split('#');
1064- var filename = parts[0];
1065- var anchor = parts.length > 1 ? '#' + parts[1] : '';
1066- link.setAttribute('href', '?' + gistId + '/' + filename + anchor);
1059+
1060+ function rewriteLinks(root) {
1061+ (root || document).querySelectorAll('a[href]').forEach(function(link) {
1062+ var href = link.getAttribute('href');
1063+ // Skip already-rewritten links (issue #26 fix)
1064+ if (href.startsWith('?')) return;
1065+ // Skip external links and anchors
1066+ if (href.startsWith('http') || href.startsWith('#') || href.startsWith('//')) return;
1067+ // Handle anchor in relative URL (e.g., page-001.html#msg-123)
1068+ var parts = href.split('#');
1069+ var filename = parts[0];
1070+ var anchor = parts.length > 1 ? '#' + parts[1] : '';
1071+ link.setAttribute('href', '?' + gistId + '/' + filename + anchor);
1072+ });
1073+ }
1074+
1075+ // Run immediately
1076+ rewriteLinks();
1077+
1078+ // Also run on DOMContentLoaded in case DOM isn't ready yet
1079+ if (document.readyState === 'loading') {
1080+ document.addEventListener('DOMContentLoaded', function() { rewriteLinks(); });
1081+ }
1082+
1083+ // Use MutationObserver to catch dynamically added content
1084+ // gistpreview.github.io may add content after initial load
1085+ var observer = new MutationObserver(function(mutations) {
1086+ mutations.forEach(function(mutation) {
1087+ mutation.addedNodes.forEach(function(node) {
1088+ if (node.nodeType === 1) { // Element node
1089+ rewriteLinks(node);
1090+ // Also check if the node itself is a link
1091+ if (node.tagName === 'A' && node.getAttribute('href')) {
1092+ var href = node.getAttribute('href');
1093+ if (!href.startsWith('?') && !href.startsWith('http') &&
1094+ !href.startsWith('#') && !href.startsWith('//')) {
1095+ var parts = href.split('#');
1096+ var filename = parts[0];
1097+ var anchor = parts.length > 1 ? '#' + parts[1] : '';
1098+ node.setAttribute('href', '?' + gistId + '/' + filename + anchor);
1099+ }
1100+ }
1101+ }
1102+ });
1103+ });
10671104 });
10681105
1106+ // Start observing once body exists
1107+ function startObserving() {
1108+ if (document.body) {
1109+ observer.observe(document.body, { childList: true, subtree: true });
1110+ } else {
1111+ setTimeout(startObserving, 10);
1112+ }
1113+ }
1114+ startObserving();
1115+
10691116 // Handle fragment navigation after dynamic content loads
10701117 // gistpreview.github.io loads content dynamically, so the browser's
10711118 // native fragment navigation fails because the element doesn't exist yet
@@ -1084,7 +1131,7 @@ def render_message(log_type, message_json, timestamp):
10841131 // Try immediately in case content is already loaded
10851132 if (!scrollToFragment()) {
10861133 // Retry with increasing delays to handle dynamic content loading
1087- var delays = [100, 300, 500, 1000];
1134+ var delays = [100, 300, 500, 1000, 2000 ];
10881135 delays.forEach(function(delay) {
10891136 setTimeout(scrollToFragment, delay);
10901137 });
0 commit comments