diff options
Diffstat (limited to 'src/runtime.ffi.mjs')
-rw-r--r-- | src/runtime.ffi.mjs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/runtime.ffi.mjs b/src/runtime.ffi.mjs index c3cec68..f7b711b 100644 --- a/src/runtime.ffi.mjs +++ b/src/runtime.ffi.mjs @@ -227,6 +227,32 @@ function morphElement(prev, curr, dispatch, parent) { function morphAttr(el, name, value, dispatch) { switch (typeof value) { + case name.startsWith("data-lustre-on-") && "string": { + if (!value) { + el.removeAttribute(name); + el.removeEventListener(event, el.$lustre[`${name}Handler`]); + + break; + } + if (el.hasAttribute(name)) break; + + const event = name.slice(15).toLowerCase(); + const handler = (e) => dispatch(serverEventHandler(e)); + + if (el.$lustre[`${name}Handler`]) { + el.removeEventListener(event, el.$lustre[`${name}Handler`]); + } + + el.addEventListener(event, handler); + + el.$lustre[name] = value; + el.$lustre[`${name}Handler`] = handler; + el.$lustre.__registered_events.add(name); + el.setAttribute(name, value); + + break; + } + case "string": if (el.getAttribute(name) !== value) el.setAttribute(name, value); if (value === "") el.removeAttribute(name); @@ -281,3 +307,38 @@ function morphText(prev, curr) { return prev; } + +// UTILS ----------------------------------------------------------------------- + +function serverEventHandler(event) { + const el = event.target; + const tag = el.getAttribute(`data-lustre-on-${event.type}`); + const data = JSON.parse(el.getAttribute("data-lustre-data") || "{}"); + const include = JSON.parse(el.getAttribute("data-lustre-include") || "[]"); + + switch (event.type) { + case "input": + case "change": + include.push("target.value"); + break; + } + + return { + tag, + data: include.reduce((data, property) => { + const path = property.split("."); + + for (let i = 0, o = data, e = event; i < path.length; i++) { + if (i === path.length - 1) { + o[path[i]] = e[path[i]]; + } else { + o[path[i]] ??= {}; + e = e[path[i]]; + o = o[path[i]]; + } + } + + return data; + }, data), + }; +} |