Fixes to markdown extensions/styling. Sort crawlers most recent first.

This commit is contained in:
2026-08-27 01:27:49 +00:00
parent 5c2433b766
commit 3518ac9ac7
5 changed files with 57 additions and 14 deletions
+3 -3
View File
@@ -349,8 +349,8 @@ export function mainDomain(host, limit = 24) {
/**
* Group raw crawler hits by client hash and format each group as a row showing
* every internal page that crawler visited. Rows are sorted by total hits,
* most active crawler first, rather than by most recent hit.
* every internal page that crawler visited. Rows are sorted by most recent hit
* first, with total hits as a tie-breaker.
* ``clients`` maps client hashes to client records.
*/
export function formatCrawlerRows(crawlers, clients, pageTree, now = Date.now()) {
@@ -380,7 +380,7 @@ export function formatCrawlerRows(crawlers, clients, pageTree, now = Date.now())
return n
}
return [...groups.values()]
.sort((a, b) => totalHits(b) - totalHits(a) || b.lastStart - a.lastStart)
.sort((a, b) => b.lastStart - a.lastStart || totalHits(b) - totalHits(a))
.slice(0, 10)
.map((g) => {
const client = g.client || {}
+7 -7
View File
@@ -928,10 +928,10 @@ figure:has(img[width]) {
later rules win at equal specificity. The analytics dashboard uses the
same breakout directly on its container (div.wide — it is the page's
whole content, not a figure), and code blocks via a trailing {.wide}
line (fence attrs land on <code>, hence pre:has(.wide)). */
line (fence block attrs land on <pre> itself). */
figure:has(.wide),
div.wide,
pre:has(.wide) {
pre.wide {
width: 100vw;
max-width: none;
margin-inline: calc(50% - 50vw);
@@ -939,7 +939,7 @@ pre:has(.wide) {
/* Full bleed means edge to edge — no rounded corners. */
figure:has(.wide) img,
pre:has(.wide) {
pre.wide {
border-radius: 0;
}
@@ -948,7 +948,7 @@ pre:has(.wide) {
1fr + 4fr grid, i.e. 20vw — plus main's padding, and spans on to the
right viewport edge. */
body:has(.multicol) figure:has(.wide),
body:has(.multicol) pre:has(.wide) {
body:has(.multicol) pre.wide {
margin-inline: calc(-20vw - 1.25rem) 0;
}
@@ -956,7 +956,7 @@ body:has(.multicol) pre:has(.wide) {
window keeps its overlay scrollbars while editing, so — unlike a classic
scrollbar — they take no layout space and the vw math stays exact. */
body.editing figure:has(.wide),
body.editing pre:has(.wide) {
body.editing pre.wide {
width: calc(100vw - var(--editor-w));
margin-inline: calc(50% - (100vw - var(--editor-w)) / 2);
}
@@ -964,7 +964,7 @@ body.editing pre:has(.wide) {
/* Editing + multicol: the left gutter is 1/5 of the space right of the
editor, and the bleed also crosses main's 1.25rem left padding. */
body.editing:has(.multicol) figure:has(.wide),
body.editing:has(.multicol) pre:has(.wide) {
body.editing:has(.multicol) pre.wide {
margin-inline: calc((100vw - var(--editor-w)) / -5 - 1.25rem) 0;
}
@@ -977,7 +977,7 @@ body.editing:has(.multicol) pre:has(.wide) {
where the editing rules above apply instead. */
@media (max-width: 102rem) {
body:has(#sidebar):not(.editing) figure:has(.wide),
body:has(#sidebar):not(.editing) pre:has(.wide) {
body:has(#sidebar):not(.editing) pre.wide {
margin-inline: -13.25rem 0;
}
}
+20 -3
View File
@@ -235,9 +235,26 @@ import "overlayscrollbars/overlayscrollbars.css";
btn.textContent = "copy";
btn.addEventListener("click", async () => {
const code = pre.querySelector("code");
await navigator.clipboard.writeText(
(code || pre).textContent.replace(/\n$/, ""),
);
const text = (code || pre).textContent.replace(/\n$/, "");
// navigator.clipboard exists only in secure contexts (https or
// localhost); viewing over plain http needs the textarea fallback.
try {
if (navigator.clipboard) {
await navigator.clipboard.writeText(text);
} else {
const ta = document.createElement("textarea");
ta.value = text;
ta.style.cssText = "position:fixed;opacity:0";
document.body.append(ta);
ta.select();
document.execCommand("copy");
ta.remove();
}
} catch {
btn.textContent = "failed";
setTimeout(() => (btn.textContent = "copy"), 1500);
return;
}
btn.textContent = "copied";
btn.classList.add("copied");
setTimeout(() => {