Skip to content

Commit dec7a7a

Browse files
JoviDeCroockdevelopit
andauthoredSep 10, 2022
add parent and children for useId (#237)
* Update index.js * fix tests * Update young-cougars-protect.md * remove changeset * fix * fix tests * Use `props.children` as vnode._children instead of creating a new Array. * unset vnode parent properties after rendering. Also consolidate Fragment and component rendering codepaths. * Create dull-baboons-kneel.md Co-authored-by: Jason Miller <developit@users.noreply.github.com> Co-authored-by: Jason Miller <jason@developit.ca>
1 parent 2d0cd1d commit dec7a7a

File tree

3 files changed

+56
-25
lines changed

3 files changed

+56
-25
lines changed
 

‎.changeset/dull-baboons-kneel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"preact-render-to-string": patch
3+
---
4+
5+
add parent and children for useId

‎src/constants.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export const SKIP_EFFECTS = '__s';
77

88
// VNode properties
99
export const COMPONENT = '__c';
10+
export const CHILDREN = '__k';
11+
export const PARENT = '__';
1012

1113
// Component properties
1214
export const VNODE = '__v';

‎src/index.js

+49-25
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
XLINK,
88
VOID_ELEMENTS
99
} from './util';
10-
import { options, Fragment } from 'preact';
10+
import { options, h, Fragment } from 'preact';
1111
import { _renderToStringPretty } from './pretty';
1212
import {
1313
COMMIT,
@@ -16,9 +16,11 @@ import {
1616
DIFFED,
1717
DIRTY,
1818
NEXT_STATE,
19+
PARENT,
1920
RENDER,
2021
SKIP_EFFECTS,
21-
VNODE
22+
VNODE,
23+
CHILDREN
2224
} from './constants';
2325

2426
/** @typedef {import('preact').VNode} VNode */
@@ -59,6 +61,9 @@ function renderToString(vnode, context, opts) {
5961
const previousSkipEffects = options[SKIP_EFFECTS];
6062
options[SKIP_EFFECTS] = true;
6163

64+
const parent = h(Fragment, null);
65+
parent[CHILDREN] = [vnode];
66+
6267
let res;
6368
if (
6469
opts &&
@@ -72,7 +77,7 @@ function renderToString(vnode, context, opts) {
7277
) {
7378
res = _renderToStringPretty(vnode, context, opts);
7479
} else {
75-
res = _renderToString(vnode, context, false, undefined);
80+
res = _renderToString(vnode, context, false, undefined, parent);
7681
}
7782

7883
// options._commit, we don't schedule any effects in this library right now,
@@ -181,7 +186,7 @@ const isArray = Array.isArray;
181186
const assign = Object.assign;
182187

183188
/** The default export is an alias of `render()`. */
184-
function _renderToString(vnode, context, isSvgMode, selectValue) {
189+
function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
185190
// Ignore non-rendered VNodes/values
186191
if (vnode == null || vnode === true || vnode === false || vnode === '') {
187192
return '';
@@ -195,13 +200,16 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
195200
// Recurse into children / Arrays
196201
if (isArray(vnode)) {
197202
let rendered = '';
203+
parent[CHILDREN] = vnode;
198204
for (let i = 0; i < vnode.length; i++) {
199205
rendered =
200-
rendered + _renderToString(vnode[i], context, isSvgMode, selectValue);
206+
rendered +
207+
_renderToString(vnode[i], context, isSvgMode, selectValue, parent);
201208
}
202209
return rendered;
203210
}
204211

212+
vnode[PARENT] = parent;
205213
if (options[DIFF]) options[DIFF](vnode);
206214

207215
let type = vnode.type,
@@ -210,30 +218,32 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
210218
// Invoke rendering on Components
211219
const isComponent = typeof type === 'function';
212220
if (isComponent) {
213-
if (type === Fragment) {
214-
return _renderToString(
215-
vnode.props.children,
216-
context,
217-
isSvgMode,
218-
selectValue
219-
);
220-
}
221-
222221
let rendered;
223-
if (type.prototype && typeof type.prototype.render === 'function') {
224-
rendered = renderClassComponent(vnode, context);
222+
if (type === Fragment) {
223+
rendered = props.children;
225224
} else {
226-
rendered = renderFunctionComponent(vnode, context);
227-
}
225+
if (type.prototype && typeof type.prototype.render === 'function') {
226+
rendered = renderClassComponent(vnode, context);
227+
} else {
228+
rendered = renderFunctionComponent(vnode, context);
229+
}
228230

229-
let component = vnode[COMPONENT];
230-
if (component.getChildContext) {
231-
context = assign({}, context, component.getChildContext());
231+
let component = vnode[COMPONENT];
232+
if (component.getChildContext) {
233+
context = assign({}, context, component.getChildContext());
234+
}
232235
}
233236

234237
// Recurse into children before invoking the after-diff hook
235-
const str = _renderToString(rendered, context, isSvgMode, selectValue);
238+
const str = _renderToString(
239+
rendered,
240+
context,
241+
isSvgMode,
242+
selectValue,
243+
vnode
244+
);
236245
if (options[DIFFED]) options[DIFFED](vnode);
246+
vnode[PARENT] = undefined;
237247
return str;
238248
}
239249

@@ -314,13 +324,19 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
314324
pieces = pieces + encodeEntities(children);
315325
hasChildren = true;
316326
} else if (isArray(children)) {
327+
vnode[CHILDREN] = children;
317328
for (let i = 0; i < children.length; i++) {
318329
let child = children[i];
319-
320330
if (child != null && child !== false) {
321331
let childSvgMode =
322332
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
323-
let ret = _renderToString(child, context, childSvgMode, selectValue);
333+
let ret = _renderToString(
334+
child,
335+
context,
336+
childSvgMode,
337+
selectValue,
338+
vnode
339+
);
324340

325341
// Skip if we received an empty string
326342
if (ret) {
@@ -330,9 +346,16 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
330346
}
331347
}
332348
} else if (children != null && children !== false && children !== true) {
349+
vnode[CHILDREN] = [children];
333350
let childSvgMode =
334351
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
335-
let ret = _renderToString(children, context, childSvgMode, selectValue);
352+
let ret = _renderToString(
353+
children,
354+
context,
355+
childSvgMode,
356+
selectValue,
357+
vnode
358+
);
336359

337360
// Skip if we received an empty string
338361
if (ret) {
@@ -342,6 +365,7 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
342365
}
343366

344367
if (options[DIFFED]) options[DIFFED](vnode);
368+
vnode[PARENT] = undefined;
345369

346370
if (hasChildren) {
347371
s = s + pieces;

0 commit comments

Comments
 (0)
Please sign in to comment.