chore(htmx): upgrade htmx to v4
release.yaml / publish (push) Successful in 3m48s

This commit was merged in pull request #3.
This commit is contained in:
schreifuchs committed 2026-09-29 11:03:38 +02:00
1 parent 812891a205
commit 2a96034fca
17 files changed
+94 -95

No files matched your search

+61 -48
View File
@@ -1,63 +1,76 @@
/**
* @file preload-links.js
* @description HTMX extension to extract <link rel="preload"> from preloaded HTML responses.
* @description HTMX helper to extract <link rel=preload> and image hints from fetched HTML responses.
* @generated By opencode (AI Agent)
* @model gemini-3-flash-preview
* @date Thu Mar 19 2026
* @date Tue Sep 29 2026
*/
(function () {
// Save the original XHR methods
const originalOpen = XMLHttpRequest.prototype.open;
const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
const originalSend = XMLHttpRequest.prototype.send;
const originalFetch = window.fetch;
// We need to track which XHRs are preloads
XMLHttpRequest.prototype.open = function () {
this._isHtmxPreload = false;
return originalOpen.apply(this, arguments);
};
window.fetch = function (input, init) {
const responsePromise = originalFetch.apply(this, arguments);
XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
if (header.toLowerCase() === "hx-preloaded" && value === "true") {
this._isHtmxPreload = true;
}
return originalSetRequestHeader.apply(this, arguments);
};
let method = init?.method;
if (!method && input instanceof Request) method = input.method;
method = (method || "GET").toUpperCase();
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");
responsePromise
.then((response) => {
const contentType = response.headers.get("content-type") || "";
if (method !== "GET" || !contentType.includes("text/html")) return;
// Find all preload links
const links = doc.querySelectorAll('link[rel="preload"]');
return response
.clone()
.text()
.then((html) => {
const doc = new DOMParser().parseFromString(html, "text/html");
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;
doc.querySelectorAll('link[rel="preload"]').forEach((link) => {
const href = link.getAttribute("href");
if (!href) return;
if (
document.head.querySelector(
`link[rel="preload"][href="${href}"]`,
)
)
return;
// Copy relevant attributes
["as", "type", "media", "fetchpriority", "crossorigin"].forEach(
(attr) => {
const val = link.getAttribute(attr);
if (val) newLink.setAttribute(attr, val);
},
);
const newLink = document.createElement("link");
newLink.rel = "preload";
newLink.href = href;
document.head.appendChild(newLink);
}
});
});
}
return originalSend.apply(this, arguments);
["as", "type", "media", "fetchpriority", "crossorigin"].forEach(
(attr) => {
const val = link.getAttribute(attr);
if (val) newLink.setAttribute(attr, val);
},
);
document.head.appendChild(newLink);
});
doc.querySelectorAll("img[src]").forEach((img) => {
const href = img.getAttribute("src");
if (!href) return;
if (
document.head.querySelector(
`link[rel="preload"][href="${href}"][as="image"]`,
)
)
return;
const newLink = document.createElement("link");
newLink.rel = "preload";
newLink.as = "image";
newLink.href = href;
document.head.appendChild(newLink);
});
});
})
.catch(() => {});
return responsePromise;
};
})();