Add event bindings and data-sx-emit processing
- adapter-dom.sx: detect :on-click/:on-submit etc. in render-dom-element — if attr starts with "on-" and value is callable, wire via dom-listen - orchestration.sx: add process-emit-elements for data-sx-emit attrs — auto-dispatch custom events on click with optional JSON detail - bootstrap_js.py: add processEmitElements RENAME - Regenerate sx-ref.js with all changes - Update reactive-islands status table Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-08T11:12:31Z";
|
||||
var SX_VERSION = "2026-03-08T11:14:47Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -1490,7 +1490,10 @@ continue; } else { return NIL; } } };
|
||||
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
|
||||
var attrName = keywordName(arg);
|
||||
var attrVal = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
|
||||
(isSxTruthy(sxOr(isNil(attrVal), (attrVal == false))) ? NIL : (isSxTruthy(contains(BOOLEAN_ATTRS, attrName)) ? (isSxTruthy(attrVal) ? domSetAttr(el, attrName, "") : NIL) : (isSxTruthy((attrVal == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(attrVal))))));
|
||||
(isSxTruthy(sxOr(isNil(attrVal), (attrVal == false))) ? NIL : (isSxTruthy((isSxTruthy(startsWith(attrName, "on-")) && isCallable(attrVal))) ? (function() {
|
||||
var eventName = substring(attrName, 3, stringLength(attrName));
|
||||
return domListen(el, eventName, attrVal);
|
||||
})() : (isSxTruthy(contains(BOOLEAN_ATTRS, attrName)) ? (isSxTruthy(attrVal) ? domSetAttr(el, attrName, "") : NIL) : (isSxTruthy((attrVal == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(attrVal)))))));
|
||||
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
|
||||
})() : ((isSxTruthy(!isSxTruthy(contains(VOID_ELEMENTS, tag))) ? domAppend(el, renderToDom(arg, env, newNs)) : NIL), assoc(state, "i", (get(state, "i") + 1)))));
|
||||
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
||||
@@ -2496,7 +2499,8 @@ return postSwap(target); })) : NIL);
|
||||
})();
|
||||
processBoosted(root);
|
||||
processSse(root);
|
||||
return bindInlineHandlers(root); };
|
||||
bindInlineHandlers(root);
|
||||
return processEmitElements(root); };
|
||||
|
||||
// process-one
|
||||
var processOne = function(el) { return (function() {
|
||||
@@ -2504,6 +2508,19 @@ return bindInlineHandlers(root); };
|
||||
return (isSxTruthy(verbInfo) ? (isSxTruthy(!isSxTruthy(domHasAttr(el, "sx-disable"))) ? (bindTriggers(el, verbInfo), bindPreloadFor(el)) : NIL) : NIL);
|
||||
})(); };
|
||||
|
||||
// process-emit-elements
|
||||
var processEmitElements = function(root) { return (function() {
|
||||
var els = domQueryAll(sxOr(root, domBody()), "[data-sx-emit]");
|
||||
return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "emit"))) ? (markProcessed(el, "emit"), (function() {
|
||||
var eventName = domGetAttr(el, "data-sx-emit");
|
||||
return (isSxTruthy(eventName) ? domListen(el, "click", function(e) { return (function() {
|
||||
var detailJson = domGetAttr(el, "data-sx-emit-detail");
|
||||
var detail = (isSxTruthy(detailJson) ? jsonParse(detailJson) : {});
|
||||
return domDispatch(el, eventName, detail);
|
||||
})(); }) : NIL);
|
||||
})()) : NIL); }, els);
|
||||
})(); };
|
||||
|
||||
// handle-popstate
|
||||
var handlePopstate = function(scrollY) { return (function() {
|
||||
var url = browserLocationHref();
|
||||
|
||||
Reference in New Issue
Block a user