66 assign ,
77 getChildren
88} from './util' ;
9- import { options , Fragment , createElement } from 'preact' ;
9+ import { options } from 'preact' ;
10+
11+ /** @typedef {import('preact').VNode } VNode */
1012
1113const SHALLOW = { shallow : true } ;
1214
@@ -28,7 +30,7 @@ const noop = () => {};
2830 * @param {Boolean } [options.shallow=false] If `true`, renders nested Components as HTML elements (`<Foo a="b" />`).
2931 * @param {Boolean } [options.xml=false] If `true`, uses self-closing tags for elements without children.
3032 * @param {Boolean } [options.pretty=false] If `true`, adds whitespace for readability
31- * @param {RegEx |undefined } [options.voidElements] RegeEx that matches elements that are considered void (self-closing)
33+ * @param {RegExp |undefined } [options.voidElements] RegeEx that matches elements that are considered void (self-closing)
3234 */
3335renderToString . render = renderToString ;
3436
@@ -43,6 +45,8 @@ let shallowRender = (vnode, context) => renderToString(vnode, context, SHALLOW);
4345
4446const EMPTY_ARR = [ ] ;
4547function renderToString ( vnode , context , opts ) {
48+ context = context || { } ;
49+ opts = opts || { } ;
4650 const res = _renderToString ( vnode , context , opts ) ;
4751 // options._commit, we don't schedule any effects in this library right now,
4852 // so we can pass an empty queue to this hook.
@@ -56,48 +60,40 @@ function _renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
5660 return '' ;
5761 }
5862
63+ // #text nodes
64+ if ( typeof vnode !== 'object' ) {
65+ return encodeEntities ( vnode ) ;
66+ }
67+
68+ let pretty = opts . pretty ,
69+ indentChar = pretty && typeof pretty === 'string' ? pretty : '\t' ;
70+
5971 // wrap array nodes in Fragment
6072 if ( Array . isArray ( vnode ) ) {
61- vnode = createElement ( Fragment , null , vnode ) ;
73+ let rendered = '' ;
74+ for ( let i = 0 ; i < vnode . length ; i ++ ) {
75+ if ( pretty && i > 0 ) rendered += '\n' ;
76+ rendered += _renderToString (
77+ vnode [ i ] ,
78+ context ,
79+ opts ,
80+ inner ,
81+ isSvgMode ,
82+ selectValue
83+ ) ;
84+ }
85+ return rendered ;
6286 }
6387
6488 let nodeName = vnode . type ,
6589 props = vnode . props ,
6690 isComponent = false ;
67- context = context || { } ;
68- opts = opts || { } ;
69-
70- let pretty = opts . pretty ,
71- indentChar = pretty && typeof pretty === 'string' ? pretty : '\t' ;
72-
73- // #text nodes
74- if ( typeof vnode !== 'object' && ! nodeName ) {
75- return encodeEntities ( vnode ) ;
76- }
7791
7892 // components
7993 if ( typeof nodeName === 'function' ) {
8094 isComponent = true ;
8195 if ( opts . shallow && ( inner || opts . renderRootComponent === false ) ) {
8296 nodeName = getComponentName ( nodeName ) ;
83- } else if ( nodeName === Fragment ) {
84- let rendered = '' ;
85- let children = [ ] ;
86- getChildren ( children , vnode . props . children ) ;
87-
88- for ( let i = 0 ; i < children . length ; i ++ ) {
89- rendered +=
90- ( i > 0 && pretty ? '\n' : '' ) +
91- _renderToString (
92- children [ i ] ,
93- context ,
94- opts ,
95- opts . shallowHighOrder !== false ,
96- isSvgMode ,
97- selectValue
98- ) ;
99- }
100- return rendered ;
10197 } else {
10298 let rendered ;
10399
@@ -197,7 +193,7 @@ function _renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
197193 }
198194
199195 // render JSX to HTML
200- let s = '' ,
196+ let s = '<' + nodeName ,
201197 propChildren ,
202198 html ;
203199
@@ -215,7 +211,7 @@ function _renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
215211 continue ;
216212 }
217213
218- if ( name . match ( / [ \s \n \\ / = ' " \0 < > ] / ) ) continue ;
214+ if ( UNSAFE_NAME . test ( name ) ) continue ;
219215
220216 if (
221217 ! ( opts && opts . allAttributes ) &&
@@ -287,18 +283,19 @@ function _renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
287283
288284 // account for >1 multiline attribute
289285 if ( pretty ) {
290- let sub = s . replace ( / ^ \n \s * / , ' ' ) ;
286+ let sub = s . replace ( / \n \s * / , ' ' ) ;
291287 if ( sub !== s && ! ~ sub . indexOf ( '\n' ) ) s = sub ;
292288 else if ( pretty && ~ s . indexOf ( '\n' ) ) s += '\n' ;
293289 }
294290
295- s = `<${ nodeName } ${ s } >` ;
296- if ( UNSAFE_NAME . test ( String ( nodeName ) ) )
291+ s += '>' ;
292+
293+ if ( UNSAFE_NAME . test ( nodeName ) )
297294 throw new Error ( `${ nodeName } is not a valid HTML tag name in ${ s } ` ) ;
298295
299296 let isVoid =
300- VOID_ELEMENTS . test ( String ( nodeName ) ) ||
301- ( opts . voidElements && opts . voidElements . test ( String ( nodeName ) ) ) ;
297+ VOID_ELEMENTS . test ( nodeName ) ||
298+ ( opts . voidElements && opts . voidElements . test ( nodeName ) ) ;
302299 let pieces = [ ] ;
303300
304301 let children ;
0 commit comments