feat: preload images
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
@source "../../**/*.templ";
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Outfit-LatinExt-Variable.woff2") format("woff2");
|
||||
unicode-range:
|
||||
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
|
||||
U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
|
||||
U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Outfit";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Outfit-Latin-Variable.woff2") format("woff2");
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
|
||||
U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
|
||||
U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@theme {
|
||||
/* Font Family Namespace */
|
||||
--font-sans: "Outfit", "outfit", sans-serif;
|
||||
|
||||
/* Text Shadow Namespace */
|
||||
/* These will automatically generate .text-shadow-sm, .text-shadow, and .text-shadow-lg */
|
||||
--text-shadow-sm: 0 1px 2px #000;
|
||||
--text-shadow: 0 2px 4px #000;
|
||||
--text-shadow-lg: 0px 0px 20px #000;
|
||||
}
|
||||
|
||||
/*
|
||||
Functional Utility for arbitrary values (e.g., text-shadow-[...])
|
||||
This replaces the 'matchUtilities' logic from your JS plugin.
|
||||
*/
|
||||
@utility text-shadow-* {
|
||||
text-shadow: --value(--text-shadow-*, [color], [*]);
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.prose img {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
|
||||
max-height: 90vh;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file preload-links.js
|
||||
* @description HTMX extension to extract <link rel="preload"> from preloaded HTML responses.
|
||||
* @generated By opencode (AI Agent)
|
||||
* @model gemini-3-flash-preview
|
||||
* @date Thu Mar 19 2026
|
||||
*/
|
||||
(function () {
|
||||
// Save the original XHR methods
|
||||
const originalOpen = XMLHttpRequest.prototype.open;
|
||||
const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
||||
const originalSend = XMLHttpRequest.prototype.send;
|
||||
|
||||
// We need to track which XHRs are preloads
|
||||
XMLHttpRequest.prototype.open = function () {
|
||||
this._isHtmxPreload = false;
|
||||
return originalOpen.apply(this, arguments);
|
||||
};
|
||||
|
||||
XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
|
||||
if (header.toLowerCase() === "hx-preloaded" && value === "true") {
|
||||
this._isHtmxPreload = true;
|
||||
}
|
||||
return originalSetRequestHeader.apply(this, arguments);
|
||||
};
|
||||
|
||||
XMLHttpRequest.prototype.send = function () {
|
||||
if (this._isHtmxPreload) {
|
||||
this.addEventListener("load", function () {
|
||||
// Parse the response text as HTML
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(this.responseText, "text/html");
|
||||
|
||||
// Find all preload links
|
||||
const links = doc.querySelectorAll('link[rel="preload"]');
|
||||
|
||||
links.forEach((link) => {
|
||||
const href = link.getAttribute("href");
|
||||
// Only inject if the current document doesn't already have it
|
||||
if (
|
||||
href &&
|
||||
!document.querySelector(`link[rel="preload"][href="${href}"]`)
|
||||
) {
|
||||
const newLink = document.createElement("link");
|
||||
newLink.rel = "preload";
|
||||
newLink.href = href;
|
||||
|
||||
// Copy relevant attributes
|
||||
["as", "type", "media", "fetchpriority", "crossorigin"].forEach(
|
||||
(attr) => {
|
||||
const val = link.getAttribute(attr);
|
||||
if (val) newLink.setAttribute(attr, val);
|
||||
},
|
||||
);
|
||||
|
||||
document.head.appendChild(newLink);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return originalSend.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user