Skip to content

Commit

Permalink
Footnotes/RichText: fix getRichTextValues for deeply nested blocks (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored and tellthemachines committed Aug 1, 2023
1 parent b93e9c1 commit 9a04e31
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import { Content } from './content';
* except that it does not render the elements to a string, but instead collects
* the values of all rich text `Content` elements.
*/
function addValuesForElement( element, ...args ) {
function addValuesForElement( element, values, innerBlocks ) {
if ( null === element || undefined === element || false === element ) {
return;
}

if ( Array.isArray( element ) ) {
return addValuesForElements( element, ...args );
return addValuesForElements( element, values, innerBlocks );
}

switch ( typeof element ) {
Expand All @@ -38,35 +38,32 @@ function addValuesForElement( element, ...args ) {
switch ( type ) {
case StrictMode:
case Fragment:
return addValuesForElements( props.children, ...args );
return addValuesForElements( props.children, values, innerBlocks );
case RawHTML:
return;
case InnerBlocks.Content:
return addValuesForBlocks( ...args );
return addValuesForBlocks( values, innerBlocks );
case Content:
const [ values ] = args;
values.push( props.value );
return;
}

switch ( typeof type ) {
case 'string':
if ( typeof props.children !== 'undefined' ) {
return addValuesForElements( props.children, ...args );
return addValuesForElements(
props.children,
values,
innerBlocks
);
}
return;
case 'function':
if (
type.prototype &&
typeof type.prototype.render === 'function'
) {
return addValuesForElement(
new type( props ).render(),
...args
);
}

return addValuesForElement( type( props ), ...args );
const el =
type.prototype && typeof type.prototype.render === 'function'
? new type( props ).render()
: type( props );
return addValuesForElement( el, values, innerBlocks );
}
}

Expand All @@ -78,20 +75,17 @@ function addValuesForElements( children, ...args ) {
}
}

function _getSaveElement( name, attributes, innerBlocks ) {
return getSaveElement(
name,
attributes,
innerBlocks.map( ( block ) =>
_getSaveElement( block.name, block.attributes, block.innerBlocks )
)
);
}

function addValuesForBlocks( values, blocks ) {
for ( let i = 0; i < blocks.length; i++ ) {
const { name, attributes, innerBlocks } = blocks[ i ];
const saveElement = _getSaveElement( name, attributes, innerBlocks );
const saveElement = getSaveElement(
name,
attributes,
// Instead of letting save elements use `useInnerBlocksProps.save`,
// force them to use InnerBlocks.Content instead so we can intercept
// a single component.
<InnerBlocks.Content />
);
addValuesForElement( saveElement, values, innerBlocks );
}
}
Expand Down
11 changes: 5 additions & 6 deletions packages/blocks/src/api/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,11 @@ export function getBlockProps( props = {} ) {
*/
export function getInnerBlocksProps( props = {} ) {
const { innerBlocks } = innerBlocksPropsProvider;
const [ firstBlock ] = innerBlocks ?? [];
if ( ! firstBlock ) return props;
// If the innerBlocks passed to `getSaveElement` are not blocks but already
// components, return the props as is. This is the case for
// `getRichTextValues`.
if ( ! firstBlock.clientId ) return { ...props, children: innerBlocks };
// Allow a different component to be passed to getSaveElement to handle
// inner blocks, bypassing the default serialisation.
if ( ! Array.isArray( innerBlocks ) ) {
return { ...props, children: innerBlocks };
}
// Value is an array of blocks, so defer to block serializer.
const html = serialize( innerBlocks, { isInnerBlocks: true } );
// Use special-cased raw HTML tag to avoid default escaping.
Expand Down

0 comments on commit 9a04e31

Please sign in to comment.