Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FSE: Compute the block state of different entities separately (#21368)
** Add Controlled Inner Blocks State ** Allows us to tell if a certain block is controlling its own InnerBlocks. This is helpful for entities like template parts which persist their blocks outside of the root block-editor onChange method. Without this state, it would be hard to tell which blocks belong to which entity. With this state, we can easily traverse up the block hierarchy to find the closest parent block which is an inner block controller. Practically, we can use this to make sure that the dirty state between different entities is consistent. This commit also updates the tests which refer to the block state so that they all contain the new state slice in the before state. Otherwise, some of those tests were failing some some of the before state did not exist. ** Add useBlockSync hook to sync block-editor changes ** The useBlockSync hook syncs a component't block-edior changes with an onChange or onInput handler. The onChange handler is used for persistent changes, and onInput is used for other changes. All changes are scoped to the entity provided: e.g. w.r.t. a root clientId. No changes are included which are part of other entities. For example, a wp_template containing a wp_template_part will not be notified of changes within that template part, but only to changes in the template itself. In other words, it ignores changes which happen in nested inner block controllers. Previously, very similar logic was used for BlockEditorProvider, but it proved necessary to extract so that it could be integrated into InnerBlocks later on. At the same time, we have refactored BlockEditorProvider into a functional component with hooks to save space and to remove needless higher order components. ** Refactor Inner Blocks to use new blockSync hook ** This changes InnerBlocks into a functional component. Practically, this should work exactly the same as before. This allows us to more easily use the useBlockSync hook in order to set up inner block controllers (i.e. with template parts). We now specify a ControlledInnerBlocks component which handles block sync instead of having that logic within InnerBlocks itself. It also allows us to reuse the same logic as the root BlockEditorProvider, so that we don't miss any of the logic and race condition fixes that already exist there. I did try adding similar logic to the old InnerBlocks component with what existed, but it proved very prone to breakage and was hard to make compatible with the root entity controller. It is much more straightforward to keep the logic in the same place! We also refactored the react native file for inner blocks, and added forwardedRef and block context. ** Integrate reducers with controlled inner blocks state ** - Correctly include and exclude clientIDs from block reset depending on whether they are part of an inner block controller or not. - Also handle inner block controllers themselves, not updating their cache or order when the action occurs - Stop invalidating grandparent controller cache - Fix undefined index access in selector state - Handle replaceInnerBlocks action similar to the reset blocks action so that we do not inadvertently delete a template part from the editor. There were a lot of bugs around RESET_BLOCKS and REPLACE_INNER_BLOCKS actions as relating to controlled inner blocks. This is because those actions tend to delete all blocks from the editor without providing back all of the blocks to reinsert. This is because the entity which dispatches the action does not have access to the inner blocks of other entities, so they are not dispatched in the action. These changes update the reducers to make sure that nested inner block controllers are not deleted when they should stay in the editor. Additionally, there are some fixes for the cache state so that it does not invalidate when the changes affect a different entity. ** Wait for inserted blocks to show up in e2e test helper ** ** Add e2e tests for multi-entity dirty state ** ** Add unit tests for use block sync hook **
- Loading branch information