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