From 737de6326a300423d80bef66dc6d78dff268079d Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Wed, 8 May 2024 18:55:31 +0900 Subject: [PATCH 1/2] Revert "useBlockSync: just testing without isControlled effect (#61114)" This reverts commit dcecf338e956ac203f0da1cbc519a4fae8a68e43. --- .../src/components/provider/use-block-sync.js | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/provider/use-block-sync.js b/packages/block-editor/src/components/provider/use-block-sync.js index 57e53979142d66..300c108a70cf1a 100644 --- a/packages/block-editor/src/components/provider/use-block-sync.js +++ b/packages/block-editor/src/components/provider/use-block-sync.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { useEffect, useRef } from '@wordpress/element'; -import { useRegistry } from '@wordpress/data'; +import { useRegistry, useSelect } from '@wordpress/data'; import { cloneBlock } from '@wordpress/blocks'; /** @@ -82,6 +82,15 @@ export default function useBlockSync( { } = registry.dispatch( blockEditorStore ); const { getBlockName, getBlocks, getSelectionStart, getSelectionEnd } = registry.select( blockEditorStore ); + const isControlled = useSelect( + ( select ) => { + return ( + ! clientId || + select( blockEditorStore ).areInnerBlocksControlled( clientId ) + ); + }, + [ clientId ] + ); const pendingChanges = useRef( { incoming: null, outgoing: [] } ); const subscribed = useRef( false ); @@ -177,6 +186,23 @@ export default function useBlockSync( { } }, [ controlledBlocks, clientId ] ); + const isMounted = useRef( false ); + + useEffect( () => { + // On mount, controlled blocks are already set in the effect above. + if ( ! isMounted.current ) { + isMounted.current = true; + return; + } + + // When the block becomes uncontrolled, it means its inner state has been reset + // we need to take the blocks again from the external value property. + if ( ! isControlled ) { + pendingChanges.current.outgoing = []; + setControlledBlocks(); + } + }, [ isControlled ] ); + useEffect( () => { const { getSelectedBlocksInitialCaretPosition, From a3e9454ad83274d511aa8f92cab2df087518d9b8 Mon Sep 17 00:00:00 2001 From: Ella Date: Wed, 8 May 2024 19:33:12 +0900 Subject: [PATCH 2/2] Add e2e test --- test/e2e/specs/site-editor/undo.spec.js | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/e2e/specs/site-editor/undo.spec.js diff --git a/test/e2e/specs/site-editor/undo.spec.js b/test/e2e/specs/site-editor/undo.spec.js new file mode 100644 index 00000000000000..17c4e4ada6e61b --- /dev/null +++ b/test/e2e/specs/site-editor/undo.spec.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'undo', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activateTheme( 'emptytheme' ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.activateTheme( 'twentytwentyone' ); + } ); + + test( 'does not empty header', async ( { admin, page, editor } ) => { + await admin.visitSiteEditor( { canvas: 'edit' } ); + + // Check if there's a valid child block with a type (not appender). + await expect( + editor.canvas.locator( + '[data-type="core/template-part"] [data-type]' + ) + ).not.toHaveCount( 0 ); + + // insert a block + await editor.insertBlock( { name: 'core/paragraph' } ); + + // undo + await page + .getByRole( 'button', { + name: 'Undo', + } ) + .click(); + + // Check if there's a valid child block with a type (not appender). + await expect( + editor.canvas.locator( + '[data-type="core/template-part"] [data-type]' + ) + ).not.toHaveCount( 0 ); + } ); +} );