5
5
// a node is not optimizable it simply falls back to the default codegen.
6
6
7
7
// import * as directives from './directives'
8
- import { FULL , SELF , PARTIAL , CHILDREN } from './optimizer'
9
-
8
+ import { optimizability } from './optimizer'
10
9
import {
11
10
genIf ,
12
11
genFor ,
@@ -23,6 +22,16 @@ type SSRCompileResult = {
23
22
stringRenderFns: Array < string > ;
24
23
} ;
25
24
25
+ // segment types
26
+ const HTML = 0
27
+ const TEXT = 1
28
+ const EXP = 2
29
+
30
+ type StringSegment = {
31
+ type : number ;
32
+ value: string ;
33
+ } ;
34
+
26
35
class SSRCodegenState extends CodegenState {
27
36
stringRenderFns : Array < string > ;
28
37
@@ -53,16 +62,16 @@ function genSSRElement (el: ASTElement, state: SSRCodegenState): string {
53
62
}
54
63
55
64
switch ( el . ssrOptimizability ) {
56
- case FULL :
65
+ case optimizability . FULL :
57
66
// stringify whole tree
58
67
return genStringElement ( el , state , true )
59
- case SELF :
68
+ case optimizability . SELF :
60
69
// stringify self and check children
61
70
return genStringElement ( el , state , false )
62
- case CHILDREN :
71
+ case optimizability . CHILDREN :
63
72
// generate self as VNode and stringify children
64
73
return genNormalElement ( el , state , true )
65
- case PARTIAL :
74
+ case optimizability . PARTIAL :
66
75
// generate self as VNode and check children
67
76
return genNormalElement ( el , state , false )
68
77
default :
@@ -71,32 +80,81 @@ function genSSRElement (el: ASTElement, state: SSRCodegenState): string {
71
80
}
72
81
}
73
82
74
- function genSSRNode ( el , state ) {
75
- return el . type === 1
76
- ? genSSRElement ( el , state )
77
- : genText ( el , state )
78
- }
79
-
80
- function genSSRChildren ( el , state , checkSkip ) {
81
- return genChildren ( el , state , checkSkip , genSSRElement , genSSRNode )
82
- }
83
-
84
83
function genNormalElement ( el , state , stringifyChildren ) {
85
84
const data = el . plain ? undefined : genData ( el , state )
86
85
const children = stringifyChildren
87
86
? genStringChildren ( el , state )
88
87
: genSSRChildren ( el , state , true )
89
88
return `_c('${ el . tag } '${
90
- data ? `,${ data } ` : '' // data
89
+ data ? `,${ data } ` : ''
91
90
} ${
92
- children ? `,${ children } ` : '' // children
91
+ children ? `,${ children } ` : ''
93
92
} )`
94
93
}
95
94
96
- function genStringElement ( el , state , stringifyChildren ) {
97
- return '"string element"'
95
+ function genSSRChildren ( el , state , checkSkip ) {
96
+ return genChildren ( el , state , checkSkip , genSSRElement , genSSRNode )
97
+ }
98
+
99
+ function genSSRNode ( el , state ) {
100
+ return el . type === 1
101
+ ? genSSRElement ( el , state )
102
+ : genText ( el , state )
98
103
}
99
104
100
105
function genStringChildren ( el , state ) {
101
- return '"string children"'
106
+ return `[_ss(${ flattenSegments ( childrenToSegments ( el , state ) ) } )]`
107
+ }
108
+
109
+ function genStringElement ( el , state , stringifyChildren ) {
110
+ if ( stringifyChildren ) {
111
+ return `_ss(${ flattenSegments ( elementToSegments ( el , state ) ) } )`
112
+ } else {
113
+ const children = genSSRChildren ( el , state , true )
114
+ return `_ss(${
115
+ flattenSegments ( elementToOpenTagSegments ( el , state ) )
116
+ } ","${ el . tag } "${
117
+ children ? `,${ children } ` : ''
118
+ } )`
119
+ }
120
+ }
121
+
122
+ function elementToSegments ( el , state ) : Array < StringSegment > {
123
+ const openSegments = elementToOpenTagSegments ( el , state )
124
+ const childrenSegments = childrenToSegments ( el , state )
125
+ const { isUnaryTag } = state . options
126
+ const close = ( isUnaryTag && isUnaryTag ( el . tag ) )
127
+ ? [ ]
128
+ : [ { type : HTML , value : `</${ el . tag } >` } ]
129
+ return openSegments . concat ( childrenSegments , close )
130
+ }
131
+
132
+ function elementToOpenTagSegments ( el , state ) : Array < StringSegment > {
133
+ // TODO: handle attrs/props/styles/classes/directives
134
+ return [ { type : HTML , value : `<${ el . tag } >` } ]
135
+ }
136
+
137
+ function childrenToSegments (el, state): Array< StringSegment > {
138
+ const children = el . children
139
+ if ( children ) {
140
+ const segments = [ ]
141
+ for ( let i = 0 ; i < children . length ; i ++ ) {
142
+ const c = children [ i ]
143
+ if ( c . type === 1 ) {
144
+ segments . push . apply ( segments , elementToSegments ( c , state ) )
145
+ } else if ( c . type === 2 ) {
146
+ segments . push ( { type : EXP , value : c . expression } )
147
+ } else if (c.type === 3) {
148
+ segments . push ( { type : TEXT , value : c . text } )
149
+ }
150
+ }
151
+ return segments
152
+ } else {
153
+ return [ ]
154
+ }
155
+ }
156
+
157
+ function flattenSegments ( segments : Array < StringSegment > ): string {
158
+ console . log ( segments )
159
+ return 'TODO'
102
160
}
0 commit comments