HS take command: class/attr with+giving, attr removal from scope, giving keyword

- tokenizer: add 'giving' as keyword so parse-take-cmd can detect it.
- parser.sx parse-take-cmd: loop over 'with <class>' / 'giving <class>' /
  'from <sel>' / 'for <tgt>' clauses in any order for both the class and
  attribute cases. Emits uniform (take! kind name from-sel for-tgt
  attr-val with-val) 7-slot AST.
- compiler emit-take: pass with-cls for the class case through to runtime.
- runtime hs-take!: with a class 'with' replacement, toggle both classes
  across scope + target. For attribute take, always strip the attr from
  the scope 'others' (setting to with-val if given, otherwise removing).
- generator pw-body: translate evaluate(() => document.querySelector(s).
  click()) and .dispatchEvent(new Event('name', …)) into dom-dispatch ops
  so bubbling-click assertions in 'parent takes…' tests work.
- generator toHaveClass: strip JS regex word-boundaries (\\b) from the
  expected class name.
- shared/static/wasm/sx/dom.sx: dom-child-list / dom-child-nodes mirror
  the dom-query-all SX-list passthrough — childNodes arrives pre-SXified.

Net: take 6→15 (100%), remove 16→17, fetch 11→15.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 16:51:17 +00:00
parent 3528cef35a
commit 601fdc1c34
11 changed files with 356 additions and 143 deletions

View File

@@ -349,7 +349,9 @@
(dom-append _el-div _el-btn1)
(hs-activate! _el-div)
(host-set! (host-global "window") "clicks" 0)
(dom-dispatch (dom-query-by-id "btn1") "click" nil)
(dom-dispatch _el-div "click" nil)
(dom-dispatch (dom-query-by-id "btn1") "click" nil)
))
(deftest "append to undefined ignores the undefined"
(hs-cleanup!)
@@ -1987,6 +1989,7 @@
(dom-append (dom-body) _el-target)
(dom-append (dom-body) _el-other)
(hs-activate! _el-target)
(dom-dispatch (dom-query-by-id "other") "click" nil)
))
(deftest "can remove class by id"
(hs-cleanup!)
@@ -10177,6 +10180,7 @@
(let ((_el-untilTest (dom-create-element "div")))
(dom-set-attr _el-untilTest "id" "untilTest")
(dom-append (dom-body) _el-untilTest)
(dom-dispatch (dom-query-by-id "untilTest") "click" nil)
))
(deftest "until keyword works"
(hs-cleanup!)
@@ -11434,6 +11438,7 @@
(dom-append _el-div _el-d2)
(dom-append _el-div _el-d3)
(hs-activate! _el-div)
(dom-dispatch (dom-query-by-id "d2") "click" nil)
(assert (not (dom-has-class? (dom-query-by-id "d1") "foo")))
(assert (dom-has-class? (dom-query-by-id "d2") "foo"))
(assert (not (dom-has-class? (dom-query-by-id "d3") "foo")))
@@ -11454,6 +11459,7 @@
(dom-append _el-div _el-d2)
(dom-append _el-div _el-d3)
(hs-activate! _el-div)
(dom-dispatch (dom-query-by-id "d2") "click" nil)
(assert (not (dom-has-attr? (dom-query-by-id "d1") "data-foo")))
(assert= (dom-get-attr (dom-query-by-id "d2") "data-foo") "")
(assert (not (dom-has-attr? (dom-query-by-id "d3") "data-foo")))
@@ -11474,8 +11480,8 @@
(hs-activate! _el-div1)
(dom-dispatch (nth (dom-query-all (dom-body) "div") 1) "click" nil)
(assert (dom-has-class? _el-div "unselected"))
(assert (not (dom-has-class? _el-div "\bselected\b")))
(assert (dom-has-class? (nth (dom-query-all (dom-body) "div") 1) "\bselected\b"))
(assert (not (dom-has-class? _el-div "selected")))
(assert (dom-has-class? (nth (dom-query-all (dom-body) "div") 1) "selected"))
(assert (not (dom-has-class? (nth (dom-query-all (dom-body) "div") 1) "unselected")))
(assert (dom-has-class? (nth (dom-query-all (dom-body) "div") 2) "unselected"))
))
@@ -11492,9 +11498,9 @@
(dom-append (dom-body) _el-div2)
(hs-activate! _el-div1)
(dom-dispatch (nth (dom-query-all (dom-body) "div") 1) "click" nil)
(assert (not (dom-has-class? _el-div "\bselected\b")))
(assert (not (dom-has-class? _el-div "selected")))
(assert (dom-has-class? _el-div "unselected"))
(assert (dom-has-class? (nth (dom-query-all (dom-body) "div") 1) "\bselected\b"))
(assert (dom-has-class? (nth (dom-query-all (dom-body) "div") 1) "selected"))
(assert (not (dom-has-class? (nth (dom-query-all (dom-body) "div") 1) "unselected")))
(assert (dom-has-class? (nth (dom-query-all (dom-body) "div") 2) "unselected"))
))
@@ -12610,6 +12616,7 @@ end")
(assert (not (dom-has-class? (dom-query "div:nth-of-type(2)") "foo")))
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
(assert (dom-has-class? (dom-query "div:nth-of-type(2)") "foo"))
(dom-dispatch (dom-query-by-id "d1") "foo" nil)
(assert (not (dom-has-class? (dom-query "div:nth-of-type(2)") "foo")))
))
(deftest "can toggle visibility"
@@ -12980,6 +12987,7 @@ end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert= (dom-text-content _el-div) "bar")
))
(deftest "can wait on event"
@@ -12991,6 +12999,7 @@ end")
(dom-dispatch _el-div "click" nil)
(assert (dom-has-class? _el-div "foo"))
(assert (not (dom-has-class? _el-div "bar")))
(dom-dispatch _el-div "foo" nil)
(assert (dom-has-class? _el-div "bar"))
))
(deftest "can wait on event on another element"
@@ -13004,6 +13013,7 @@ end")
(dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil)
(assert (dom-has-class? (dom-query "div:nth-of-type(2)") "foo"))
(assert (not (dom-has-class? (dom-query "div:nth-of-type(2)") "bar")))
(dom-dispatch (dom-query-by-id "d2") "foo" nil)
(assert (dom-has-class? (dom-query "div:nth-of-type(2)") "bar"))
))
(deftest "can wait on event or timeout 1"
@@ -13043,6 +13053,7 @@ end")
(dom-append (dom-body) _el-div)
(hs-activate! _el-div)
(dom-dispatch _el-div "click" nil)
(dom-dispatch _el-div "foo" nil)
(assert= (dom-text-content _el-div) "hyperscript is hyper cool")
))
)