Skip to content

Commit 7bc4235

Browse files
committed
web,web/programs: Use idiomorph to preserve DOM on HtmlWhen swap
Fixes program details closing every time the program set changes.
1 parent 64c2b86 commit 7bc4235

File tree

4 files changed

+1422
-6
lines changed

4 files changed

+1422
-6
lines changed

builtin-programs/web/programs.folk

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ Wish the web server handles route "/programs" with handler {
55
set returnList [list "<details data-label='$label' data-count='[llength $programList]'><summary>$prettyLabel ([llength $programList])</summary>"]
66
lappend returnList "<ul>"
77
foreach item $programList {
8-
lappend returnList "<li><details><summary>[dict get $item programName]</summary><pre><code>[htmlEscape [dict get $item programCode]]</code></pre></details></li>"
8+
lappend returnList [subst {
9+
<li id="program-[string map {{ } -} $item(programName)]"><details>
10+
<summary>$item(programName)</summary>
11+
<pre><code>[htmlEscape $item(programCode)]</code></pre>
12+
</details></li>
13+
}]
914
}
1015
lappend returnList "</ul>"
1116
lappend returnList "</details>"
@@ -62,6 +67,7 @@ Wish the web server handles route "/programs" with handler {
6267
}
6368
</style>
6469
<script src="/lib/folk.js"></script>
70+
<script src="/vendor/idiomorph.js"></script>
6571
<script>
6672
const folk = new FolkWS();
6773
</script>
@@ -70,7 +76,10 @@ Wish the web server handles route "/programs" with handler {
7076
[HtmlWhen the collected results for [list /programName/ has program code /programCode/] \
7177
are /programs/ {
7278
emitHtmlForPrograms $programs
73-
}]
79+
80+
} -beforeAttributeUpdated {(attributeName, node, mutationType) => {
81+
if (attributeName === "open") { return false; }
82+
}}]
7483
</body>
7584
</html>
7685
}]

builtin-programs/web/web.folk

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ proc handlePage {path httpStatusVar contentTypeVar} {
4444
set contentType "text/javascript"
4545
readFile "lib/folk.js" contentType
4646
}
47+
"/vendor/idiomorph.js" {
48+
set contentType "text/javascript"
49+
readFile "vendor/idiomorph.js" contentType
50+
}
4751
default {
4852
upvar $httpStatusVar httpStatus
4953
set httpStatus "HTTP/1.1 404 Not Found"
@@ -79,8 +83,23 @@ proc parseQueryString {queryString} {
7983
}
8084

8185
fn HtmlWhen args {
82-
set body [lindex $args end]
83-
set pattern [lreplace $args end end]
86+
set callbacks [dict create]
87+
set pattern [list]
88+
for {set i 0} {$i < [llength $args]} {incr i} {
89+
set arg [lindex $args $i]
90+
if {$arg in [list "-beforeNodeAdded" "-afterNodeAdded" "-beforeNodeMorphed" \
91+
"-afterNodeMorphed" "-beforeNodeRemoved" "-afterNodeRemoved" \
92+
"-beforeAttributeUpdated"]} {
93+
incr i
94+
dict set callbacks [string range $arg 1 end] \
95+
[lindex $args $i]
96+
} else {
97+
lappend pattern $arg
98+
}
99+
}
100+
101+
set body [lindex $pattern end]
102+
set pattern [lreplace $pattern end end]
84103
set envStack [uplevel captureEnvStack]
85104
lappend envStack [list ^HtmlWhen ${^HtmlWhen}]
86105
# TODO: Retract this when the page is closed.
@@ -115,14 +134,17 @@ fn HtmlWhen args {
115134
}
116135
}
117136

137+
set callbacksJs [join [lmap {callbackName callback} $callbacks {
138+
subst {$callbackName: $callback}
139+
}] ,]
118140
return [subst {
119141
<div style="display: contents;">[join $htmls \n]</div>
120142
<script>
121143
(function() {
122144
const el = document.currentScript.previousElementSibling;
145+
const callbacks = {$callbacksJs};
123146
folk.subscribe(`the html for {$pattern} is /html/`, ({html}) => {
124-
// TODO: use morph algorithm.
125-
el.innerHTML = html;
147+
Idiomorph.morph(el, html, {morphStyle:'innerHTML', callbacks:callbacks});
126148
});
127149
})();
128150
</script>

vendor/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ Some of these packages have been modified by us.
1010
<https://github.com/stv0g/c11-queues/tree/b602dcd2df5e835798581c46755487d1aca73e2d>
1111
- wslay is from <https://github.com/tatsuhiro-t/wslay/tree/0e7d106ff89ad6638090fd811a9b2e4c5dda8d40>
1212
- `vk_mem_alloc` is from <https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/blob/e722e57c891a8fbe3cc73ca56c19dd76be242759/include/vk_mem_alloc.h>
13+
- idiomorph is from
14+
<https://github.com/bigskysoftware/idiomorph/blob/10224e0841d4b14bead9f6fd9ac2dfa2d030b4c7/dist/idiomorph.js>

0 commit comments

Comments
 (0)