88
99import { createPlugin } from '../create-plugin' ;
1010import { escape , consumeSanitizedHTML } from '../sanitization' ;
11- import type { Context , SSRDecider as SSRDeciderService } from '../types.js' ;
11+ import type {
12+ Context ,
13+ SSRDecider as SSRDeciderService ,
14+ SSRBodyTemplate as SSRBodyTemplateService ,
15+ } from '../types.js' ;
1216
1317const SSRDecider = createPlugin ( {
1418 provides : ( ) => {
@@ -27,12 +31,62 @@ const SSRDecider = createPlugin({
2731} ) ;
2832export { SSRDecider } ;
2933
34+ const SSRBodyTemplate = createPlugin ( {
35+ provides : ( ) => {
36+ return ctx => {
37+ const { htmlAttrs, bodyAttrs, title, head, body} = ctx . template ;
38+ const safeAttrs = Object . keys ( htmlAttrs )
39+ . map ( attrKey => {
40+ return ` ${ escape ( attrKey ) } ="${ escape ( htmlAttrs [ attrKey ] ) } "` ;
41+ } )
42+ . join ( '' ) ;
43+
44+ const safeBodyAttrs = Object . keys ( bodyAttrs )
45+ . map ( attrKey => {
46+ return ` ${ escape ( attrKey ) } ="${ escape ( bodyAttrs [ attrKey ] ) } "` ;
47+ } )
48+ . join ( '' ) ;
49+
50+ const safeTitle = escape ( title ) ;
51+ // $FlowFixMe
52+ const safeHead = head . map ( consumeSanitizedHTML ) . join ( '' ) ;
53+ // $FlowFixMe
54+ const safeBody = body . map ( consumeSanitizedHTML ) . join ( '' ) ;
55+
56+ const preloadHintLinks = getPreloadHintLinks ( ctx ) ;
57+ const coreGlobals = getCoreGlobals ( ctx ) ;
58+ const chunkScripts = getChunkScripts ( ctx ) ;
59+ const bundleSplittingBootstrap = [
60+ preloadHintLinks ,
61+ coreGlobals ,
62+ chunkScripts ,
63+ ] . join ( '' ) ;
64+
65+ return [
66+ '<!doctype html>' ,
67+ `<html${ safeAttrs } >` ,
68+ `<head>` ,
69+ `<meta charset="utf-8" />` ,
70+ `<title>${ safeTitle } </title>` ,
71+ `${ bundleSplittingBootstrap } ${ safeHead } ` ,
72+ `</head>` ,
73+ `<body${ safeBodyAttrs } >${ ctx . rendered } ${ safeBody } </body>` ,
74+ '</html>' ,
75+ ] . join ( '' ) ;
76+ } ;
77+ } ,
78+ } ) ;
79+
80+ export { SSRBodyTemplate } ;
81+
3082export default function createSSRPlugin ( {
3183 element,
3284 ssrDecider,
85+ ssrBodyTemplate,
3386} : {
3487 element : any ,
3588 ssrDecider : SSRDeciderService ,
89+ ssrBodyTemplate : SSRBodyTemplateService ,
3690} ) {
3791 return async function ssrPlugin ( ctx : Context , next : ( ) = > Promise < void > ) {
3892 if ( ! ssrDecider ( ctx ) ) return next ( ) ;
@@ -57,45 +111,7 @@ export default function createSSRPlugin({
57111 return ;
58112 }
59113
60- const { htmlAttrs, bodyAttrs, title, head, body} = ctx . template ;
61- const safeAttrs = Object . keys ( htmlAttrs )
62- . map ( attrKey => {
63- return ` ${ escape ( attrKey ) } ="${ escape ( htmlAttrs [ attrKey ] ) } "` ;
64- } )
65- . join ( '' ) ;
66-
67- const safeBodyAttrs = Object . keys ( bodyAttrs )
68- . map ( attrKey => {
69- return ` ${ escape ( attrKey ) } ="${ escape ( bodyAttrs [ attrKey ] ) } "` ;
70- } )
71- . join ( '' ) ;
72-
73- const safeTitle = escape ( title ) ;
74- // $FlowFixMe
75- const safeHead = head . map ( consumeSanitizedHTML ) . join ( '' ) ;
76- // $FlowFixMe
77- const safeBody = body . map ( consumeSanitizedHTML ) . join ( '' ) ;
78-
79- const preloadHintLinks = getPreloadHintLinks ( ctx ) ;
80- const coreGlobals = getCoreGlobals ( ctx ) ;
81- const chunkScripts = getChunkScripts ( ctx ) ;
82- const bundleSplittingBootstrap = [
83- preloadHintLinks ,
84- coreGlobals ,
85- chunkScripts ,
86- ] . join ( '' ) ;
87-
88- ctx . body = [
89- '<!doctype html>' ,
90- `<html${ safeAttrs } >` ,
91- `<head>` ,
92- `<meta charset="utf-8" />` ,
93- `<title>${ safeTitle } </title>` ,
94- `${ bundleSplittingBootstrap } ${ safeHead } ` ,
95- `</head>` ,
96- `<body${ safeBodyAttrs } >${ ctx . rendered } ${ safeBody } </body>` ,
97- '</html>' ,
98- ] . join ( '' ) ;
114+ ctx . body = ssrBodyTemplate ( ctx ) ;
99115 } ;
100116}
101117
0 commit comments