Skip to content

Commit

Permalink
add parent and children for useId (#237)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
Co-authored-by: Jason Miller <[email protected]>
  • Loading branch information
3 people authored Sep 10, 2022
1 parent 2d0cd1d commit dec7a7a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-baboons-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"preact-render-to-string": patch
---

add parent and children for useId
2 changes: 2 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const SKIP_EFFECTS = '__s';

// VNode properties
export const COMPONENT = '__c';
export const CHILDREN = '__k';
export const PARENT = '__';

// Component properties
export const VNODE = '__v';
Expand Down
74 changes: 49 additions & 25 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
XLINK,
VOID_ELEMENTS
} from './util';
import { options, Fragment } from 'preact';
import { options, h, Fragment } from 'preact';
import { _renderToStringPretty } from './pretty';
import {
COMMIT,
Expand All @@ -16,9 +16,11 @@ import {
DIFFED,
DIRTY,
NEXT_STATE,
PARENT,
RENDER,
SKIP_EFFECTS,
VNODE
VNODE,
CHILDREN
} from './constants';

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

const parent = h(Fragment, null);
parent[CHILDREN] = [vnode];

let res;
if (
opts &&
Expand All @@ -72,7 +77,7 @@ function renderToString(vnode, context, opts) {
) {
res = _renderToStringPretty(vnode, context, opts);
} else {
res = _renderToString(vnode, context, false, undefined);
res = _renderToString(vnode, context, false, undefined, parent);
}

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

/** The default export is an alias of `render()`. */
function _renderToString(vnode, context, isSvgMode, selectValue) {
function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
// Ignore non-rendered VNodes/values
if (vnode == null || vnode === true || vnode === false || vnode === '') {
return '';
Expand All @@ -195,13 +200,16 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
// Recurse into children / Arrays
if (isArray(vnode)) {
let rendered = '';
parent[CHILDREN] = vnode;
for (let i = 0; i < vnode.length; i++) {
rendered =
rendered + _renderToString(vnode[i], context, isSvgMode, selectValue);
rendered +
_renderToString(vnode[i], context, isSvgMode, selectValue, parent);
}
return rendered;
}

vnode[PARENT] = parent;
if (options[DIFF]) options[DIFF](vnode);

let type = vnode.type,
Expand All @@ -210,30 +218,32 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
// Invoke rendering on Components
const isComponent = typeof type === 'function';
if (isComponent) {
if (type === Fragment) {
return _renderToString(
vnode.props.children,
context,
isSvgMode,
selectValue
);
}

let rendered;
if (type.prototype && typeof type.prototype.render === 'function') {
rendered = renderClassComponent(vnode, context);
if (type === Fragment) {
rendered = props.children;
} else {
rendered = renderFunctionComponent(vnode, context);
}
if (type.prototype && typeof type.prototype.render === 'function') {
rendered = renderClassComponent(vnode, context);
} else {
rendered = renderFunctionComponent(vnode, context);
}

let component = vnode[COMPONENT];
if (component.getChildContext) {
context = assign({}, context, component.getChildContext());
let component = vnode[COMPONENT];
if (component.getChildContext) {
context = assign({}, context, component.getChildContext());
}
}

// Recurse into children before invoking the after-diff hook
const str = _renderToString(rendered, context, isSvgMode, selectValue);
const str = _renderToString(
rendered,
context,
isSvgMode,
selectValue,
vnode
);
if (options[DIFFED]) options[DIFFED](vnode);
vnode[PARENT] = undefined;
return str;
}

Expand Down Expand Up @@ -314,13 +324,19 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
pieces = pieces + encodeEntities(children);
hasChildren = true;
} else if (isArray(children)) {
vnode[CHILDREN] = children;
for (let i = 0; i < children.length; i++) {
let child = children[i];

if (child != null && child !== false) {
let childSvgMode =
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
let ret = _renderToString(child, context, childSvgMode, selectValue);
let ret = _renderToString(
child,
context,
childSvgMode,
selectValue,
vnode
);

// Skip if we received an empty string
if (ret) {
Expand All @@ -330,9 +346,16 @@ function _renderToString(vnode, context, isSvgMode, selectValue) {
}
}
} else if (children != null && children !== false && children !== true) {
vnode[CHILDREN] = [children];
let childSvgMode =
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
let ret = _renderToString(children, context, childSvgMode, selectValue);
let ret = _renderToString(
children,
context,
childSvgMode,
selectValue,
vnode
);

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

if (options[DIFFED]) options[DIFFED](vnode);
vnode[PARENT] = undefined;

if (hasChildren) {
s = s + pieces;
Expand Down

0 comments on commit dec7a7a

Please sign in to comment.