prototyped svg reports

This commit is contained in:
2026-07-18 18:24:37 -06:00
parent 22e7b003f6
commit c51ad80dc6
106 changed files with 5450 additions and 46 deletions
+108
View File
@@ -0,0 +1,108 @@
(function(){
const defaultDebounceTimeInMs = 500;
let isReady = false
document.addEventListener('DOMContentLoaded', function() {
isReady = true
})
function onReady(fn) {
if (isReady || document.readyState === 'complete') {
fn()
} else {
document.addEventListener('DOMContentLoaded', fn)
}
}
htmx.defineExtension("resize", {
init: (api) => {
function hasResizeTrigger(elt) {
for (spec of api.getTriggerSpecs(elt)) {
if (spec.trigger === 'resize') {
return true;
}
}
return false;
}
function getDebounceTimeInMs(elt) {
const amountAttr = elt.attributes['hx-resize-debounce'];
if (!amountAttr) {
return defaultDebounceTimeInMs
}
const amountStr = amountAttr.value
if (!amountStr) {
return defaultDebounceTimeInMs
}
try {
return parseInt(amountStr);
} catch (err) {
console.warn('invalid debounce time on trigger:', trigger);
console.error(err);
return defaultDebounceTimeInMs;
}
}
let nextID = 1;
let timeoutIDs = {};
let observers = {};
function processNode(elt) {
if (!hasResizeTrigger(elt)) {
return;
}
let data = elt['hx-resize-internal-data'];
if (!data) {
data = {
id: nextID,
};
nextID += 1;
elt['hx-resize-internal-data'] = data;
}
const obs = new ResizeObserver(() => {
if (timeoutIDs[data.id]) {
return;
}
const debounceTime = getDebounceTimeInMs(elt);
timeoutIDs[data.id] = setTimeout(() => {
elt.dispatchEvent(new Event('resize'));
delete timeoutIDs[data.id];
}, debounceTime);
});
obs.observe(elt);
observers[data.id] = obs;
}
function cleanupNode(elt) {
if (!hasResizeTrigger(elt)) {
return;
}
let data = elt['hx-resize-internal-data'];
if (!data) {
return;
}
const obs = observers[data.id];
if (obs) {
obs.disconnect();
}
delete observers[data.id];
delete timeoutIDs[data.id];
}
// process nodes
htmx.on('htmx:beforeProcessNode', evt => processNode(evt.target));
htmx.on('htmx:beforeCleanupElement', evt => cleanupNode(evt.target));
onReady(function() {
document.querySelectorAll('[hx-trigger]').forEach(processNode);
})
}
});
})()