Checkout i2: Handle text nodes in inner block rendering (https://github.com/woocommerce/woocommerce-blocks/pull/4822)

* Handle text nodes

* Tidy and add inline doc
This commit is contained in:
Mike Jolley 2021-09-24 15:06:21 +01:00 committed by GitHub
parent f9f70893e0
commit 04387a7726
1 changed files with 32 additions and 18 deletions

View File

@ -108,7 +108,7 @@ const renderInnerBlocks = ( {
// Wrapper for inner components.
blockWrapper?: React.ElementType;
// Elements from the DOM being converted to components.
children: HTMLCollection;
children: HTMLCollection | NodeList;
// Depth within the DOM hierarchy.
depth?: number;
} ): ( JSX.Element | null )[] | null => {
@ -133,27 +133,41 @@ const renderInnerBlocks = ( {
/**
* If the component cannot be found, or blockName is missing, return the original element. This also ensures
* that children within the element are processed also, since it may be an element containing block markup.
*
* Note we use childNodes rather than children so that text nodes are also rendered.
*/
if ( ! InnerBlockComponent ) {
const parsedElement = parse( element.outerHTML );
const parsedElement = parse(
element?.outerHTML || element?.textContent || ''
);
if ( isValidElement( parsedElement ) ) {
const elementChildren = renderInnerBlocks( {
block,
blockMap,
children: element.children || [],
depth: depth + 1,
blockWrapper,
} );
return elementChildren
? cloneElement(
parsedElement,
componentProps,
elementChildren
)
: cloneElement( parsedElement, componentProps );
// Returns text nodes without manipulation.
if ( typeof parsedElement === 'string' && !! parsedElement ) {
return parsedElement;
}
return null;
// Do not render invalid elements.
if ( ! isValidElement( parsedElement ) ) {
return null;
}
const renderedChildren = element.childNodes.length
? renderInnerBlocks( {
block,
blockMap,
children: element.childNodes,
depth: depth + 1,
blockWrapper,
} )
: undefined;
return renderedChildren
? cloneElement(
parsedElement,
componentProps,
renderedChildren
)
: cloneElement( parsedElement, componentProps );
}
// This will wrap inner blocks with the provided wrapper. If no wrapper is provided, we default to Fragment.