Skip to content

Commit

Permalink
Widgets: Temporary fix for saving widgets (#28078)
Browse files Browse the repository at this point in the history
* Widgets: Temporary fix for saving widgets

Fixes two issues with saving widgets on the widgets screen:

1. Unable to save a new widget. What's happening here is that
   `saveEntityRecord()` passes execution back to `saveWidgetArea()`
   before it has a chance to call `addToBatch`. This means that nothing
   is in the batch processing queue when `processBatch()` is called. The
   temporary fix is to wait for a promise before calling
   `processBatch()`. This allows execution in `saveEntityRecord()` to
   resume.

2. Unable to save existing widgets. What's happening here is that the
   client IDs are changed by `useBlockSync()`. This breaks the internal
   mapping that the widget editor maintains of widget IDs <-> block
   client IDs. The temporary fix is to have the widgets editor pass a
   prop to `useBlockSync()` that disables cloning blocks.

* Fix typo in comment
  • Loading branch information
noisysocks authored Jan 11, 2021
1 parent f27e8bd commit da6d7ae
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 3 deletions.
12 changes: 9 additions & 3 deletions packages/block-editor/src/components/provider/use-block-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ import { cloneBlock } from '@wordpress/blocks';
* change has been made in the block-editor blocks
* for the given clientId. When this is called,
* controlling sources do not become dirty.
* @param {boolean} props.__unstableCloneValue Whether or not to clone each of
* the blocks provided in the value prop.
*/
export default function useBlockSync( {
clientId = null,
Expand All @@ -71,6 +73,7 @@ export default function useBlockSync( {
selectionEnd: controlledSelectionEnd,
onChange = noop,
onInput = noop,
__unstableCloneValue = true,
} ) {
const registry = useRegistry();

Expand Down Expand Up @@ -98,9 +101,12 @@ export default function useBlockSync( {
if ( clientId ) {
setHasControlledInnerBlocks( clientId, true );
__unstableMarkNextChangeAsNotPersistent();
const storeBlocks = controlledBlocks.map( ( block ) =>
cloneBlock( block )
);
let storeBlocks = controlledBlocks;
if ( __unstableCloneValue ) {
storeBlocks = controlledBlocks.map( ( block ) =>
cloneBlock( block )
);
}
if ( subscribed.current ) {
pendingChanges.current.incoming = storeBlocks;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export default function WidgetAreaInnerBlocks() {
onChange={ onChange }
templateLock={ false }
renderAppender={ InnerBlocks.DefaultBlockAppender }
// HACK: The widget editor relies on a mapping of block client IDs
// to widget IDs. We therefore instruct `useBlockSync` to not clone
// the blocks it receives which would change the block client IDs`.
// See https://github.com/WordPress/gutenberg/issues/27173.
__unstableCloneValue={ false }
/>
);
}
9 changes: 9 additions & 0 deletions packages/edit-widgets/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ export function* saveWidgetArea( widgetAreaId ) {
} );
}

// HACK: Await any promise here so that rungen passes execution back to
// `saveEntityRecord` above. This prevents `processBatch` from being called
// here before `addToBatch` is called by `saveEntityRecord`.
// See https://github.com/WordPress/gutenberg/issues/27173.
yield {
type: 'AWAIT_PROMISE',
promise: Promise.resolve(),
};

const batch = yield dispatch(
'core/__experimental-batch-processing',
'processBatch',
Expand Down
2 changes: 2 additions & 0 deletions packages/edit-widgets/src/store/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ export function dispatch( registryName, actionName, ...args ) {
}

const controls = {
AWAIT_PROMISE: ( { promise } ) => promise,

SELECT: createRegistryControl(
( registry ) => ( { registryName, selectorName, args } ) => {
return registry.select( registryName )[ selectorName ]( ...args );
Expand Down

0 comments on commit da6d7ae

Please sign in to comment.