HS: as HTML (NodeList elements via outerHTML) + as Fragment (+4 tests)

hs-coerce HTML list case: use outerHTML for element items, not str.
hs-coerce Fragment case: actually build a DocumentFragment — element
items are appended directly; strings are parsed via a temp div.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 06:27:01 +00:00
parent 092da5b819
commit ecd89270c0
3 changed files with 111 additions and 6 deletions

View File

@@ -1210,7 +1210,14 @@
((= type-name "Array") (if (list? value) value (list value)))
((= type-name "HTML")
(cond
((list? value) (join "" (map (fn (x) (str x)) value)))
((list? value)
(join
""
(map
(fn
(x)
(if (hs-element? x) (host-get x "outerHTML") (str x)))
value)))
((hs-element? value) (host-get value "outerHTML"))
(true (str value))))
((= type-name "JSON")
@@ -1261,7 +1268,25 @@
((factor (pow 10 digits)))
(str (/ (floor (+ (* num factor) 0.5)) factor))))))
((= type-name "Selector") (str value))
((= type-name "Fragment") value)
((= type-name "Fragment")
(let
((frag (host-call (dom-document) "createDocumentFragment")))
(do
(for-each
(fn
(item)
(if
(hs-element? item)
(dom-append frag item)
(let
((tmp (dom-create-element "div")))
(do
(dom-set-inner-html tmp (str item))
(for-each
(fn (k) (dom-append frag k))
(host-get tmp "children"))))))
(if (list? value) value (list value)))
frag)))
((= type-name "Values") (hs-as-values value))
((= type-name "Keys")
(if

View File

@@ -3759,7 +3759,25 @@
))
)
(deftest "converts a NodeList into HTML"
(error "SKIP (untranslated): converts a NodeList into HTML"))
(let ((_frag (host-call (dom-document) "createDocumentFragment")))
(let ((_d (dom-create-element "div")))
(do
(host-set! _d "id" "first")
(host-set! _d "innerText" "With Text")
(dom-append _frag _d)
(let ((_span (dom-create-element "span")))
(do
(host-set! _span "id" "second")
(dom-append _frag _span)
(let ((_i (dom-create-element "i")))
(do
(host-set! _i "id" "third")
(dom-append _frag _i)
(let ((_nodeList (host-get _frag "childNodes")))
(assert=
(eval-hs-locals "nodeList as HTML" (list (list (quote nodeList) _nodeList)))
"<div id=\"first\">With Text</div><span id=\"second\"></span><i id=\"third\"></i>")))))))))
)
(deftest "converts a complete form into Values"
(let ((_node (dom-create-element "form")))
(dom-set-inner-html _node "<div><span><b> Catches elements nested deeply within the DOM tree <input name=\"firstName\" value=\"John\"><br> <input name=\"lastName\" value=\"Connor\"><br> <input name=\"phone\" value=\"555-1212\"> </b></span></div> Works with Textareas <textarea name=\"aboutMe\">It began on a warm summer day in 1969...</textarea> Works with Single Select Boxes <select name=\"animal\"> <option value=\"dog\" selected>Doggo</option> <option value=\"cat\">Kitteh</option> <option value=\"raccoon\">Trash Panda</option> <option value=\"possum\">Sleepy Boi</option> </select> Works with Multi-Select Boxes <select name=\"spiritAnimal\" multiple> <option value=\"dog\" selected>Doggo</option> <option value=\"cat\">Kitteh</option> <option value=\"raccoon\" selected>Trash Panda</option> <option value=\"possum\">Sleepy Boi</option> </select> Works with Radio Buttons <input type=\"radio\" name=\"coolOrNaw\" value=\"Cool\" checked> <input type=\"radio\" name=\"coolOrNaw\" value=\"Naw Bruh\"> Works with Checkboxes <input type=\"checkbox\" name=\"gender\" value=\"Male\" checked> <input type=\"checkbox\" name=\"gender\" value=\"Female\" checked> <input type=\"checkbox\" name=\"gender\" value=\"Other\" checked>")
@@ -3858,7 +3876,14 @@
(assert= (eval-hs "[1,2,2,3,3] as Unique") (list 1 2 3))
)
(deftest "converts arrays into fragments"
(error "SKIP (untranslated): converts arrays into fragments"))
(let ((_p (dom-create-element "p")))
(let ((_arr (list _p "<p></p>")))
(let ((_r (eval-hs-locals "value as Fragment" (list (list (quote value) _arr)))))
(do
(assert= (len (host-get _r "children")) 2)
(assert= (host-get (nth (host-get _r "children") 0) "tagName") "P")
(assert= (host-get (nth (host-get _r "children") 1) "tagName") "P")))))
)
(deftest "converts checkboxes into a Value correctly"
(let ((_node (dom-create-element "form")))
(dom-set-inner-html _node "<div> <input type=\"checkbox\" name=\"gender\" value=\"Male\" checked> <input type=\"checkbox\" name=\"gender\" value=\"Female\" checked> <input type=\"checkbox\" name=\"gender\" value=\"Other\" checked> </div>")
@@ -3869,7 +3894,12 @@
))
)
(deftest "converts elements into fragments"
(error "SKIP (untranslated): converts elements into fragments"))
(let ((_p (dom-create-element "p")))
(let ((_r (eval-hs-locals "value as Fragment" (list (list (quote value) _p)))))
(do
(assert= (len (host-get _r "children")) 1)
(assert= (host-get (first (host-get _r "children")) "tagName") "P"))))
)
(deftest "converts multiple selects into a Value correctly"
(let ((_node (dom-create-element "form")))
(dom-set-inner-html _node "<select name=\"animal\" multiple> <option value=\"dog\" selected>Doggo</option> <option value=\"cat\">Kitteh</option> <option value=\"raccoon\" selected>Trash Panda</option> <option value=\"possum\">Sleepy Boi</option> </select>")
@@ -3922,7 +3952,11 @@
(assert= (host-get (eval-hs "'{\"foo\":\"bar\"}' as Object") "foo") "bar")
)
(deftest "converts strings into fragments"
(error "SKIP (untranslated): converts strings into fragments"))
(let ((_r (eval-hs-locals "value as Fragment" (list (list (quote value) "<p></p>")))))
(do
(assert= (len (host-get _r "children")) 1)
(assert= (host-get (first (host-get _r "children")) "tagName") "P")))
)
(deftest "converts value as Boolean"
(assert= (eval-hs "1 as Boolean") true)
(assert= (eval-hs "0 as Boolean") false)

View File

@@ -415,6 +415,52 @@ MANUAL_TEST_BODIES = {
' (hs-activate! _el))',
' (assert (nil? caught))))',
],
# asExpression: NodeList as HTML — each element serialised via outerHTML
"converts a NodeList into HTML": [
' (let ((_frag (host-call (dom-document) "createDocumentFragment")))',
' (let ((_d (dom-create-element "div")))',
' (do',
' (host-set! _d "id" "first")',
' (host-set! _d "innerText" "With Text")',
' (dom-append _frag _d)',
' (let ((_span (dom-create-element "span")))',
' (do',
' (host-set! _span "id" "second")',
' (dom-append _frag _span)',
' (let ((_i (dom-create-element "i")))',
' (do',
' (host-set! _i "id" "third")',
' (dom-append _frag _i)',
' (let ((_nodeList (host-get _frag "childNodes")))',
' (assert=',
' (eval-hs-locals "nodeList as HTML" (list (list (quote nodeList) _nodeList)))',
' "<div id=\\"first\\">With Text</div><span id=\\"second\\"></span><i id=\\"third\\"></i>")))))))))',
],
# asExpression: array of [element, html-string] as Fragment
"converts arrays into fragments": [
' (let ((_p (dom-create-element "p")))',
' (let ((_arr (list _p "<p></p>")))',
' (let ((_r (eval-hs-locals "value as Fragment" (list (list (quote value) _arr)))))',
' (do',
' (assert= (len (host-get _r "children")) 2)',
' (assert= (host-get (nth (host-get _r "children") 0) "tagName") "P")',
' (assert= (host-get (nth (host-get _r "children") 1) "tagName") "P")))))',
],
# asExpression: single element as Fragment wraps it in a DocumentFragment
"converts elements into fragments": [
' (let ((_p (dom-create-element "p")))',
' (let ((_r (eval-hs-locals "value as Fragment" (list (list (quote value) _p)))))',
' (do',
' (assert= (len (host-get _r "children")) 1)',
' (assert= (host-get (first (host-get _r "children")) "tagName") "P"))))',
],
# asExpression: HTML string as Fragment — parses and wraps children
"converts strings into fragments": [
' (let ((_r (eval-hs-locals "value as Fragment" (list (list (quote value) "<p></p>")))))',
' (do',
' (assert= (len (host-get _r "children")) 1)',
' (assert= (host-get (first (host-get _r "children")) "tagName") "P")))',
],
}