Fix element paths in virtualRender

master
Vitaliy Filippov 2021-09-20 02:28:44 +03:00
parent cee9239c22
commit 4f72118fe8
1 changed files with 13 additions and 46 deletions

View File

@ -2,6 +2,7 @@
// Simpler alternative to react-test-renderer, also allows to visit element tree during rendering
//
// (c) Vitaliy Filippov 2021+
// Version: 2021-09-20
// License: Dual-license MPL 1.1+ or GNU LGPL 3.0+
// Credits to react-apollo/getDataFromTree.ts and react-tree-walker
@ -15,7 +16,9 @@ const ensureChild = child => (child && typeof child.render === "function" ? ensu
// Preact puts children directly on element, and React via props
const getChildren = element =>
element.props && element.props.children ? element.props.children : element.children ? element.children : undefined;
element.props && element.props.children !== undefined
? element.props.children
: element.children;
// Preact uses "nodeName", React uses "type"
const getType = element => element.type || element.nodeName;
@ -103,51 +106,7 @@ function walkTree(tree, visitor, context, options, path = '')
key = ':'+series+':'+index;
else
key = '['+key+']';
let typeName;
if (type && type.name)
typeName = type.name;
else if (typeof type == 'symbol')
typeName = type.toString();
else
typeName = type;
res.push(walkTree(item, visitor, context, options, path+'/'+typeName+'['+key+']'));
}
return res;
}
if (tree instanceof Array)
{
// Process array, remembering keys and indices within series of elements of the same type
let index = 0, series = 0;
let lastType = null, lastHasKey = false;
let res = [];
for (let item of tree)
{
if (item)
{
let type = getType(item);
let key = item.key;
if (lastType == type && lastHasKey == (key != null))
index++;
else
{
series++;
index = 0;
lastType = type;
lastHasKey = (key != null);
}
if (key == null)
key = ':'+series+':'+index;
else
key = '['+key+']';
let typeName;
if (type && type.name)
typeName = type.name;
else if (typeof type == 'symbol')
typeName = type.toString();
else
typeName = type;
res.push(walkTree(item, visitor, context, options, path+'/'+typeName+'['+key+']'));
}
res.push(walkTree(item, visitor, context, options, path+key));
}
return res;
}
@ -173,6 +132,14 @@ function walkTree(tree, visitor, context, options, path = '')
if (isReactElement(tree))
{
const Component = getType(tree);
let typeName;
if (Component && Component.name)
typeName = Component.name;
else if (typeof Component == 'symbol')
typeName = Component.toString();
else
typeName = Component;
path += '/'+typeName;
const visitChildren = (render, compInstance, elContext, childContext) =>
{
const result = visitor ? visitor(tree, path, compInstance, elContext, childContext) : true;