From 89543e01529574a382e67f5295978e19af1d868c Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 24 Mar 2026 10:17:18 +0000 Subject: [PATCH] Fix modifier-key click guard in orchestration verb handler The set!-based approach (nested when + mutate + re-check) didn't work because CEK evaluates the outer when condition once. Replace with a single (when (and should-fire (not modifier-click?)) ...) guard. Co-Authored-By: Claude Opus 4.6 (1M context) --- shared/static/scripts/sx-browser.js | 6 +++--- web/orchestration.sx | 11 ++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/shared/static/scripts/sx-browser.js b/shared/static/scripts/sx-browser.js index c982b31..1f6aeb0 100644 --- a/shared/static/scripts/sx-browser.js +++ b/shared/static/scripts/sx-browser.js @@ -14,7 +14,7 @@ // ========================================================================= var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } }); - var SX_VERSION = "2026-03-24T10:04:16Z"; + var SX_VERSION = "2026-03-24T10:16:21Z"; function isNil(x) { return x === NIL || x === null || x === undefined; } function isSxTruthy(x) { return x !== false && !isNil(x); } @@ -4185,7 +4185,7 @@ PRIMITIVES["bind-triggers"] = bindTriggers; return (isSxTruthy((val == lastVal)) ? (shouldFire = false) : (lastVal = val)); })(); } - return (isSxTruthy(shouldFire) ? ((isSxTruthy((isSxTruthy((eventName == "click")) && eventModifierKey_p(e))) ? (shouldFire = false) : NIL), (isSxTruthy(shouldFire) ? ((isSxTruthy(sxOr((eventName == "submit"), (isSxTruthy((eventName == "click")) && domHasAttr(el, "href")))) ? preventDefault_(e) : NIL), (function() { + return (isSxTruthy((isSxTruthy(shouldFire) && !isSxTruthy((isSxTruthy((eventName == "click")) && eventModifierKey_p(e))))) ? ((isSxTruthy(sxOr((eventName == "submit"), (isSxTruthy((eventName == "click")) && domHasAttr(el, "href")))) ? preventDefault_(e) : NIL), (function() { var liveInfo = sxOr(getVerbInfo(el), verbInfo); var isGetLink = (isSxTruthy((eventName == "click")) && isSxTruthy((get(liveInfo, "method") == "GET")) && isSxTruthy(domHasAttr(el, "href")) && !isSxTruthy(get(mods, "delay"))); var clientRouted = false; @@ -4193,7 +4193,7 @@ PRIMITIVES["bind-triggers"] = bindTriggers; clientRouted = tryClientRoute(urlPathname(get(liveInfo, "url")), domGetAttr(el, "sx-target")); } return (isSxTruthy(clientRouted) ? (browserPushState(get(liveInfo, "url")), browserScrollTo(0, 0)) : ((isSxTruthy(isGetLink) ? logInfo((String("sx:route server fetch ") + String(get(liveInfo, "url")))) : NIL), (isSxTruthy(get(mods, "delay")) ? (clearTimeout_(timer), (timer = setTimeout_(function() { return executeRequest(el, NIL, NIL); }, get(mods, "delay")))) : executeRequest(el, NIL, NIL)))); -})()) : NIL)) : NIL); +})()) : NIL); })(); }, (isSxTruthy(get(mods, "once")) ? {["once"]: true} : NIL)) : NIL); })(); }; PRIMITIVES["bind-event"] = bindEvent; diff --git a/web/orchestration.sx b/web/orchestration.sx index 6100aa3..63c01ec 100644 --- a/web/orchestration.sx +++ b/web/orchestration.sx @@ -415,12 +415,9 @@ (set! should-fire false) (set! last-val val)))) - (when should-fire - ;; Let browser handle modifier-key clicks (ctrl-click → new tab) - (when (and (= event-name "click") (event-modifier-key? e)) - (set! should-fire false)) - - (when should-fire + ;; Let browser handle modifier-key clicks (ctrl-click → new tab) + (when (and should-fire + (not (and (= event-name "click") (event-modifier-key? e)))) ;; Prevent default for submit/click on links (when (or (= event-name "submit") (and (= event-name "click") @@ -453,7 +450,7 @@ (set-timeout (fn () (execute-request el nil nil)) (get mods "delay")))) - (execute-request el nil nil))))))))) + (execute-request el nil nil)))))))) (if (get mods "once") (dict "once" true) nil))))))