Use htmx.js instead of htmx.min.js

This wastes 30 kB gzipped, which I think is acceptable in exchange for
having method names in the debugger.
This commit is contained in:
Cadence Ember
2025-01-31 16:42:15 +13:00
parent b1b9124052
commit a459ee1d1c
4 changed files with 5352 additions and 92 deletions

View File

@@ -1,89 +1,89 @@
mixin guild(guild) mixin guild(guild)
span.s-avatar.s-avatar__32.s-user-card--avatar span.s-avatar.s-avatar__32.s-user-card--avatar
if guild.icon if guild.icon
img.s-avatar--image(src=`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=32`) img.s-avatar--image(src=`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=32`)
else else
.s-avatar--letter.bg-silver-400.bar-md(aria-hidden="true")= guild.name[0] .s-avatar--letter.bg-silver-400.bar-md(aria-hidden="true")= guild.name[0]
.s-user-card--info.ai-start .s-user-card--info.ai-start
strong= guild.name strong= guild.name
ul.s-user-card--awards ul.s-user-card--awards
li #{discord.guildChannelMap.get(guild.id).filter(c => [0, 5, 15, 16].includes(discord.channels.get(c).type)).length} channels li #{discord.guildChannelMap.get(guild.id).filter(c => [0, 5, 15, 16].includes(discord.channels.get(c).type)).length} channels
doctype html doctype html
html(lang="en") html(lang="en")
head head
title Out Of Your Element title Out Of Your Element
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
link(rel="stylesheet" type="text/css" href=rel("/static/stacks.min.css")) link(rel="stylesheet" type="text/css" href=rel("/static/stacks.min.css"))
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 80%22><text y=%22.83em%22 font-size=%2283%22>💬</text></svg>"> <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 80%22><text y=%22.83em%22 font-size=%2283%22>💬</text></svg>">
meta(name="htmx-config" content='{"indicatorClass":"is-loading"}') meta(name="htmx-config" content='{"indicatorClass":"is-loading"}')
style. style.
.themed { .themed {
--theme-base-primary-color-h: 266; --theme-base-primary-color-h: 266;
--theme-base-primary-color-s: 53%; --theme-base-primary-color-s: 53%;
--theme-base-primary-color-l: 63%; --theme-base-primary-color-l: 63%;
--theme-dark-primary-color-h: 266; --theme-dark-primary-color-h: 266;
--theme-dark-primary-color-s: 53%; --theme-dark-primary-color-s: 53%;
--theme-dark-primary-color-l: 63%; --theme-dark-primary-color-l: 63%;
} }
.s-toggle-switch.s-toggle-switch__multiple.s-toggle-switch__incremental input[type="radio"]:checked ~ label:not(.s-toggle-switch--label-off) { .s-toggle-switch.s-toggle-switch__multiple.s-toggle-switch__incremental input[type="radio"]:checked ~ label:not(.s-toggle-switch--label-off) {
--_ts-multiple-bg: var(--green-400); --_ts-multiple-bg: var(--green-400);
--_ts-multiple-fc: var(--white); --_ts-multiple-fc: var(--white);
} }
body.themed.theme-system body.themed.theme-system
header.s-topbar header.s-topbar
.s-topbar--skip-link(href="#content") Skip to main content .s-topbar--skip-link(href="#content") Skip to main content
.s-topbar--container.wmx9 .s-topbar--container.wmx9
a.s-topbar--logo(href=rel("/")) a.s-topbar--logo(href=rel("/"))
img.s-avatar.s-avatar__32(src=rel("/icon.png")) img.s-avatar.s-avatar__32(src=rel("/icon.png"))
nav.s-topbar--navigation nav.s-topbar--navigation
ul.s-topbar--content ul.s-topbar--content
li.ps-relative li.ps-relative
if !session.data.managedGuilds || session.data.managedGuilds.length === 0 if !session.data.managedGuilds || session.data.managedGuilds.length === 0
a.s-btn.s-btn__icon.as-center(href=rel("/oauth")) a.s-btn.s-btn__icon.as-center(href=rel("/oauth"))
!= icons.Icons.IconDiscord != icons.Icons.IconDiscord
= ` Log in` = ` Log in`
else if guild_id && session.data.managedGuilds.includes(guild_id) && discord.guilds.has(guild_id) else if guild_id && session.data.managedGuilds.includes(guild_id) && discord.guilds.has(guild_id)
button.s-topbar--item.s-btn.s-btn__muted.s-user-card(popovertarget="guilds") button.s-topbar--item.s-btn.s-btn__muted.s-user-card(popovertarget="guilds")
+guild(discord.guilds.get(guild_id)) +guild(discord.guilds.get(guild_id))
else if session.data.managedGuilds else if session.data.managedGuilds
button.s-topbar--item.s-btn.s-btn__muted.s-btn__dropdown.pr24.s-user-card.s-label(popovertarget="guilds") button.s-topbar--item.s-btn.s-btn__muted.s-btn__dropdown.pr24.s-user-card.s-label(popovertarget="guilds")
| Your servers | Your servers
#guilds(popover data-popper-placement="bottom" style="display: revert; width: revert;").s-popover.overflow-visible #guilds(popover data-popper-placement="bottom" style="display: revert; width: revert;").s-popover.overflow-visible
.s-popover--arrow.s-popover--arrow__tc .s-popover--arrow.s-popover--arrow__tc
.s-popover--content.overflow-y-auto.overflow-x-hidden .s-popover--content.overflow-y-auto.overflow-x-hidden
ul.s-menu(role="menu") ul.s-menu(role="menu")
each guild in (session.data.managedGuilds || []).map(id => discord.guilds.get(id)).filter(g => g) each guild in (session.data.managedGuilds || []).map(id => discord.guilds.get(id)).filter(g => g)
li(role="menuitem") li(role="menuitem")
a.s-topbar--item.s-user-card.d-flex.p4(href=rel(`/guild?guild_id=${guild.id}`)) a.s-topbar--item.s-user-card.d-flex.p4(href=rel(`/guild?guild_id=${guild.id}`))
+guild(guild) +guild(guild)
//- Body //- Body
.mx-auto.w100.wmx9.py24.px8.fs-body1#content .mx-auto.w100.wmx9.py24.px8.fs-body1#content
block body block body
//- Guild list popover //- Guild list popover
script. script.
document.querySelectorAll("[popovertarget]").forEach(e => { document.querySelectorAll("[popovertarget]").forEach(e => {
e.addEventListener("click", () => { e.addEventListener("click", () => {
const rect = e.getBoundingClientRect() const rect = e.getBoundingClientRect()
const t = `:popover-open { position: absolute; top: ${Math.floor(rect.bottom)}px; left: ${Math.floor(rect.left + rect.width / 2)}px; width: ${Math.floor(rect.width)}px; transform: translateX(-50%); box-sizing: content-box; margin: 0 }` const t = `:popover-open { position: absolute; top: ${Math.floor(rect.bottom)}px; left: ${Math.floor(rect.left + rect.width / 2)}px; width: ${Math.floor(rect.width)}px; transform: translateX(-50%); box-sizing: content-box; margin: 0 }`
// console.log(t) // console.log(t)
document.styleSheets[0].insertRule(t) document.styleSheets[0].insertRule(t)
}) })
}) })
script(src=rel("/static/htmx.min.js")) script(src=rel("/static/htmx.js"))
//- Error dialog //- Error dialog
aside.s-modal#server-error(aria-hidden="true") aside.s-modal#server-error(aria-hidden="true")
.s-modal--dialog .s-modal--dialog
h1.s-modal--header Server error h1.s-modal--header Server error
pre.overflow-auto#server-error-content pre.overflow-auto#server-error-content
button.s-modal--close.s-btn.s-btn__muted(aria-label="Close" type="button" onclick="hideError()")!= icons.Icons.IconClearSm button.s-modal--close.s-btn.s-btn__muted(aria-label="Close" type="button" onclick="hideError()")!= icons.Icons.IconClearSm
.s-modal--footer .s-modal--footer
button.s-btn.s-btn__outlined.s-btn__muted(type="button" onclick="hideError()") OK button.s-btn.s-btn__outlined.s-btn__muted(type="button" onclick="hideError()") OK
script. script.
function hideError() { function hideError() {
document.getElementById("server-error").setAttribute("aria-hidden", "true") document.getElementById("server-error").setAttribute("aria-hidden", "true")
} }
document.body.addEventListener("htmx:responseError", event => { document.body.addEventListener("htmx:responseError", event => {
document.getElementById("server-error").setAttribute("aria-hidden", "false") document.getElementById("server-error").setAttribute("aria-hidden", "false")
document.getElementById("server-error-content").textContent = event.detail.xhr.responseText document.getElementById("server-error-content").textContent = event.detail.xhr.responseText
}) })

View File

@@ -49,12 +49,12 @@ as.router.get("/static/stacks.min.css", defineEventHandler({
} }
})) }))
as.router.get("/static/htmx.min.js", defineEventHandler({ as.router.get("/static/htmx.js", defineEventHandler({
onBeforeResponse: compressResponse, onBeforeResponse: compressResponse,
handler: async event => { handler: async event => {
handleCacheHeaders(event, {maxAge: 86400}) handleCacheHeaders(event, {maxAge: 86400})
defaultContentType(event, "text/javascript") defaultContentType(event, "text/javascript")
return fs.promises.readFile(join(__dirname, "static", "htmx.min.js"), "utf-8") return fs.promises.readFile(join(__dirname, "static", "htmx.js"), "utf-8")
} }
})) }))

5261
src/web/static/htmx.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long