From 9c8f7fd7ee5c1eaabdb576a6b152dec83ad57729 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Tue, 14 Jul 2026 11:00:16 +0200 Subject: [PATCH 1/2] logview: add anchors for each line So we can easily point to a part of it. When the user clicks on the page, the anchor is added in the URL, which can be easily copied. Signed-off-by: Matthieu Baerts --- ui/logview.html | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ui/logview.html b/ui/logview.html index e5dc7a4..30db056 100644 --- a/ui/logview.html +++ b/ui/logview.html @@ -158,32 +158,35 @@ const lines = text.split("\n"); let pass = 0, fail = 0, skip = 0; - function renderLine(line) { + function renderLine(line, i) { + i += this.add; const cls = classify(line); if (cls === "ln-pass") pass++; else if (cls === "ln-fail") fail++; else if (cls === "ln-skip") skip++; const e = esc(line); - return cls ? `${e}` : e; + const c = cls ? `class=${cls}` : ``; + return `${e}`; } // Group runs of deeply-nested "# #" diagnostic lines into a foldable // block (rendered expanded; collapse via the marker or "fold all"). // Totals lines are kept out so the summary stays visible. const foldable = l => l.startsWith("# #") && !/Totals: pass/.test(l); + this.add = 0; const pieces = []; let i = 0; while (i < lines.length) { if (foldable(lines[i])) { let j = i; while (j < lines.length && foldable(lines[j])) j++; - const body = lines.slice(i, j).map(renderLine).join("\n"); + const body = lines.slice(i, j).map(renderLine, {add: i}).join("\n"); pieces.push( `${j - i} lines` + `\n${body}`); i = j; } else { - pieces.push(renderLine(lines[i])); + pieces.push(renderLine(lines[i], i)); i++; } } @@ -199,6 +202,11 @@ out.addEventListener("click", e => { const t = e.target.closest(".fold-toggle"); if (t) t.parentElement.classList.toggle("open"); + + // Set #Line in url + var id = e.target.id; + if (id && id.startsWith("L")) + history.pushState(null, null, "#" + id); }); // Fold/unfold all button. From 69187a03ad73efa9ce3d7fcf7786497e7b102d90 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Wed, 22 Jul 2026 20:25:13 +0200 Subject: [PATCH 2/2] logview: highlight the selected line Add a background colour to help seeing which one needs to be looked at. Signed-off-by: Matthieu Baerts --- ui/logview.html | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ui/logview.html b/ui/logview.html index 30db056..3e4c0d9 100644 --- a/ui/logview.html +++ b/ui/logview.html @@ -16,6 +16,7 @@ --plan: #0550ae; --bar-bg: #f2f2f2; --hl: #fff8c5; + --bg-line: #f2dd2650; } @media (prefers-color-scheme: dark) { :root { @@ -28,6 +29,7 @@ --plan: #809fff; --bar-bg: #282828; --hl: #4a3f1a; + --bg-line: #f2dd2650; } } html, body { @@ -76,6 +78,7 @@ .ln-diag { color: var(--dim); } .ln-totals { color: var(--plan); } .ln-err { color: var(--fail); } + .ln-bg { background-color: var(--bg-line); } .fold-toggle { cursor: pointer; color: var(--plan); @@ -160,12 +163,15 @@ function renderLine(line, i) { i += this.add; + var classes = [] const cls = classify(line); if (cls === "ln-pass") pass++; else if (cls === "ln-fail") fail++; else if (cls === "ln-skip") skip++; + if (cls) classes.push(cls); + if (this.bg == i) classes.push("ln-bg") const e = esc(line); - const c = cls ? `class=${cls}` : ``; + const c = classes.length > 0 ? `class="${classes.join(" ")}"` : ``; return `${e}`; } @@ -173,6 +179,8 @@ // block (rendered expanded; collapse via the marker or "fold all"). // Totals lines are kept out so the summary stays visible. const foldable = l => l.startsWith("# #") && !/Totals: pass/.test(l); + const anchor = window.location.hash.match(/^#L(\d+)/); + this.bg = anchor && anchor.length > 1 ? anchor[1] : -1; this.add = 0; const pieces = []; let i = 0; @@ -180,7 +188,8 @@ if (foldable(lines[i])) { let j = i; while (j < lines.length && foldable(lines[j])) j++; - const body = lines.slice(i, j).map(renderLine, {add: i}).join("\n"); + const body = lines.slice(i, j).map(renderLine, + {add: i, bg: bg}).join("\n"); pieces.push( `${j - i} lines` + `\n${body}`);