@@ -2,81 +2,7 @@ import React, { Children, createElement, isValidElement, PropsWithChildren, Reac
22import type { AlephRuntime } from './types.ts'
33import util , { hashShort } from './util.ts'
44
5- const serverHeadElements : Map < string , { type : string , props : Record < string , any > } > = new Map ( )
6- const serverStyles : Map < string , { css : string , asLink : boolean } > = new Map ( )
7-
8- export async function renderHead ( styles ?: { url : string , hash : string , async ?: boolean } [ ] ) {
9- const { __appRoot, __buildMode, __buildTarget } = ( window as any ) . ALEPH as AlephRuntime
10- const tags : string [ ] = [ ]
11- serverHeadElements . forEach ( ( { type, props } ) => {
12- if ( type === 'title' ) {
13- if ( util . isNEString ( props . children ) ) {
14- tags . push ( `<title ssr>${ props . children } </title>` )
15- } else if ( util . isNEArray ( props . children ) ) {
16- tags . push ( `<title ssr>${ props . children . join ( '' ) } </title>` )
17- }
18- } else {
19- const attrs = Object . keys ( props )
20- . filter ( key => key !== 'children' )
21- . map ( key => ` ${ key } =${ JSON . stringify ( props [ key ] ) } ` )
22- . join ( '' )
23- if ( util . isNEString ( props . children ) ) {
24- tags . push ( `<${ type } ${ attrs } ssr>${ props . children } </${ type } >` )
25- } else if ( util . isNEArray ( props . children ) ) {
26- tags . push ( `<${ type } ${ attrs } ssr>${ props . children . join ( '' ) } </${ type } >` )
27- } else {
28- tags . push ( `<${ type } ${ attrs } ssr />` )
29- }
30- }
31- } )
32- await Promise . all ( styles ?. filter ( ( { async } ) => ! ! async ) . map ( ( { url, hash } ) => {
33- return import ( 'file://' + util . cleanPath ( `${ __appRoot } /.aleph/${ __buildMode } .${ __buildTarget } /${ url } .${ hash . slice ( 0 , hashShort ) } .js` ) )
34- } ) || [ ] )
35- styles ?. forEach ( ( { url } ) => {
36- if ( serverStyles . has ( url ) ) {
37- const { css, asLink } = serverStyles . get ( url ) !
38- if ( asLink ) {
39- tags . push ( `<link rel="stylesheet" href="${ css } " data-module-id=${ JSON . stringify ( url ) } />` )
40- } else {
41- tags . push ( `<style type="text/css" data-module-id=${ JSON . stringify ( url ) } >${ css } </style>` )
42- }
43- }
44- } )
45- serverHeadElements . clear ( )
46- return tags
47- }
48-
49- export function applyCSS ( id : string , css : string , asLink : boolean = false ) {
50- if ( window . Deno ) {
51- serverStyles . set ( id , { css, asLink } )
52- } else {
53- const { document } = ( window as any )
54- const styleEl = document . createElement ( asLink ? 'link' : 'style' )
55- const prevStyleEls = Array . from ( document . head . children ) . filter ( ( el : any ) => el . getAttribute ( 'data-module-id' ) === id )
56- if ( asLink ) {
57- styleEl . rel = 'stylesheet'
58- styleEl . href = css
59- } else {
60- styleEl . type = 'text/css'
61- styleEl . appendChild ( document . createTextNode ( css ) )
62- }
63- styleEl . setAttribute ( 'data-module-id' , id )
64- document . head . appendChild ( styleEl )
65- if ( prevStyleEls . length > 0 ) {
66- if ( asLink ) {
67- styleEl . addEventListener ( 'load' , ( ) => {
68- prevStyleEls . forEach ( el => document . head . removeChild ( el ) )
69- } )
70- } else {
71- setTimeout ( ( ) => {
72- prevStyleEls . forEach ( el => document . head . removeChild ( el ) )
73- } , 0 )
74- }
75- }
76- }
77- }
78-
79- export function Head ( { children } : PropsWithChildren < { } > ) {
5+ export default function Head ( { children } : PropsWithChildren < { } > ) {
806 if ( window . Deno ) {
817 parse ( children ) . forEach ( ( { type, props } , key ) => serverHeadElements . set ( key , { type, props } ) )
828 }
@@ -182,6 +108,80 @@ export function Viewport(props: ViewportProps) {
182108 )
183109}
184110
111+ const serverHeadElements : Map < string , { type : string , props : Record < string , any > } > = new Map ( )
112+ const serverStyles : Map < string , { css : string , asLink : boolean } > = new Map ( )
113+
114+ export async function renderHead ( styles ?: { url : string , hash : string , async ?: boolean } [ ] ) {
115+ const { __appRoot, __buildMode, __buildTarget } = ( window as any ) . ALEPH as AlephRuntime
116+ const tags : string [ ] = [ ]
117+ serverHeadElements . forEach ( ( { type, props } ) => {
118+ if ( type === 'title' ) {
119+ if ( util . isNEString ( props . children ) ) {
120+ tags . push ( `<title ssr>${ props . children } </title>` )
121+ } else if ( util . isNEArray ( props . children ) ) {
122+ tags . push ( `<title ssr>${ props . children . join ( '' ) } </title>` )
123+ }
124+ } else {
125+ const attrs = Object . keys ( props )
126+ . filter ( key => key !== 'children' )
127+ . map ( key => ` ${ key } =${ JSON . stringify ( props [ key ] ) } ` )
128+ . join ( '' )
129+ if ( util . isNEString ( props . children ) ) {
130+ tags . push ( `<${ type } ${ attrs } ssr>${ props . children } </${ type } >` )
131+ } else if ( util . isNEArray ( props . children ) ) {
132+ tags . push ( `<${ type } ${ attrs } ssr>${ props . children . join ( '' ) } </${ type } >` )
133+ } else {
134+ tags . push ( `<${ type } ${ attrs } ssr />` )
135+ }
136+ }
137+ } )
138+ await Promise . all ( styles ?. filter ( ( { async } ) => ! ! async ) . map ( ( { url, hash } ) => {
139+ return import ( 'file://' + util . cleanPath ( `${ __appRoot } /.aleph/${ __buildMode } .${ __buildTarget } /${ url } .${ hash . slice ( 0 , hashShort ) } .js` ) )
140+ } ) || [ ] )
141+ styles ?. forEach ( ( { url } ) => {
142+ if ( serverStyles . has ( url ) ) {
143+ const { css, asLink } = serverStyles . get ( url ) !
144+ if ( asLink ) {
145+ tags . push ( `<link rel="stylesheet" href="${ css } " data-module-id=${ JSON . stringify ( url ) } />` )
146+ } else {
147+ tags . push ( `<style type="text/css" data-module-id=${ JSON . stringify ( url ) } >${ css } </style>` )
148+ }
149+ }
150+ } )
151+ serverHeadElements . clear ( )
152+ return tags
153+ }
154+
155+ export function applyCSS ( id : string , css : string , asLink : boolean = false ) {
156+ if ( window . Deno ) {
157+ serverStyles . set ( id , { css, asLink } )
158+ } else {
159+ const { document } = ( window as any )
160+ const styleEl = document . createElement ( asLink ? 'link' : 'style' )
161+ const prevStyleEls = Array . from ( document . head . children ) . filter ( ( el : any ) => el . getAttribute ( 'data-module-id' ) === id )
162+ if ( asLink ) {
163+ styleEl . rel = 'stylesheet'
164+ styleEl . href = css
165+ } else {
166+ styleEl . type = 'text/css'
167+ styleEl . appendChild ( document . createTextNode ( css ) )
168+ }
169+ styleEl . setAttribute ( 'data-module-id' , id )
170+ document . head . appendChild ( styleEl )
171+ if ( prevStyleEls . length > 0 ) {
172+ if ( asLink ) {
173+ styleEl . addEventListener ( 'load' , ( ) => {
174+ prevStyleEls . forEach ( el => document . head . removeChild ( el ) )
175+ } )
176+ } else {
177+ setTimeout ( ( ) => {
178+ prevStyleEls . forEach ( el => document . head . removeChild ( el ) )
179+ } , 0 )
180+ }
181+ }
182+ }
183+ }
184+
185185function parse ( node : ReactNode , els : Map < string , { type : string , props : Record < string , any > } > = new Map ( ) ) {
186186 Children . forEach ( node , child => {
187187 if ( ! isValidElement ( child ) ) {
0 commit comments