Engine: trigger filter support, sx-on event mapping, JS inline handlers

1. parse-trigger-spec: strip [condition] from event names, store as
   "filter" modifier (e.g. keyup[key=='s'] → event="keyup", filter=...)
2. bind-event: evaluate filter conditions via JS Function constructor
   when filter modifier is present
3. bind-inline-handlers: map afterSwap/beforeRequest etc. to sx:*
   event names (matching what the engine dispatches)
4. bind-inline-handlers: detect JS syntax in body (contains ".") and
   eval via Function instead of SX parse — enables this.reset() etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-01 22:56:24 +00:00
parent 13eb701518
commit 235d73d837
6 changed files with 98 additions and 36 deletions

View File

@@ -63,7 +63,26 @@
(starts-with? tok "from:")
(dict-set! mods "from" (slice tok 5))))
(rest tokens))
(dict "event" (first tokens) "modifiers" mods))))))
(let
((raw-event (first tokens)))
(let
((bracket-idx (index-of raw-event "[")))
(if
(>= bracket-idx 0)
(do
(dict-set!
mods
"filter"
(slice
raw-event
(+ bracket-idx 1)
(- (len raw-event) 1)))
(dict
"event"
(slice raw-event 0 bracket-idx)
"modifiers"
mods))
(dict "event" raw-event "modifiers" mods)))))))))
raw-parts))))))
(define

File diff suppressed because one or more lines are too long

View File

@@ -462,7 +462,7 @@
(fn
(e)
(let
((should-fire true))
((should-fire (if (get mods "filter") (host-call (host-call (dom-window) "Function" "event" (get mods "filter")) "call" el e) true)))
(when
(get mods "changed")
(let
@@ -1385,25 +1385,37 @@
(when
(starts-with? name "sx-on:")
(let
((event-name (slice name 6)))
((event-name (let ((raw (slice name 6))) (if (or (starts-with? raw "after") (starts-with? raw "before")) (str "sx:" raw) raw))))
(when
(not (is-processed? el (str "on:" event-name)))
(mark-processed! el (str "on:" event-name))
(let
((exprs (sx-parse body)))
(dom-on
el
event-name
(dom-on
el
event-name
(if
(contains? body ".")
(fn
(e)
(let
((handler-env (env-extend (dict))))
(env-bind! handler-env "event" e)
(env-bind! handler-env "this" el)
(env-bind! handler-env "detail" (event-detail e))
(for-each
(fn (expr) (eval-expr expr handler-env))
exprs))))))))))
(host-call
(host-call (dom-window) "Function" "event" body)
"call"
el
e))
(let
((exprs (parse body)))
(fn
(e)
(let
((handler-env (make-env)))
(env-bind! handler-env "event" e)
(env-bind! handler-env "this" el)
(env-bind!
handler-env
"detail"
(event-detail e))
(for-each
(fn (expr) (eval-expr expr handler-env))
exprs)))))))))))
(dom-attr-list el)))
(dom-query-all (or root (dom-body)) "[sx-on\\:]"))))

File diff suppressed because one or more lines are too long

View File

@@ -63,7 +63,26 @@
(starts-with? tok "from:")
(dict-set! mods "from" (slice tok 5))))
(rest tokens))
(dict "event" (first tokens) "modifiers" mods))))))
(let
((raw-event (first tokens)))
(let
((bracket-idx (index-of raw-event "[")))
(if
(>= bracket-idx 0)
(do
(dict-set!
mods
"filter"
(slice
raw-event
(+ bracket-idx 1)
(- (len raw-event) 1)))
(dict
"event"
(slice raw-event 0 bracket-idx)
"modifiers"
mods))
(dict "event" raw-event "modifiers" mods)))))))))
raw-parts))))))
(define

View File

@@ -462,7 +462,7 @@
(fn
(e)
(let
((should-fire true))
((should-fire (if (get mods "filter") (host-call (host-call (dom-window) "Function" "event" (get mods "filter")) "call" el e) true)))
(when
(get mods "changed")
(let
@@ -1385,25 +1385,37 @@
(when
(starts-with? name "sx-on:")
(let
((event-name (slice name 6)))
((event-name (let ((raw (slice name 6))) (if (or (starts-with? raw "after") (starts-with? raw "before")) (str "sx:" raw) raw))))
(when
(not (is-processed? el (str "on:" event-name)))
(mark-processed! el (str "on:" event-name))
(let
((exprs (sx-parse body)))
(dom-on
el
event-name
(dom-on
el
event-name
(if
(contains? body ".")
(fn
(e)
(let
((handler-env (env-extend (dict))))
(env-bind! handler-env "event" e)
(env-bind! handler-env "this" el)
(env-bind! handler-env "detail" (event-detail e))
(for-each
(fn (expr) (eval-expr expr handler-env))
exprs))))))))))
(host-call
(host-call (dom-window) "Function" "event" body)
"call"
el
e))
(let
((exprs (parse body)))
(fn
(e)
(let
((handler-env (make-env)))
(env-bind! handler-env "event" e)
(env-bind! handler-env "this" el)
(env-bind!
handler-env
"detail"
(event-detail e))
(for-each
(fn (expr) (eval-expr expr handler-env))
exprs)))))))))))
(dom-attr-list el)))
(dom-query-all (or root (dom-body)) "[sx-on\\:]"))))