HS: Group 11 misc — toggle-var-cycle, closest-to, tailwind class, toggle timing (+3 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 6m13s

- parser: `toggle $var between v1 and v2 ...` → `(toggle-var-cycle $var (v1 v2 ...))`
- compiler: emit `(hs-toggle-var-cycle! win var-name values)` for new AST node
- runtime: `hs-toggle-var-cycle!` cycles through a list of values on a variable
- parser: `closest .sel to .target` / `closest #id to .target` / `closest sel to .target`
  now consumes the `to` keyword and parses the target expr instead of defaulting to beingTold
- tokenizer: `read-class-name` handles backslash escapes and allows `(`, `)`, `&`
  chars so Tailwind classes like `group-[:nth-of-type(3)_&]:block` tokenize correctly
- platform.py: `domListen` drives async result via `_driveAsync` after `cekCall`
- test: fixed-time toggle asserts `.foo` IS present after click (toggle started, 10ms window open)
- generate-sx-tests.py: aligned MANUAL_TEST_BODIES for timed toggle with corrected assertion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-04 17:03:52 +00:00
parent d47db58cde
commit d9b7e1e392
12 changed files with 569 additions and 306 deletions

View File

@@ -140,15 +140,35 @@
((and (= kind (quote closest)) (= typ "ident") (= val "parent"))
(do (adv!) (parse-trav (quote closest-parent))))
((= typ "selector")
(do (adv!) (list kind val (list (quote beingTold)))))
(do
(adv!)
(list
kind
val
(if
(and (= kind (quote closest)) (match-kw "to"))
(parse-expr)
(list (quote beingTold))))))
((= typ "class")
(do
(adv!)
(list kind (str "." val) (list (quote beingTold)))))
(list
kind
(str "." val)
(if
(and (= kind (quote closest)) (match-kw "to"))
(parse-expr)
(list (quote beingTold))))))
((= typ "id")
(do
(adv!)
(list kind (str "#" val) (list (quote beingTold)))))
(list
kind
(str "#" val)
(if
(and (= kind (quote closest)) (match-kw "to"))
(parse-expr)
(list (quote beingTold))))))
((= typ "attr")
(do
(adv!)
@@ -1493,6 +1513,40 @@
((tgt (nth expr 1)) (cls (nth expr 2)))
(list (quote toggle-class) cls tgt)))
(true nil)))))
((and (= (tp-type) "ident") (> (len (tp-val)) 0) (= (substring (tp-val) 0 1) "$"))
(let
((var-name (tp-val)))
(adv!)
(if
(match-kw "between")
(let
((val1 (parse-atom)))
(define
collect-vals
(fn
(acc)
(if
(or
(= (tp-type) "comma")
(and
(= (tp-type) "keyword")
(= (tp-val) "and")))
(do
(when (= (tp-type) "comma") (adv!))
(when
(and
(= (tp-type) "keyword")
(= (tp-val) "and"))
(adv!))
(collect-vals (append acc (list (parse-atom)))))
acc)))
(let
((more-vals (collect-vals (list))))
(list
(quote toggle-var-cycle)
var-name
(cons val1 more-vals))))
nil)))
(true nil))))
(define
parse-set-cmd
@@ -2451,7 +2505,8 @@
(if
(or
(at-end?)
(and (= (tp-type) "keyword") (= (tp-val) "end")))
(and (= (tp-type) "keyword") (= (tp-val) "end"))
(and (= (tp-type) "keyword") (= (tp-val) "behavior")))
acc
(let
((feat (parse-feat)))