Convert htmx-redirect-toast.js to TS; remove dead legacy utils.js (issue #17)
- Add ts/htmx-redirect-toast.ts: typed port of the hx-redirect-toast htmx extension. Stays a classic (non-module) script — only touches the global htmx and registers an extension; layout.py now serves dist/htmx-redirect-toast.js - Delete games/static/js/utils.js: the legacy hand-written copy is dead — every compiled module imports dist/utils.js (from ts/utils.ts); nothing references the old path With this, the only first-party JS served is compiled from ts/; the sole remaining hand-written .js in static is the vendored datepicker.umd.js bundle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* htmx "hx-redirect-toast" extension.
|
||||
*
|
||||
* A custom swap style that performs no DOM swap. On an HX-Redirect response it
|
||||
* navigates immediately (the toast shows on the destination page); otherwise it
|
||||
* turns the HX-Trigger header into CustomEvents so toasts fire in place.
|
||||
*
|
||||
* Classic (non-module) script: it only touches the global htmx and registers an
|
||||
* extension, so it stays a plain <script> like the other vendored-adjacent glue.
|
||||
*/
|
||||
declare const htmx: any;
|
||||
|
||||
(() => {
|
||||
htmx.defineExtension("hx-redirect-toast", {
|
||||
isInlineSwap(swapStyle: string): boolean {
|
||||
return swapStyle === "hx-redirect-toast";
|
||||
},
|
||||
handleSwap(
|
||||
swapStyle: string,
|
||||
target: HTMLElement,
|
||||
fragment: Node,
|
||||
settleInfo: unknown,
|
||||
htmxConfig: { xhr: XMLHttpRequest }
|
||||
): null {
|
||||
const xhr = htmxConfig.xhr;
|
||||
const hxRedirect = xhr.getResponseHeader("HX-Redirect");
|
||||
const hxTrigger = xhr.getResponseHeader("HX-Trigger");
|
||||
|
||||
// Redirect immediately (toast will be shown on the new page)
|
||||
if (hxRedirect) {
|
||||
window.location.href = hxRedirect;
|
||||
}
|
||||
|
||||
// Only dispatch HX-Trigger events for toasts when not redirecting
|
||||
if (!hxRedirect && hxTrigger) {
|
||||
const triggers = JSON.parse(hxTrigger);
|
||||
const events = Array.isArray(triggers) ? triggers : [triggers];
|
||||
events.forEach((triggerObject: Record<string, unknown>) => {
|
||||
Object.entries(triggerObject).forEach(([name, rawDetail]) => {
|
||||
let detail: unknown = rawDetail;
|
||||
try {
|
||||
detail = JSON.parse(rawDetail as string);
|
||||
} catch {
|
||||
// keep as-is
|
||||
}
|
||||
target.dispatchEvent(
|
||||
new CustomEvent(name, {
|
||||
detail,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Return null to prevent any DOM swap
|
||||
return null;
|
||||
},
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user