Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
insert/move were top-level only; a block could never move into/out of a section. content/move-into (relocate to a section child at index, tree-wide) + content/promote (lift nested block to top level, subtree intact). Pure tree transforms like the rest of move.sx; cycle-safe (rejects moving a block into its own descendant). +13 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
146 lines
3.9 KiB
Plaintext
146 lines
3.9 KiB
Plaintext
;; Extension — relative block reorder + tree reparent.
|
|
|
|
(st-bootstrap-classes!)
|
|
(content/bootstrap!)
|
|
(content-bootstrap-section!)
|
|
|
|
(define
|
|
d
|
|
(doc-append
|
|
(doc-append
|
|
(doc-append (doc-empty "d") (mk-text "a" "A"))
|
|
(mk-text "b" "B"))
|
|
(mk-text "c" "C")))
|
|
|
|
;; ── move-before ──
|
|
(content-test
|
|
"move-before"
|
|
(doc-ids (content/move-before d "c" "a"))
|
|
(list "c" "a" "b"))
|
|
(content-test
|
|
"move-before mid"
|
|
(doc-ids (content/move-before d "c" "b"))
|
|
(list "a" "c" "b"))
|
|
(content-test "move-before immutable" (doc-ids d) (list "a" "b" "c"))
|
|
|
|
;; ── move-after ──
|
|
(content-test
|
|
"move-after"
|
|
(doc-ids (content/move-after d "a" "b"))
|
|
(list "b" "a" "c"))
|
|
(content-test
|
|
"move-after last"
|
|
(doc-ids (content/move-after d "a" "c"))
|
|
(list "b" "c" "a"))
|
|
|
|
;; ── move-to-front / back ──
|
|
(content-test
|
|
"move-to-front"
|
|
(doc-ids (content/move-to-front d "c"))
|
|
(list "c" "a" "b"))
|
|
(content-test
|
|
"move-to-back"
|
|
(doc-ids (content/move-to-back d "a"))
|
|
(list "b" "c" "a"))
|
|
(content-test
|
|
"front already first"
|
|
(doc-ids (content/move-to-front d "a"))
|
|
(list "a" "b" "c"))
|
|
|
|
;; ── no-ops ──
|
|
(content-test
|
|
"missing id no-op"
|
|
(doc-ids (content/move-before d "zzz" "a"))
|
|
(list "a" "b" "c"))
|
|
(content-test
|
|
"missing target no-op"
|
|
(doc-ids (content/move-before d "a" "zzz"))
|
|
(list "a" "b" "c"))
|
|
|
|
;; ── render after move ──
|
|
(content-test
|
|
"render after move"
|
|
(asHTML (content/move-after d "a" "c"))
|
|
"<p>B</p><p>C</p><p>A</p>")
|
|
|
|
;; ── reparent: move a top-level block INTO a section ──
|
|
(define
|
|
nd
|
|
(doc-append
|
|
(doc-append (doc-empty "d") (mk-text "p" "P"))
|
|
(mk-section "s" (list (mk-text "x" "X")))))
|
|
(content-test
|
|
"move-into: block leaves top level"
|
|
(doc-ids (content/move-into nd "p" "s" 1))
|
|
(list "s"))
|
|
(content-test
|
|
"move-into: block lands in section at index"
|
|
(doc-tree-ids (content/move-into nd "p" "s" 1))
|
|
(list "s" "x" "p"))
|
|
(content-test
|
|
"move-into at front of section"
|
|
(doc-tree-ids (content/move-into nd "p" "s" 0))
|
|
(list "s" "p" "x"))
|
|
(content-test "move-into immutable" (doc-tree-ids nd) (list "p" "s" "x"))
|
|
|
|
;; ── reparent: move a NESTED block to a different section ──
|
|
(define
|
|
two
|
|
(doc-append
|
|
(doc-append (doc-empty "d") (mk-section "s1" (list (mk-text "n" "N"))))
|
|
(mk-section "s2" (list (mk-text "y" "Y")))))
|
|
(content-test
|
|
"move-into across sections"
|
|
(doc-tree-ids (content/move-into two "n" "s2" 1))
|
|
(list "s1" "s2" "y" "n"))
|
|
|
|
;; ── promote: nested block out to top level (appended last) ──
|
|
(content-test
|
|
"promote nested to top level"
|
|
(doc-tree-ids (content/promote two "n"))
|
|
(list "s1" "s2" "y" "n"))
|
|
(content-test
|
|
"promote leaves section empty shell"
|
|
(doc-ids (content/promote two "n"))
|
|
(list "s1" "s2" "n"))
|
|
(content-test
|
|
"promote a whole section keeps its subtree"
|
|
(doc-tree-ids
|
|
(content/promote
|
|
(doc-append
|
|
(doc-empty "d")
|
|
(mk-section "o" (list (mk-section "i" (list (mk-text "z" "Z"))))))
|
|
"i"))
|
|
(list "o" "i" "z"))
|
|
|
|
;; ── cycle guard: cannot move a section into its own descendant ──
|
|
(define
|
|
nest
|
|
(doc-append
|
|
(doc-empty "d")
|
|
(mk-section
|
|
"outer"
|
|
(list (mk-section "inner" (list (mk-text "t" "T")))))))
|
|
(content-test
|
|
"move section into its own child is a no-op"
|
|
(doc-tree-ids (content/move-into nest "outer" "inner" 0))
|
|
(list "outer" "inner" "t"))
|
|
(content-test
|
|
"move block into itself is a no-op"
|
|
(doc-tree-ids (content/move-into nest "inner" "inner" 0))
|
|
(list "outer" "inner" "t"))
|
|
|
|
;; ── reparent no-ops on missing ids ──
|
|
(content-test
|
|
"move-into missing block no-op"
|
|
(doc-tree-ids (content/move-into nd "zzz" "s" 0))
|
|
(list "p" "s" "x"))
|
|
(content-test
|
|
"move-into missing section no-op"
|
|
(doc-tree-ids (content/move-into nd "p" "zzz" 0))
|
|
(list "p" "s" "x"))
|
|
(content-test
|
|
"promote missing no-op"
|
|
(doc-tree-ids (content/promote nd "zzz"))
|
|
(list "p" "s" "x"))
|