preact-render-to-string 5.2.4 → 5.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +102 -102
- package/dist/commonjs.js +1 -1
- package/dist/commonjs.js.map +1 -1
- package/dist/index.d.ts +16 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.module.js +1 -1
- package/dist/index.module.js.map +1 -1
- package/dist/jsx-entry.js +1 -1
- package/dist/jsx-entry.js.map +1 -1
- package/dist/jsx.d.ts +13 -13
- package/dist/jsx.js.map +1 -1
- package/dist/jsx.mjs +1 -1
- package/dist/jsx.modern.js +1 -1
- package/dist/jsx.modern.js.map +1 -1
- package/dist/jsx.module.js +1 -1
- package/dist/jsx.module.js.map +1 -1
- package/jsx.js +1 -1
- package/package.json +148 -148
- package/src/constants.js +16 -16
- package/src/index.d.ts +16 -16
- package/src/index.js +406 -396
- package/src/jsx.d.ts +13 -13
- package/src/jsx.js +76 -76
- package/src/polyfills.js +8 -8
- package/src/pretty.js +389 -385
- package/src/util.js +125 -125
- package/typings.json +5 -5
package/src/pretty.js
CHANGED
|
@@ -1,385 +1,389 @@
|
|
|
1
|
-
import {
|
|
2
|
-
encodeEntities,
|
|
3
|
-
indent,
|
|
4
|
-
isLargeString,
|
|
5
|
-
styleObjToCss,
|
|
6
|
-
getChildren,
|
|
7
|
-
createComponent,
|
|
8
|
-
getContext,
|
|
9
|
-
UNSAFE_NAME,
|
|
10
|
-
XLINK,
|
|
11
|
-
VOID_ELEMENTS
|
|
12
|
-
} from './util';
|
|
13
|
-
import { options, Fragment } from 'preact';
|
|
14
|
-
|
|
15
|
-
// components without names, kept as a hash for later comparison to return consistent UnnamedComponentXX names.
|
|
16
|
-
const UNNAMED = [];
|
|
17
|
-
|
|
18
|
-
export function _renderToStringPretty(
|
|
19
|
-
vnode,
|
|
20
|
-
context,
|
|
21
|
-
opts,
|
|
22
|
-
inner,
|
|
23
|
-
isSvgMode,
|
|
24
|
-
selectValue
|
|
25
|
-
) {
|
|
26
|
-
if (vnode == null || typeof vnode === 'boolean') {
|
|
27
|
-
return '';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// #text nodes
|
|
31
|
-
if (typeof vnode !== 'object') {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
rendered =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
isComponent =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
c
|
|
115
|
-
c.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
c.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
c.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
name = '
|
|
199
|
-
} else if (name === '
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
encodeEntities,
|
|
3
|
+
indent,
|
|
4
|
+
isLargeString,
|
|
5
|
+
styleObjToCss,
|
|
6
|
+
getChildren,
|
|
7
|
+
createComponent,
|
|
8
|
+
getContext,
|
|
9
|
+
UNSAFE_NAME,
|
|
10
|
+
XLINK,
|
|
11
|
+
VOID_ELEMENTS
|
|
12
|
+
} from './util';
|
|
13
|
+
import { options, Fragment } from 'preact';
|
|
14
|
+
|
|
15
|
+
// components without names, kept as a hash for later comparison to return consistent UnnamedComponentXX names.
|
|
16
|
+
const UNNAMED = [];
|
|
17
|
+
|
|
18
|
+
export function _renderToStringPretty(
|
|
19
|
+
vnode,
|
|
20
|
+
context,
|
|
21
|
+
opts,
|
|
22
|
+
inner,
|
|
23
|
+
isSvgMode,
|
|
24
|
+
selectValue
|
|
25
|
+
) {
|
|
26
|
+
if (vnode == null || typeof vnode === 'boolean') {
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// #text nodes
|
|
31
|
+
if (typeof vnode !== 'object') {
|
|
32
|
+
if (typeof vnode === 'function') return '';
|
|
33
|
+
return encodeEntities(vnode);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let pretty = opts.pretty,
|
|
37
|
+
indentChar = pretty && typeof pretty === 'string' ? pretty : '\t';
|
|
38
|
+
|
|
39
|
+
if (Array.isArray(vnode)) {
|
|
40
|
+
let rendered = '';
|
|
41
|
+
for (let i = 0; i < vnode.length; i++) {
|
|
42
|
+
if (pretty && i > 0) rendered = rendered + '\n';
|
|
43
|
+
rendered =
|
|
44
|
+
rendered +
|
|
45
|
+
_renderToStringPretty(
|
|
46
|
+
vnode[i],
|
|
47
|
+
context,
|
|
48
|
+
opts,
|
|
49
|
+
inner,
|
|
50
|
+
isSvgMode,
|
|
51
|
+
selectValue
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return rendered;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// VNodes have {constructor:undefined} to prevent JSON injection:
|
|
58
|
+
if (vnode.constructor !== undefined) return '';
|
|
59
|
+
|
|
60
|
+
let nodeName = vnode.type,
|
|
61
|
+
props = vnode.props,
|
|
62
|
+
isComponent = false;
|
|
63
|
+
|
|
64
|
+
// components
|
|
65
|
+
if (typeof nodeName === 'function') {
|
|
66
|
+
isComponent = true;
|
|
67
|
+
if (opts.shallow && (inner || opts.renderRootComponent === false)) {
|
|
68
|
+
nodeName = getComponentName(nodeName);
|
|
69
|
+
} else if (nodeName === Fragment) {
|
|
70
|
+
const children = [];
|
|
71
|
+
getChildren(children, vnode.props.children);
|
|
72
|
+
return _renderToStringPretty(
|
|
73
|
+
children,
|
|
74
|
+
context,
|
|
75
|
+
opts,
|
|
76
|
+
opts.shallowHighOrder !== false,
|
|
77
|
+
isSvgMode,
|
|
78
|
+
selectValue
|
|
79
|
+
);
|
|
80
|
+
} else {
|
|
81
|
+
let rendered;
|
|
82
|
+
|
|
83
|
+
let c = (vnode.__c = createComponent(vnode, context));
|
|
84
|
+
|
|
85
|
+
// options._diff
|
|
86
|
+
if (options.__b) options.__b(vnode);
|
|
87
|
+
|
|
88
|
+
// options._render
|
|
89
|
+
let renderHook = options.__r;
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
!nodeName.prototype ||
|
|
93
|
+
typeof nodeName.prototype.render !== 'function'
|
|
94
|
+
) {
|
|
95
|
+
let cctx = getContext(nodeName, context);
|
|
96
|
+
|
|
97
|
+
// If a hook invokes setState() to invalidate the component during rendering,
|
|
98
|
+
// re-render it up to 25 times to allow "settling" of memoized states.
|
|
99
|
+
// Note:
|
|
100
|
+
// This will need to be updated for Preact 11 to use internal.flags rather than component._dirty:
|
|
101
|
+
// https://github.com/preactjs/preact/blob/d4ca6fdb19bc715e49fd144e69f7296b2f4daa40/src/diff/component.js#L35-L44
|
|
102
|
+
let count = 0;
|
|
103
|
+
while (c.__d && count++ < 25) {
|
|
104
|
+
c.__d = false;
|
|
105
|
+
|
|
106
|
+
if (renderHook) renderHook(vnode);
|
|
107
|
+
|
|
108
|
+
// stateless functional components
|
|
109
|
+
rendered = nodeName.call(vnode.__c, props, cctx);
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
let cctx = getContext(nodeName, context);
|
|
113
|
+
|
|
114
|
+
// c = new nodeName(props, context);
|
|
115
|
+
c = vnode.__c = new nodeName(props, cctx);
|
|
116
|
+
c.__v = vnode;
|
|
117
|
+
// turn off stateful re-rendering:
|
|
118
|
+
c._dirty = c.__d = true;
|
|
119
|
+
c.props = props;
|
|
120
|
+
if (c.state == null) c.state = {};
|
|
121
|
+
|
|
122
|
+
if (c._nextState == null && c.__s == null) {
|
|
123
|
+
c._nextState = c.__s = c.state;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
c.context = cctx;
|
|
127
|
+
if (nodeName.getDerivedStateFromProps)
|
|
128
|
+
c.state = Object.assign(
|
|
129
|
+
{},
|
|
130
|
+
c.state,
|
|
131
|
+
nodeName.getDerivedStateFromProps(c.props, c.state)
|
|
132
|
+
);
|
|
133
|
+
else if (c.componentWillMount) {
|
|
134
|
+
c.componentWillMount();
|
|
135
|
+
|
|
136
|
+
// If the user called setState in cWM we need to flush pending,
|
|
137
|
+
// state updates. This is the same behaviour in React.
|
|
138
|
+
c.state =
|
|
139
|
+
c._nextState !== c.state
|
|
140
|
+
? c._nextState
|
|
141
|
+
: c.__s !== c.state
|
|
142
|
+
? c.__s
|
|
143
|
+
: c.state;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (renderHook) renderHook(vnode);
|
|
147
|
+
|
|
148
|
+
rendered = c.render(c.props, c.state, c.context);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (c.getChildContext) {
|
|
152
|
+
context = Object.assign({}, context, c.getChildContext());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (options.diffed) options.diffed(vnode);
|
|
156
|
+
return _renderToStringPretty(
|
|
157
|
+
rendered,
|
|
158
|
+
context,
|
|
159
|
+
opts,
|
|
160
|
+
opts.shallowHighOrder !== false,
|
|
161
|
+
isSvgMode,
|
|
162
|
+
selectValue
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// render JSX to HTML
|
|
168
|
+
let s = '<' + nodeName,
|
|
169
|
+
propChildren,
|
|
170
|
+
html;
|
|
171
|
+
|
|
172
|
+
if (props) {
|
|
173
|
+
let attrs = Object.keys(props);
|
|
174
|
+
|
|
175
|
+
// allow sorting lexicographically for more determinism (useful for tests, such as via preact-jsx-chai)
|
|
176
|
+
if (opts && opts.sortAttributes === true) attrs.sort();
|
|
177
|
+
|
|
178
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
179
|
+
let name = attrs[i],
|
|
180
|
+
v = props[name];
|
|
181
|
+
if (name === 'children') {
|
|
182
|
+
propChildren = v;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (UNSAFE_NAME.test(name)) continue;
|
|
187
|
+
|
|
188
|
+
if (
|
|
189
|
+
!(opts && opts.allAttributes) &&
|
|
190
|
+
(name === 'key' ||
|
|
191
|
+
name === 'ref' ||
|
|
192
|
+
name === '__self' ||
|
|
193
|
+
name === '__source')
|
|
194
|
+
)
|
|
195
|
+
continue;
|
|
196
|
+
|
|
197
|
+
if (name === 'defaultValue') {
|
|
198
|
+
name = 'value';
|
|
199
|
+
} else if (name === 'defaultChecked') {
|
|
200
|
+
name = 'checked';
|
|
201
|
+
} else if (name === 'defaultSelected') {
|
|
202
|
+
name = 'selected';
|
|
203
|
+
} else if (name === 'className') {
|
|
204
|
+
if (typeof props.class !== 'undefined') continue;
|
|
205
|
+
name = 'class';
|
|
206
|
+
} else if (isSvgMode && XLINK.test(name)) {
|
|
207
|
+
name = name.toLowerCase().replace(/^xlink:?/, 'xlink:');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (name === 'htmlFor') {
|
|
211
|
+
if (props.for) continue;
|
|
212
|
+
name = 'for';
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (name === 'style' && v && typeof v === 'object') {
|
|
216
|
+
v = styleObjToCss(v);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// always use string values instead of booleans for aria attributes
|
|
220
|
+
// also see https://github.com/preactjs/preact/pull/2347/files
|
|
221
|
+
if (name[0] === 'a' && name['1'] === 'r' && typeof v === 'boolean') {
|
|
222
|
+
v = String(v);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
let hooked =
|
|
226
|
+
opts.attributeHook &&
|
|
227
|
+
opts.attributeHook(name, v, context, opts, isComponent);
|
|
228
|
+
if (hooked || hooked === '') {
|
|
229
|
+
s = s + hooked;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (name === 'dangerouslySetInnerHTML') {
|
|
234
|
+
html = v && v.__html;
|
|
235
|
+
} else if (nodeName === 'textarea' && name === 'value') {
|
|
236
|
+
// <textarea value="a&b"> --> <textarea>a&b</textarea>
|
|
237
|
+
propChildren = v;
|
|
238
|
+
} else if ((v || v === 0 || v === '') && typeof v !== 'function') {
|
|
239
|
+
if (v === true || v === '') {
|
|
240
|
+
v = name;
|
|
241
|
+
// in non-xml mode, allow boolean attributes
|
|
242
|
+
if (!opts || !opts.xml) {
|
|
243
|
+
s = s + ' ' + name;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (name === 'value') {
|
|
249
|
+
if (nodeName === 'select') {
|
|
250
|
+
selectValue = v;
|
|
251
|
+
continue;
|
|
252
|
+
} else if (
|
|
253
|
+
// If we're looking at an <option> and it's the currently selected one
|
|
254
|
+
nodeName === 'option' &&
|
|
255
|
+
selectValue == v &&
|
|
256
|
+
// and the <option> doesn't already have a selected attribute on it
|
|
257
|
+
typeof props.selected === 'undefined'
|
|
258
|
+
) {
|
|
259
|
+
s = s + ` selected`;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
s = s + ` ${name}="${encodeEntities(v)}"`;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// account for >1 multiline attribute
|
|
268
|
+
if (pretty) {
|
|
269
|
+
let sub = s.replace(/\n\s*/, ' ');
|
|
270
|
+
if (sub !== s && !~sub.indexOf('\n')) s = sub;
|
|
271
|
+
else if (pretty && ~s.indexOf('\n')) s = s + '\n';
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
s = s + '>';
|
|
275
|
+
|
|
276
|
+
if (UNSAFE_NAME.test(nodeName))
|
|
277
|
+
throw new Error(`${nodeName} is not a valid HTML tag name in ${s}`);
|
|
278
|
+
|
|
279
|
+
let isVoid =
|
|
280
|
+
VOID_ELEMENTS.test(nodeName) ||
|
|
281
|
+
(opts.voidElements && opts.voidElements.test(nodeName));
|
|
282
|
+
let pieces = [];
|
|
283
|
+
|
|
284
|
+
let children;
|
|
285
|
+
if (html) {
|
|
286
|
+
// if multiline, indent.
|
|
287
|
+
if (pretty && isLargeString(html)) {
|
|
288
|
+
html = '\n' + indentChar + indent(html, indentChar);
|
|
289
|
+
}
|
|
290
|
+
s = s + html;
|
|
291
|
+
} else if (
|
|
292
|
+
propChildren != null &&
|
|
293
|
+
getChildren((children = []), propChildren).length
|
|
294
|
+
) {
|
|
295
|
+
let hasLarge = pretty && ~s.indexOf('\n');
|
|
296
|
+
let lastWasText = false;
|
|
297
|
+
|
|
298
|
+
for (let i = 0; i < children.length; i++) {
|
|
299
|
+
let child = children[i];
|
|
300
|
+
|
|
301
|
+
if (child != null && child !== false) {
|
|
302
|
+
let childSvgMode =
|
|
303
|
+
nodeName === 'svg'
|
|
304
|
+
? true
|
|
305
|
+
: nodeName === 'foreignObject'
|
|
306
|
+
? false
|
|
307
|
+
: isSvgMode,
|
|
308
|
+
ret = _renderToStringPretty(
|
|
309
|
+
child,
|
|
310
|
+
context,
|
|
311
|
+
opts,
|
|
312
|
+
true,
|
|
313
|
+
childSvgMode,
|
|
314
|
+
selectValue
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
if (pretty && !hasLarge && isLargeString(ret)) hasLarge = true;
|
|
318
|
+
|
|
319
|
+
// Skip if we received an empty string
|
|
320
|
+
if (ret) {
|
|
321
|
+
if (pretty) {
|
|
322
|
+
let isText = ret.length > 0 && ret[0] != '<';
|
|
323
|
+
|
|
324
|
+
// We merge adjacent text nodes, otherwise each piece would be printed
|
|
325
|
+
// on a new line.
|
|
326
|
+
if (lastWasText && isText) {
|
|
327
|
+
pieces[pieces.length - 1] += ret;
|
|
328
|
+
} else {
|
|
329
|
+
pieces.push(ret);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
lastWasText = isText;
|
|
333
|
+
} else {
|
|
334
|
+
pieces.push(ret);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (pretty && hasLarge) {
|
|
340
|
+
for (let i = pieces.length; i--; ) {
|
|
341
|
+
pieces[i] = '\n' + indentChar + indent(pieces[i], indentChar);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (pieces.length || html) {
|
|
347
|
+
s = s + pieces.join('');
|
|
348
|
+
} else if (opts && opts.xml) {
|
|
349
|
+
return s.substring(0, s.length - 1) + ' />';
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (isVoid && !children && !html) {
|
|
353
|
+
s = s.replace(/>$/, ' />');
|
|
354
|
+
} else {
|
|
355
|
+
if (pretty && ~s.indexOf('\n')) s = s + '\n';
|
|
356
|
+
s = s + `</${nodeName}>`;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return s;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function getComponentName(component) {
|
|
363
|
+
return (
|
|
364
|
+
component.displayName ||
|
|
365
|
+
(component !== Function && component.name) ||
|
|
366
|
+
getFallbackComponentName(component)
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function getFallbackComponentName(component) {
|
|
371
|
+
let str = Function.prototype.toString.call(component),
|
|
372
|
+
name = (str.match(/^\s*function\s+([^( ]+)/) || '')[1];
|
|
373
|
+
if (!name) {
|
|
374
|
+
// search for an existing indexed name for the given component:
|
|
375
|
+
let index = -1;
|
|
376
|
+
for (let i = UNNAMED.length; i--; ) {
|
|
377
|
+
if (UNNAMED[i] === component) {
|
|
378
|
+
index = i;
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// not found, create a new indexed name:
|
|
383
|
+
if (index < 0) {
|
|
384
|
+
index = UNNAMED.push(component) - 1;
|
|
385
|
+
}
|
|
386
|
+
name = `UnnamedComponent${index}`;
|
|
387
|
+
}
|
|
388
|
+
return name;
|
|
389
|
+
}
|