@@ -182,15 +182,17 @@ const assign = Object.assign;
182
182
183
183
/** The default export is an alias of `render()`. */
184
184
function _renderToString ( vnode , context , isSvgMode , selectValue ) {
185
+ // Ignore non-rendered VNodes/values
185
186
if ( vnode == null || vnode === true || vnode === false || vnode === '' ) {
186
187
return '' ;
187
188
}
188
189
189
- // #text nodes
190
+ // Text VNodes: escape as HTML
190
191
if ( typeof vnode !== 'object' ) {
191
192
return encodeEntities ( vnode ) ;
192
193
}
193
194
195
+ // Recurse into children / Arrays
194
196
if ( isArray ( vnode ) ) {
195
197
let rendered = '' ;
196
198
for ( let i = 0 ; i < vnode . length ; i ++ ) {
@@ -200,13 +202,15 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
200
202
return rendered ;
201
203
}
202
204
203
- let nodeName = vnode . type ,
205
+ if ( options [ DIFF ] ) options [ DIFF ] ( vnode ) ;
206
+
207
+ let type = vnode . type ,
204
208
props = vnode . props ;
205
- const isComponent = typeof nodeName === 'function' ;
206
209
207
- // components
210
+ // Invoke rendering on Components
211
+ const isComponent = typeof type === 'function' ;
208
212
if ( isComponent ) {
209
- if ( nodeName === Fragment ) {
213
+ if ( type === Fragment ) {
210
214
return _renderToString (
211
215
vnode . props . children ,
212
216
context ,
@@ -215,10 +219,8 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
215
219
) ;
216
220
}
217
221
218
- if ( options [ DIFF ] ) options [ DIFF ] ( vnode ) ;
219
-
220
222
let rendered ;
221
- if ( nodeName . prototype && typeof nodeName . prototype . render === 'function' ) {
223
+ if ( type . prototype && typeof type . prototype . render === 'function' ) {
222
224
rendered = renderClassComponent ( vnode , context ) ;
223
225
} else {
224
226
rendered = renderFunctionComponent ( vnode , context ) ;
@@ -229,53 +231,24 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
229
231
context = assign ( { } , context , component . getChildContext ( ) ) ;
230
232
}
231
233
234
+ // Recurse into children before invoking the after-diff hook
235
+ const str = _renderToString ( rendered , context , isSvgMode , selectValue ) ;
232
236
if ( options [ DIFFED ] ) options [ DIFFED ] ( vnode ) ;
233
-
234
- return _renderToString ( rendered , context , isSvgMode , selectValue ) ;
237
+ return str ;
235
238
}
236
239
237
- // render JSX to HTML
240
+ // Serialize Element VNodes to HTML
238
241
let s = '<' ,
239
242
children ,
240
243
html ;
241
244
242
- s = s + nodeName ;
245
+ s = s + type ;
243
246
244
247
if ( props ) {
245
248
children = props . children ;
246
249
for ( let name in props ) {
247
250
let v = props [ name ] ;
248
251
249
- // switch (name) {
250
- // case 'className':
251
- // if ('class' in props) continue;
252
- // name = 'class';
253
- // break;
254
- // case 'htmlFor':
255
- // if ('for' in props) continue;
256
- // name = 'for';
257
- // break;
258
- // case 'defaultValue':
259
- // name = 'value';
260
- // break;
261
- // case 'defaultChecked':
262
- // name = 'checked';
263
- // break;
264
- // case 'defaultSelected':
265
- // name = 'selected';
266
- // break;
267
- // case 'key':
268
- // case 'ref':
269
- // case '__self':
270
- // case '__source':
271
- // case 'children':
272
- // continue;
273
- // default:
274
- // if (isSvgMode && XLINK.test(name)) {
275
- // name = name.toLowerCase().replace(/^xlink:?/, 'xlink:');
276
- // }
277
- // }
278
-
279
252
if (
280
253
name === 'key' ||
281
254
name === 'ref' ||
@@ -295,10 +268,9 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
295
268
296
269
if ( name === 'dangerouslySetInnerHTML' ) {
297
270
html = v && v . __html ;
298
- } else if ( nodeName === 'textarea' && name === 'value' ) {
271
+ } else if ( type === 'textarea' && name === 'value' ) {
299
272
// <textarea value="a&b"> --> <textarea>a&b</textarea>
300
273
children = v ;
301
- // html = encodeEntities(v);
302
274
} else if ( ( v || v === 0 || v === '' ) && typeof v !== 'function' ) {
303
275
if ( v === true || v === '' ) {
304
276
v = name ;
@@ -307,12 +279,12 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
307
279
}
308
280
309
281
if ( name === 'value' ) {
310
- if ( nodeName === 'select' ) {
282
+ if ( type === 'select' ) {
311
283
selectValue = v ;
312
284
continue ;
313
285
} else if (
314
286
// If we're looking at an <option> and it's the currently selected one
315
- nodeName === 'option' &&
287
+ type === 'option' &&
316
288
selectValue == v &&
317
289
// and the <option> doesn't already have a selected attribute on it
318
290
! ( 'selected' in props )
@@ -328,25 +300,17 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
328
300
let startElement = s ;
329
301
s = s + '>' ;
330
302
331
- if ( UNSAFE_NAME . test ( nodeName ) ) {
332
- throw new Error ( `${ nodeName } is not a valid HTML tag name in ${ s } ` ) ;
303
+ if ( UNSAFE_NAME . test ( type ) ) {
304
+ throw new Error ( `${ type } is not a valid HTML tag name in ${ s } ` ) ;
333
305
}
334
306
335
307
let pieces = '' ;
336
308
let hasChildren = false ;
337
309
338
- // let children = isArray(propChildren)
339
- // ? propChildren
340
- // : propChildren != null
341
- // ? [propChildren]
342
- // : undefined;
343
310
if ( html ) {
344
- // return s + html + '</' + nodeName + '>';
345
- // s = s + html;
346
311
pieces = pieces + html ;
347
312
hasChildren = true ;
348
313
} else if ( typeof children === 'string' ) {
349
- // s = s + encodeEntities(children);
350
314
pieces = pieces + encodeEntities ( children ) ;
351
315
hasChildren = true ;
352
316
} else if ( isArray ( children ) ) {
@@ -355,38 +319,37 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
355
319
356
320
if ( child != null && child !== false ) {
357
321
let childSvgMode =
358
- nodeName === 'svg' || ( nodeName !== 'foreignObject' && isSvgMode ) ;
322
+ type === 'svg' || ( type !== 'foreignObject' && isSvgMode ) ;
359
323
let ret = _renderToString ( child , context , childSvgMode , selectValue ) ;
360
324
361
325
// Skip if we received an empty string
362
326
if ( ret ) {
363
- // s = s + ret;
364
327
pieces = pieces + ret ;
365
328
hasChildren = true ;
366
329
}
367
330
}
368
331
}
369
332
} else if ( children != null && children !== false && children !== true ) {
370
333
let childSvgMode =
371
- nodeName === 'svg' || ( nodeName !== 'foreignObject' && isSvgMode ) ;
334
+ type === 'svg' || ( type !== 'foreignObject' && isSvgMode ) ;
372
335
let ret = _renderToString ( children , context , childSvgMode , selectValue ) ;
373
336
374
337
// Skip if we received an empty string
375
338
if ( ret ) {
376
- // s = s + ret;
377
339
pieces = pieces + ret ;
378
340
hasChildren = true ;
379
341
}
380
342
}
381
343
344
+ if ( options [ DIFFED ] ) options [ DIFFED ] ( vnode ) ;
345
+
382
346
if ( hasChildren ) {
383
347
s = s + pieces ;
384
- // return s + pieces + '</' + nodeName + '>';
385
- } else if ( VOID_ELEMENTS . test ( nodeName ) ) {
348
+ } else if ( VOID_ELEMENTS . test ( type ) ) {
386
349
return startElement + ' />' ;
387
350
}
388
351
389
- return s + '</' + nodeName + '>' ;
352
+ return s + '</' + type + '>' ;
390
353
}
391
354
392
355
/** The default export is an alias of `render()`. */
0 commit comments