Fix CSS styles lost during SPA navigation

The text/sx AJAX response path (handle-sx-response) never called
hoist-head-elements, so <style> elements stayed in #sx-content instead
of moving to <head>. Additionally, CSS rules collected during client-side
island hydration were never flushed to the DOM.

- Add hoist-head-elements call to handle-sx-response (matching
  handle-html-response which already had it)
- Add flush-collected-styles helper that drains collected CSS rules
  into a <style data-sx-css> element in <head>
- Call flush after island hydration in post-swap, boot-init, and
  run-post-render-hooks to catch reactive re-renders
- Unify on data-sx-css attribute (existing convention) in ~tw/flush
  and shell template, removing the ad-hoc data-cssx attribute

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 09:37:58 +00:00
parent 90a2eaaf7a
commit 7651260fc7
16 changed files with 691 additions and 84 deletions

View File

@@ -321,7 +321,7 @@
(dom-set-text-content el "")
(dom-append el body-dom)
(dom-set-data el "sx-disposers" disposers)
(process-elements el)
(set-timeout (fn () (process-elements el)) 0)
(log-info
(str
"hydrated island: "
@@ -415,7 +415,8 @@
" lambda: "
(lambda? hook)))
(cek-call hook nil))
*post-render-hooks*)))
*post-render-hooks*)
(flush-collected-styles)))
(define
boot-init
@@ -430,7 +431,8 @@
(sx-hydrate-elements nil)
(sx-hydrate-islands nil)
(run-post-render-hooks)
(process-elements nil)
(flush-collected-styles)
(set-timeout (fn () (process-elements nil)) 0)
(dom-listen (dom-window) "popstate" (fn (e) (handle-popstate 0)))
(dom-set-attr
(host-get (dom-document) "documentElement")