Skip to content

Commit 4a432be

Browse files
committed
fix: ux
1 parent e6427af commit 4a432be

File tree

3 files changed

+161
-13
lines changed

3 files changed

+161
-13
lines changed

site/scripts/process-agda-html.js

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ if (searchInput && searchResults) {
9595
// Ensure the path is properly encoded
9696
const encodedPath = encodeURIComponent(result.path);
9797
98-
return '<a href="/agda_html/' + encodedPath + '#L' + result.lineNumber + '" class="search-result" data-line="' + result.lineNumber + '">' +
98+
return '<a href="/agda_html/' + encodedPath + '#L' + result.lineNumber + '" class="search-result" data-line="' + result.lineNumber + '" data-term="' + result.term + '">' +
9999
'<span class="result-match">' + highlightedContent + '</span>' +
100100
'<span class="result-file">' + result.moduleName + '</span>' +
101101
'</a>';
@@ -127,19 +127,91 @@ if (searchInput && searchResults) {
127127
document.addEventListener('click', (e) => {
128128
const result = e.target.closest('.search-result');
129129
if (result) {
130+
e.preventDefault(); // Prevent default link behavior
130131
const lineNumber = result.dataset.line;
131-
const targetElement = document.querySelector('#L' + lineNumber);
132-
if (targetElement) {
133-
targetElement.scrollIntoView({ behavior: 'smooth' });
134-
targetElement.classList.add('highlight-line');
135-
setTimeout(() => targetElement.classList.remove('highlight-line'), 2000);
132+
const searchTerm = result.dataset.term;
133+
const href = result.getAttribute('href');
134+
135+
// If we're already on the target page
136+
if (window.location.pathname.endsWith(href.split('#')[0])) {
137+
scrollToLine(lineNumber, searchTerm);
138+
} else {
139+
// If we're not on the target page, navigate to it
140+
// Store the line number and search term in sessionStorage
141+
sessionStorage.setItem('scrollToLine', lineNumber);
142+
sessionStorage.setItem('searchTerm', searchTerm);
143+
window.location.href = href;
136144
}
145+
137146
searchOverlay.classList.remove('active');
138147
searchInput.value = ''; // Clear the search input
139148
searchResults.innerHTML = ''; // Clear the results
140149
}
141150
});
142151
152+
// Function to scroll to a specific line and highlight terms
153+
function scrollToLine(lineNumber, searchTerm) {
154+
// Wait for the next frame to ensure content is rendered
155+
requestAnimationFrame(() => {
156+
const targetElement = document.querySelector('#L' + lineNumber);
157+
if (targetElement) {
158+
// Add a small delay to ensure content is fully rendered
159+
setTimeout(() => {
160+
targetElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
161+
targetElement.classList.add('highlight-line');
162+
setTimeout(() => targetElement.classList.remove('highlight-line'), 2000);
163+
164+
// Highlight all matching terms on the page
165+
const content = document.querySelector('.agda-content');
166+
if (content && searchTerm) {
167+
const regex = new RegExp(searchTerm, 'gi');
168+
const walker = document.createTreeWalker(content, NodeFilter.SHOW_TEXT, null, false);
169+
const nodesToHighlight = [];
170+
171+
while (walker.nextNode()) {
172+
const node = walker.currentNode;
173+
if (node.textContent.match(regex)) {
174+
nodesToHighlight.push(node);
175+
}
176+
}
177+
178+
nodesToHighlight.forEach(node => {
179+
const span = document.createElement('span');
180+
span.className = 'search-term-highlight';
181+
span.innerHTML = node.textContent.replace(regex, match => '<mark>' + match + '</mark>');
182+
node.parentNode.replaceChild(span, node);
183+
});
184+
185+
// Remove highlights after 5 seconds
186+
setTimeout(() => {
187+
const highlights = document.querySelectorAll('.search-term-highlight');
188+
highlights.forEach(highlight => {
189+
const text = highlight.textContent;
190+
const textNode = document.createTextNode(text);
191+
highlight.parentNode.replaceChild(textNode, highlight);
192+
});
193+
}, 5000);
194+
}
195+
}, 100); // Small delay to ensure content is rendered
196+
}
197+
});
198+
}
199+
200+
// Check for stored line number and search term on page load
201+
window.addEventListener('load', () => {
202+
// Wait for a short time to ensure all content is loaded and rendered
203+
setTimeout(() => {
204+
const storedLine = sessionStorage.getItem('scrollToLine');
205+
const storedTerm = sessionStorage.getItem('searchTerm');
206+
if (storedLine) {
207+
scrollToLine(storedLine, storedTerm);
208+
// Clear the stored values
209+
sessionStorage.removeItem('scrollToLine');
210+
sessionStorage.removeItem('searchTerm');
211+
}
212+
}, 100);
213+
});
214+
143215
// Close search when clicking outside or pressing Escape
144216
document.addEventListener('click', (e) => {
145217
if (e.target === searchOverlay) {

site/static/agda_html/Agda.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ body {
134134
width: var(--content-width);
135135
min-width: 0;
136136
overflow-y: auto;
137-
overflow-x: hidden;
137+
overflow-x: auto;
138138
position: relative;
139139
box-sizing: border-box;
140140
}
@@ -146,6 +146,7 @@ body {
146146
overflow-x: visible;
147147
max-width: none;
148148
padding-bottom: 4rem; /* Add some padding at the bottom */
149+
white-space: pre; /* Preserve whitespace and line breaks */
149150
}
150151

151152
/* Add styles for highlighted line */
@@ -174,6 +175,9 @@ body {
174175
background-color: var(--code-bg);
175176
padding: 0.2em 0.4em;
176177
border-radius: 3px;
178+
white-space: pre; /* Preserve whitespace and line breaks */
179+
overflow-x: auto; /* Allow horizontal scrolling */
180+
display: inline-block; /* Ensure proper overflow behavior */
177181
}
178182

179183
.Agda a {

site/static/agda_html/agda.js

Lines changed: 78 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)