diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/footnotes.js | 2 | ||||
| -rw-r--r-- | public/my_uptime.js | 2 | ||||
| -rw-r--r-- | public/scrollbar.js | 21 | ||||
| -rw-r--r-- | public/shell.js | 128 | ||||
| -rw-r--r-- | public/styles/style.css | 105 |
5 files changed, 88 insertions, 170 deletions
diff --git a/public/footnotes.js b/public/footnotes.js index 57ded98..96a9400 100644 --- a/public/footnotes.js +++ b/public/footnotes.js @@ -8,7 +8,7 @@ const SIDENOTES = { readingWidth: null, // max width of the post text, null = no cap }; -document.addEventListener("DOMContentLoaded", () => { +document.addEventListener("htmx:load", () => { const area = document.querySelector("[data-scroll-area]"); const article = area?.querySelector("article"); if (!area || !article) return; diff --git a/public/my_uptime.js b/public/my_uptime.js index 1fdb457..b5f3ca2 100644 --- a/public/my_uptime.js +++ b/public/my_uptime.js @@ -13,7 +13,7 @@ async function updateUptime() { } // Run on page load after all DOM elements loaded -document.addEventListener("DOMContentLoaded", () => { +document.addEventListener("htmx:load", () => { updateUptime(); setInterval(updateUptime, 5 * 1000); // in ms }); diff --git a/public/scrollbar.js b/public/scrollbar.js index 2218b55..b297d76 100644 --- a/public/scrollbar.js +++ b/public/scrollbar.js @@ -1,4 +1,8 @@ function initScrollbox(box) { + // Guard against double-initialization + if (box.dataset.initialized) return; + box.dataset.initialized = "true"; + const area = box.querySelector("[data-scroll-area]"); const track = box.querySelector("[data-scroll-track]"); const thumb = box.querySelector("[data-scroll-thumb]"); @@ -51,23 +55,26 @@ function initScrollbox(box) { document.querySelectorAll("[data-scrollbox]").forEach(initScrollbox); -// Vim style j/k scrolling +document.addEventListener("htmx:afterSettle", () => { + document.querySelectorAll("[data-scrollbox]").forEach(initScrollbox); +}); + document.addEventListener("keydown", (e) => { - // Don't scroll in input elements - const tag = document.activeElement.tagName; + const tag = document.activeElement?.tagName; if ( ["INPUT", "TEXTAREA", "SELECT"].includes(tag) || - document.activeElement.isContentEditable + document.activeElement?.isContentEditable ) { return; } - // Only work for "j" and "k", no ctrl/alt/shift if (e.ctrlKey || e.altKey || e.metaKey) return; + if (e.key !== "j" && e.key !== "k") return; - const dir = key === "j" ? step : -step; - const scrollTarget = document.scrollingElement || document.documentElement; const scrollAmount = 100; // in pixels + const dir = e.key === "j" ? scrollAmount : -scrollAmount; + const scrollTarget = document.scrollingElement || document.documentElement; + if (scrollTarget && scrollTarget.scrollHeight > scrollTarget.clientHeight) { scrollTarget.scrollBy({ top: dir, behavior: "auto" }); } else { diff --git a/public/shell.js b/public/shell.js index 9a70846..3f3aef8 100644 --- a/public/shell.js +++ b/public/shell.js @@ -1,73 +1,75 @@ -const shell = document.querySelector("[data-shell]"); +document.addEventListener("htmx:load", () => { + const shell = document.querySelector("[data-shell]"); -if (shell) { - const area = shell.closest("[data-scroll-area]"); - const history = shell.querySelector("#shell-history"); - const input = shell.querySelector("[data-shell-input]"); - const caret = shell.querySelector("[data-shell-caret]"); - let busy = false; + if (shell) { + const area = shell.closest("[data-scroll-area]"); + const history = shell.querySelector("#shell-history"); + const input = shell.querySelector("[data-shell-input]"); + const caret = shell.querySelector("[data-shell-caret]"); + let busy = false; - const updateCaret = () => { - const pos = input.selectionStart ?? input.value.length; - caret.style.left = `calc(${pos}ch - ${input.scrollLeft}px)`; - caret.textContent = input.value[pos] ?? "\u00a0"; - caret.style.animation = "none"; // restart the blink so the caret is solid while typing - void caret.offsetWidth; - caret.style.animation = ""; - }; + const updateCaret = () => { + const pos = input.selectionStart ?? input.value.length; + caret.style.left = `calc(${pos}ch - ${input.scrollLeft}px)`; + caret.textContent = input.value[pos] ?? "\u00a0"; + caret.style.animation = "none"; // restart the blink so the caret is solid while typing + void caret.offsetWidth; + caret.style.animation = ""; + }; - const snapToBottom = () => { - area.scrollTop = area.scrollHeight; - }; + const snapToBottom = () => { + area.scrollTop = area.scrollHeight; + }; - const run = async (cmd) => { - busy = true; - try { - const res = await fetch("/shell/run", { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams({ cmd }), - }); - const data = await res.json(); - if (data.clear) history.replaceChildren(); - if (data.html) history.insertAdjacentHTML("beforeend", data.html); - if (data.vars) { - for (const [key, value] of Object.entries(data.vars)) { - document.documentElement.style.setProperty(`--${key}`, value); + const run = async (cmd) => { + busy = true; + try { + const res = await fetch("/shell/run", { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: new URLSearchParams({ cmd }), + }); + const data = await res.json(); + if (data.clear) history.replaceChildren(); + if (data.html) history.insertAdjacentHTML("beforeend", data.html); + if (data.vars) { + for (const [key, value] of Object.entries(data.vars)) { + document.documentElement.style.setProperty(`--${key}`, value); + } } + } catch { + const el = document.createElement("p"); + el.textContent = "request failed"; + history.append(el); + } finally { + busy = false; + snapToBottom(); } - } catch { - const el = document.createElement("p"); - el.textContent = "request failed"; - history.append(el); - } finally { - busy = false; - snapToBottom(); - } - }; + }; - input.addEventListener("keydown", (e) => { - if (e.key !== "Enter") return; - e.preventDefault(); - const cmd = input.value.trim(); - if (!cmd || busy) return; - input.value = ""; - updateCaret(); - run(cmd); - }); + input.addEventListener("keydown", (e) => { + if (e.key !== "Enter") return; + e.preventDefault(); + const cmd = input.value.trim(); + if (!cmd || busy) return; + input.value = ""; + updateCaret(); + run(cmd); + }); - for (const event of ["input", "keyup", "click", "focus"]) { - input.addEventListener(event, updateCaret); - } - document.addEventListener("selectionchange", () => { - if (document.activeElement === input) updateCaret(); - }); + for (const event of ["input", "keyup", "click", "focus"]) { + input.addEventListener(event, updateCaret); + } + document.addEventListener("selectionchange", () => { + if (document.activeElement === input) updateCaret(); + }); - area.addEventListener("click", () => { - if (!getSelection().toString()) input.focus({ preventScroll: true }); - }); + area.addEventListener("click", () => { + if (!getSelection().toString()) input.focus({ preventScroll: true }); + }); - input.focus({ preventScroll: true }); - updateCaret(); - snapToBottom(); -} + input.focus({ preventScroll: true }); + updateCaret(); + snapToBottom(); + } +}); diff --git a/public/styles/style.css b/public/styles/style.css index 3610b64..76bf2a1 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -823,26 +823,12 @@ .pointer-events-none { pointer-events: none; } - .collapse { - visibility: collapse; - } .invisible { visibility: hidden; } .visible { visibility: visible; } - .sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; - border-width: 0; - } .absolute { position: absolute; } @@ -861,9 +847,6 @@ .inset-y-0 { inset-block: 0px; } - .top-1 { - top: var(--spacing); - } .top-1\/2 { top: calc(1 / 2 * 100%); } @@ -903,24 +886,6 @@ .col-span-2 { grid-column: span 2 / span 2; } - .container { - width: 100%; - @media (width >= 40rem) { - max-width: 40rem; - } - @media (width >= 48rem) { - max-width: 48rem; - } - @media (width >= 64rem) { - max-width: 64rem; - } - @media (width >= 80rem) { - max-width: 80rem; - } - @media (width >= 96rem) { - max-width: 96rem; - } - } .-m-\[0\.4rem\] { margin: calc(0.4rem * -1); } @@ -1441,9 +1406,6 @@ .hidden { display: none; } - .inline { - display: inline; - } .inline-block { display: inline-block; } @@ -1531,33 +1493,17 @@ .flex-1 { flex: 1; } - .flex-shrink { - flex-shrink: 1; - } .shrink-0 { flex-shrink: 0; } - .flex-grow { - flex-grow: 1; - } - .grow { - flex-grow: 1; - } - .border-collapse { - border-collapse: collapse; - } - .-translate-y-1 { - --tw-translate-y: calc(var(--spacing) * -1); - translate: var(--tw-translate-x) var(--tw-translate-y); - } .-translate-y-1\/2 { --tw-translate-y: calc(calc(1 / 2 * 100%) * -1); translate: var(--tw-translate-x) var(--tw-translate-y); } - .scale-150 { - --tw-scale-x: 150%; - --tw-scale-y: 150%; - --tw-scale-z: 150%; + .scale-135 { + --tw-scale-x: 135%; + --tw-scale-y: 135%; + --tw-scale-z: 135%; scale: var(--tw-scale-x) var(--tw-scale-y); } .transform { @@ -1783,9 +1729,6 @@ .bg-\[var\(--text\)\] { background-color: var(--text); } - .bg-black { - background-color: var(--color-black); - } .bg-black\/20 { background-color: color-mix(in srgb, #000 20%, transparent); @supports (color: color-mix(in lab, red, red)) { @@ -1801,9 +1744,6 @@ .bg-transparent { background-color: transparent; } - .bg-white { - background-color: var(--color-white); - } .bg-white\/2 { background-color: color-mix(in srgb, #fff 2%, transparent); @supports (color: color-mix(in lab, red, red)) { @@ -1822,9 +1762,6 @@ .bg-\[linear-gradient\(to_bottom\,var\(--background\)\,var\(--cmp-bg\,transparent\)\)\] { background-image: linear-gradient(to bottom,var(--background),var(--cmp-bg,transparent)); } - .mask-repeat { - mask-repeat: repeat; - } .fill-\[\#7ed4fb\]\/50 { fill: color-mix(in oklab, #7ed4fb 50%, transparent); } @@ -1864,9 +1801,6 @@ .p-\[3vw\] { padding: 3vw; } - .px-3 { - padding-inline: calc(var(--spacing) * 3); - } .px-3\.5 { padding-inline: calc(var(--spacing) * 3.5); } @@ -1981,15 +1915,15 @@ .text-\[85\%\] { font-size: 85%; } - .text-\[90\%\] { - font-size: 90%; - } .text-\[95\%\] { font-size: 95%; } .text-\[110\%\] { font-size: 110%; } + .text-\[120\%\] { + font-size: 120%; + } .text-\[130\%\] { font-size: 130%; } @@ -2122,15 +2056,9 @@ .text-\[var\(--secondary\)\] { color: var(--secondary); } - .italic { - font-style: italic; - } .no-underline { text-decoration-line: none; } - .underline { - text-decoration-line: underline; - } .caret-transparent { caret-color: transparent; } @@ -2144,19 +2072,6 @@ } box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } - .ring { - --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - } - .outline { - outline-style: var(--tw-outline-style); - outline-width: 1px; - } - .transition { - transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } .transition-colors { transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); @@ -2781,11 +2696,6 @@ body { inherits: false; initial-value: 0 0 #0000; } -@property --tw-outline-style { - syntax: "*"; - inherits: false; - initial-value: solid; -} @property --tw-duration { syntax: "*"; inherits: false; @@ -2827,7 +2737,6 @@ body { --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; - --tw-outline-style: solid; --tw-duration: initial; --tw-content: ""; } |
