@@ -42,6 +42,9 @@ let escapeChar = a => ESC[a] || a;
42
42
43
43
let falsey = v => v == null || v === false ;
44
44
45
+ let indent = ( s , char ) => String ( s ) . replace ( / ( \n + ) / g, '$1' + ( char || '\t' ) ) ;
46
+
47
+ let isLargeString = s => ( String ( s ) . length > 40 || String ( s ) . indexOf ( '\n' ) !== - 1 || String ( s ) . indexOf ( '<' ) !== - 1 ) ;
45
48
46
49
/** Render Preact JSX + Components to an HTML string.
47
50
* @name render
@@ -51,6 +54,7 @@ let falsey = v => v==null || v===false;
51
54
* @param {Object } [options={}] Rendering options
52
55
* @param {Boolean } [options.shallow=false] If `true`, renders nested Components as HTML elements (`<Foo a="b" />`).
53
56
* @param {Boolean } [options.xml=false] If `true`, uses self-closing tags for elements without children.
57
+ * @param {Boolean } [options.pretty=false] If `true`, adds whitespace for readability
54
58
*/
55
59
renderToString . render = renderToString ;
56
60
@@ -77,6 +81,10 @@ renderToString.shallowRender = (vnode, context) => renderToString(vnode, context
77
81
export default function renderToString ( vnode , context , opts , inner ) {
78
82
let { nodeName, attributes, children } = vnode || EMPTY ;
79
83
context = context || { } ;
84
+ opts = opts || { } ;
85
+
86
+ let pretty = opts . pretty ,
87
+ indentChar = typeof pretty === 'string' ? pretty : '\t' ;
80
88
81
89
// #text nodes
82
90
if ( ! nodeName ) {
@@ -85,7 +93,7 @@ export default function renderToString(vnode, context, opts, inner) {
85
93
86
94
// components
87
95
if ( typeof nodeName === 'function' ) {
88
- if ( opts && opts . shallow && ( inner || ( opts && opts . renderRootComponent === false ) ) ) {
96
+ if ( opts . shallow && ( inner || opts . renderRootComponent === false ) ) {
89
97
nodeName = getComponentName ( nodeName ) ;
90
98
}
91
99
else {
@@ -108,7 +116,7 @@ export default function renderToString(vnode, context, opts, inner) {
108
116
}
109
117
}
110
118
111
- return renderToString ( rendered , context , opts , ! opts || opts . shallowHighOrder !== false ) ;
119
+ return renderToString ( rendered , context , opts , opts . shallowHighOrder !== false ) ;
112
120
}
113
121
}
114
122
@@ -140,25 +148,47 @@ export default function renderToString(vnode, context, opts, inner) {
140
148
141
149
s += '>' ;
142
150
151
+ // if (pretty) s += '\n' + indentChar;
152
+
143
153
if ( html ) {
154
+ // if multiline, indent.
155
+ if ( pretty && isLargeString ( html ) ) {
156
+ html = '\n' + indentChar + indent ( html , indentChar ) ;
157
+ }
144
158
s += html ;
145
159
}
146
160
else {
147
161
let len = children && children . length ;
148
162
if ( len ) {
163
+ let pieces = [ ] ,
164
+ hasLarge = false ;
149
165
for ( let i = 0 ; i < len ; i ++ ) {
150
166
let child = children [ i ] ;
151
167
if ( ! falsey ( child ) ) {
152
- s += renderToString ( child , context , opts , true ) ;
168
+ let ret = renderToString ( child , context , opts , true ) ;
169
+ // if (pretty && isLargeString(ret)) {
170
+ // if (pretty && isLargeString(ret)) {
171
+ // ret = '\n' + indentChar + indent(ret);
172
+ // }
173
+ //s += ret;
174
+ if ( ! hasLarge && pretty && isLargeString ( ret ) ) hasLarge = true ;
175
+ pieces . push ( ret ) ;
176
+ }
177
+ }
178
+ if ( hasLarge ) {
179
+ for ( let i = pieces . length ; i -- ; ) {
180
+ pieces [ i ] = '\n' + indentChar + indent ( pieces [ i ] , indentChar ) ;
153
181
}
154
182
}
183
+ s += pieces . join ( '' ) ;
155
184
}
156
185
else if ( opts && opts . xml ) {
157
186
return s . substring ( 0 , s . length - 1 ) + ' />' ;
158
187
}
159
188
}
160
189
161
190
if ( VOID_ELEMENTS . indexOf ( nodeName ) === - 1 ) {
191
+ if ( pretty && ~ s . indexOf ( '\n' ) ) s += '\n' ;
162
192
s += `</${ nodeName } >` ;
163
193
}
164
194
0 commit comments