diff --git a/packages/block-library/src/template-part/edit/import-controls.js b/packages/block-library/src/template-part/edit/import-controls.js index 48178451e33dec..f629691535a327 100644 --- a/packages/block-library/src/template-part/edit/import-controls.js +++ b/packages/block-library/src/template-part/edit/import-controls.js @@ -12,10 +12,6 @@ import { __experimentalHStack as HStack, __experimentalSpacer as Spacer, } from '@wordpress/components'; -import { - switchToBlockType, - getPossibleBlockTransformations, -} from '@wordpress/blocks'; import { store as coreStore } from '@wordpress/core-data'; import { store as noticesStore } from '@wordpress/notices'; @@ -110,36 +106,13 @@ export function TemplatePartImportControls( { area, setAttributes } ) { const blocks = widgets.flatMap( ( widget ) => { const block = transformWidgetToBlock( widget ); - if ( block.name !== 'core/legacy-widget' ) { - return block; - } - - const transforms = getPossibleBlockTransformations( [ - block, - ] ).filter( ( item ) => { - // The block without any transformations can't be a wildcard. - if ( ! item.transforms ) { - return true; - } - - const hasWildCardFrom = item.transforms?.from?.find( - ( from ) => from.blocks && from.blocks.includes( '*' ) - ); - const hasWildCardTo = item.transforms?.to?.find( - ( to ) => to.blocks && to.blocks.includes( '*' ) - ); - - return ! hasWildCardFrom && ! hasWildCardTo; - } ); - // Skip the block if we have no matching transformations. - if ( ! transforms.length ) { + if ( ! block ) { skippedWidgets.add( widget.id_base ); return []; } - // Try transforming the Legacy Widget into a first matching block. - return switchToBlockType( block, transforms[ 0 ].name ); + return block; } ); await createFromBlocks( diff --git a/packages/block-library/src/template-part/edit/utils/transformers.js b/packages/block-library/src/template-part/edit/utils/transformers.js index fdef84d785b909..7932a005729414 100644 --- a/packages/block-library/src/template-part/edit/utils/transformers.js +++ b/packages/block-library/src/template-part/edit/utils/transformers.js @@ -1,7 +1,14 @@ /** * WordPress dependencies */ -import { createBlock, parse } from '@wordpress/blocks'; +import { + parse, + cloneBlock, + createBlock, + getGroupingBlockName, + getPossibleBlockTransformations, + switchToBlockType, +} from '@wordpress/blocks'; /** * Converts a widget entity record into a block. @@ -10,28 +17,98 @@ import { createBlock, parse } from '@wordpress/blocks'; * @return {Object} a block (converted from the entity record). */ export function transformWidgetToBlock( widget ) { - if ( widget.id_base === 'block' ) { - const parsedBlocks = parse( widget.instance.raw.content, { - __unstableSkipAutop: true, - } ); - if ( ! parsedBlocks.length ) { - return createBlock( 'core/paragraph', {}, [] ); + if ( widget.id_base !== 'block' ) { + let attributes; + if ( widget._embedded.about[ 0 ].is_multi ) { + attributes = { + idBase: widget.id_base, + instance: widget.instance, + }; + } else { + attributes = { + id: widget.id, + }; } - return parsedBlocks[ 0 ]; + return switchLegacyWidgetType( + createBlock( 'core/legacy-widget', attributes ) + ); } - let attributes; - if ( widget._embedded.about[ 0 ].is_multi ) { - attributes = { - idBase: widget.id_base, - instance: widget.instance, - }; - } else { - attributes = { - id: widget.id, - }; + const parsedBlocks = parse( widget.instance.raw.content, { + __unstableSkipAutop: true, + } ); + + if ( ! parsedBlocks.length ) { + return undefined; + } + + const block = parsedBlocks[ 0 ]; + + if ( block.name === 'core/widget-group' ) { + return createBlock( + getGroupingBlockName(), + undefined, + transformInnerBlocks( block.innerBlocks ) + ); + } + + if ( block.innerBlocks.length > 0 ) { + return cloneBlock( + block, + undefined, + transformInnerBlocks( block.innerBlocks ) + ); + } + + return block; +} + +/** + * Switch Legacy Widget to the first matching transformation block. + * + * @param {Object} block Legacy Widget block object + * @return {Object|undefined} a block + */ +function switchLegacyWidgetType( block ) { + const transforms = getPossibleBlockTransformations( [ block ] ).filter( + ( item ) => { + // The block without any transformations can't be a wildcard. + if ( ! item.transforms ) { + return true; + } + + const hasWildCardFrom = item.transforms?.from?.find( + ( from ) => from.blocks && from.blocks.includes( '*' ) + ); + const hasWildCardTo = item.transforms?.to?.find( + ( to ) => to.blocks && to.blocks.includes( '*' ) + ); + + // Skip wildcard transformations. + return ! hasWildCardFrom && ! hasWildCardTo; + } + ); + + if ( ! transforms.length ) { + return undefined; } - return createBlock( 'core/legacy-widget', attributes, [] ); + return switchToBlockType( block, transforms[ 0 ].name ); +} + +function transformInnerBlocks( innerBlocks = [] ) { + return innerBlocks + .flatMap( ( block ) => { + if ( block.name === 'core/legacy-widget' ) { + return switchLegacyWidgetType( block ); + } + + return createBlock( + block.name, + block.attributes, + transformInnerBlocks( block.innerBlocks ) + ); + } ) + .filter( ( block ) => !! block ); } diff --git a/packages/edit-post/src/index.js b/packages/edit-post/src/index.js index d2889c407690a7..1e0509f3e8f218 100644 --- a/packages/edit-post/src/index.js +++ b/packages/edit-post/src/index.js @@ -11,7 +11,10 @@ import { createRoot } from '@wordpress/element'; import { dispatch, select } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; import { store as preferencesStore } from '@wordpress/preferences'; -import { registerLegacyWidgetBlock } from '@wordpress/widgets'; +import { + registerLegacyWidgetBlock, + registerWidgetGroupBlock, +} from '@wordpress/widgets'; /** * Internal dependencies @@ -68,6 +71,7 @@ export function initializeEditor( registerCoreBlocks(); registerLegacyWidgetBlock( { inserter: false } ); + registerWidgetGroupBlock( { inserter: false } ); if ( process.env.IS_GUTENBERG_PLUGIN ) { __experimentalRegisterExperimentalCoreBlocks( { enableFSEBlocks: settings.__unstableEnableFullSiteEditingBlocks, diff --git a/packages/edit-site/src/index.js b/packages/edit-site/src/index.js index f07f9eed5121d6..d920b02e562ec6 100644 --- a/packages/edit-site/src/index.js +++ b/packages/edit-site/src/index.js @@ -17,7 +17,10 @@ import { import { store as editorStore } from '@wordpress/editor'; import { store as interfaceStore } from '@wordpress/interface'; import { store as preferencesStore } from '@wordpress/preferences'; -import { registerLegacyWidgetBlock } from '@wordpress/widgets'; +import { + registerLegacyWidgetBlock, + registerWidgetGroupBlock, +} from '@wordpress/widgets'; /** * Internal dependencies @@ -47,6 +50,7 @@ export function initializeEditor( id, settings ) { registerCoreBlocks( coreBlocks ); dispatch( blocksStore ).setFreeformFallbackBlockName( 'core/html' ); registerLegacyWidgetBlock( { inserter: false } ); + registerWidgetGroupBlock( { inserter: false } ); if ( process.env.IS_GUTENBERG_PLUGIN ) { __experimentalRegisterExperimentalCoreBlocks( { enableFSEBlocks: true, diff --git a/packages/widgets/src/index.js b/packages/widgets/src/index.js index e55b16ff12b35d..9520943bcae873 100644 --- a/packages/widgets/src/index.js +++ b/packages/widgets/src/index.js @@ -37,10 +37,21 @@ export function registerLegacyWidgetBlock( supports = {} ) { /** * Registers the Widget Group block. + * + * @param {Object} supports Block support settings. */ -export function registerWidgetGroupBlock() { +export function registerWidgetGroupBlock( supports = {} ) { const { metadata, settings, name } = widgetGroup; - registerBlockType( { name, ...metadata }, settings ); + registerBlockType( + { name, ...metadata }, + { + ...settings, + supports: { + ...settings.supports, + ...supports, + }, + } + ); } export { default as registerLegacyWidgetVariations } from './register-legacy-widget-variations';