Skip to content

Commit

Permalink
Block bindings: Refactor passing select and dispatch instead of full …
Browse files Browse the repository at this point in the history
…Registry. (WordPress#65710)

* Try use select and dispatch instead of registry

* Pass `select` to `canUserEditValue`

* Pass `select` to `getFieldsList`

* Fix `setValues`

---------

Co-authored-by: cbravobernal <[email protected]>
Co-authored-by: SantosGuillamot <[email protected]>
  • Loading branch information
3 people authored and huubl committed Oct 2, 2024
1 parent 6772238 commit 4e532d0
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 151 deletions.
13 changes: 3 additions & 10 deletions packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export function RichTextWrapper(

const _disableBoundBlock =
! blockBindingsSource?.canUserEditValue?.( {
registry,
select,
context: blockBindingsContext,
args: relatedBinding.args,
} );
Expand All @@ -206,7 +206,7 @@ export function RichTextWrapper(
const { getBlockAttributes } = select( blockEditorStore );
const blockAttributes = getBlockAttributes( clientId );
const fieldsList = blockBindingsSource?.getFieldsList?.( {
registry,
select,
context: blockBindingsContext,
} );
const bindingKey =
Expand Down Expand Up @@ -235,14 +235,7 @@ export function RichTextWrapper(
bindingsLabel: _bindingsLabel,
};
},
[
blockBindings,
identifier,
blockName,
blockContext,
registry,
adjustedValue,
]
[ blockBindings, identifier, blockName, blockContext, adjustedValue ]
);

const shouldDisableEditing = readOnly || disableBoundBlock;
Expand Down
9 changes: 4 additions & 5 deletions packages/block-editor/src/hooks/block-bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
__experimentalVStack as VStack,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { useRegistry, useSelect } from '@wordpress/data';
import { useSelect } from '@wordpress/data';
import { useContext, Fragment } from '@wordpress/element';
import { useViewportMatch } from '@wordpress/compose';

Expand Down Expand Up @@ -186,15 +186,14 @@ function EditableBlockBindingsPanelItems( {
}

export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
const registry = useRegistry();
const blockContext = useContext( BlockContext );
const { removeAllBlockBindings } = useBlockBindingsUtils();
const bindableAttributes = getBindableAttributes( blockName );
const dropdownMenuProps = useToolsPanelDropdownMenuProps();

// `useSelect` is used purposely here to ensure `getFieldsList`
// is updated whenever there are updates in block context.
// `source.getFieldsList` may also call a selector via `registry.select`.
// `source.getFieldsList` may also call a selector via `select`.
const _fieldsList = {};
const { fieldsList, canUpdateBlockBindings } = useSelect(
( select ) => {
Expand All @@ -214,7 +213,7 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
}
}
const sourceList = getFieldsList( {
registry,
select,
context,
} );
// Only add source if the list is not empty.
Expand All @@ -234,7 +233,7 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
.canUpdateBlockBindings,
};
},
[ blockContext, bindableAttributes, registry ]
[ blockContext, bindableAttributes ]
);
// Return early if there are no bindable attributes.
if ( ! bindableAttributes || bindableAttributes.length === 0 ) {
Expand Down
129 changes: 66 additions & 63 deletions packages/block-editor/src/hooks/use-bindings-attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,79 +118,81 @@ export const withBlockBindingSupport = createHigherOrderComponent(
// there are attribute updates.
// `source.getValues` may also call a selector via `registry.select`.
const updatedContext = {};
const boundAttributes = useSelect( () => {
if ( ! blockBindings ) {
return;
}
const boundAttributes = useSelect(
( select ) => {
if ( ! blockBindings ) {
return;
}

const attributes = {};
const attributes = {};

const blockBindingsBySource = new Map();
const blockBindingsBySource = new Map();

for ( const [ attributeName, binding ] of Object.entries(
blockBindings
) ) {
const { source: sourceName, args: sourceArgs } = binding;
const source = sources[ sourceName ];
if ( ! source || ! canBindAttribute( name, attributeName ) ) {
continue;
}
for ( const [ attributeName, binding ] of Object.entries(
blockBindings
) ) {
const { source: sourceName, args: sourceArgs } = binding;
const source = sources[ sourceName ];
if (
! source ||
! canBindAttribute( name, attributeName )
) {
continue;
}

// Populate context.
for ( const key of source.usesContext || [] ) {
updatedContext[ key ] = blockContext[ key ];
}
// Populate context.
for ( const key of source.usesContext || [] ) {
updatedContext[ key ] = blockContext[ key ];
}

blockBindingsBySource.set( source, {
...blockBindingsBySource.get( source ),
[ attributeName ]: {
args: sourceArgs,
},
} );
}
blockBindingsBySource.set( source, {
...blockBindingsBySource.get( source ),
[ attributeName ]: {
args: sourceArgs,
},
} );
}

if ( blockBindingsBySource.size ) {
for ( const [ source, bindings ] of blockBindingsBySource ) {
// Get values in batch if the source supports it.
let values = {};
if ( ! source.getValues ) {
Object.keys( bindings ).forEach( ( attr ) => {
// Default to the the source label when `getValues` doesn't exist.
values[ attr ] = source.label;
} );
} else {
values = source.getValues( {
registry,
context: updatedContext,
clientId,
bindings,
} );
}
for ( const [ attributeName, value ] of Object.entries(
values
) ) {
if (
attributeName === 'url' &&
( ! value || ! isURLLike( value ) )
) {
// Return null if value is not a valid URL.
attributes[ attributeName ] = null;
if ( blockBindingsBySource.size ) {
for ( const [
source,
bindings,
] of blockBindingsBySource ) {
// Get values in batch if the source supports it.
let values = {};
if ( ! source.getValues ) {
Object.keys( bindings ).forEach( ( attr ) => {
// Default to the the source label when `getValues` doesn't exist.
values[ attr ] = source.label;
} );
} else {
attributes[ attributeName ] = value;
values = source.getValues( {
select,
context: updatedContext,
clientId,
bindings,
} );
}
for ( const [ attributeName, value ] of Object.entries(
values
) ) {
if (
attributeName === 'url' &&
( ! value || ! isURLLike( value ) )
) {
// Return null if value is not a valid URL.
attributes[ attributeName ] = null;
} else {
attributes[ attributeName ] = value;
}
}
}
}
}

return attributes;
}, [
blockBindings,
name,
clientId,
updatedContext,
registry,
sources,
] );
return attributes;
},
[ blockBindings, name, clientId, updatedContext, sources ]
);

const hasParentPattern = !! updatedContext[ 'pattern/overrides' ];
const hasPatternOverridesDefaultBinding =
Expand Down Expand Up @@ -240,7 +242,8 @@ export const withBlockBindingSupport = createHigherOrderComponent(
bindings,
] of blockBindingsBySource ) {
source.setValues( {
registry,
select: registry.select,
dispatch: registry.dispatch,
context: updatedContext,
clientId,
bindings,
Expand Down
5 changes: 2 additions & 3 deletions packages/block-library/src/button/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
store as blocksStore,
} from '@wordpress/blocks';
import { useMergeRefs, useRefEffect } from '@wordpress/compose';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { useSelect, useDispatch } from '@wordpress/data';

const LINK_SETTINGS = [
...LinkControl.DEFAULT_LINK_SETTINGS,
Expand Down Expand Up @@ -190,7 +190,6 @@ function ButtonEdit( props ) {
const colorProps = useColorProps( attributes );
const spacingProps = useSpacingProps( attributes );
const shadowProps = useShadowProps( attributes );
const registry = useRegistry();
const ref = useRef();
const richTextRef = useRef();
const blockProps = useBlockProps( {
Expand Down Expand Up @@ -249,7 +248,7 @@ function ButtonEdit( props ) {
lockUrlControls:
!! metadata?.bindings?.url &&
! blockBindingsSource?.canUserEditValue?.( {
registry,
select,
context,
args: metadata?.bindings?.url?.args,
} ),
Expand Down
5 changes: 2 additions & 3 deletions packages/block-library/src/image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import clsx from 'clsx';
import { isBlobURL, createBlobURL } from '@wordpress/blob';
import { store as blocksStore, createBlock } from '@wordpress/blocks';
import { Placeholder } from '@wordpress/components';
import { useDispatch, useSelect, useRegistry } from '@wordpress/data';
import { useDispatch, useSelect } from '@wordpress/data';
import {
BlockIcon,
useBlockProps,
Expand Down Expand Up @@ -113,7 +113,6 @@ export function ImageEdit( {

const [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );

const registry = useRegistry();
const containerRef = useRef();
// Only observe the max width from the parent container when the parent layout is not flex nor grid.
// This won't work for them because the container width changes with the image.
Expand Down Expand Up @@ -381,7 +380,7 @@ export function ImageEdit( {
lockUrlControls:
!! metadata?.bindings?.url &&
! blockBindingsSource?.canUserEditValue?.( {
registry,
select,
context,
args: metadata?.bindings?.url?.args,
} ),
Expand Down
9 changes: 4 additions & 5 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
Placeholder,
} from '@wordpress/components';
import { useViewportMatch } from '@wordpress/compose';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { useSelect, useDispatch } from '@wordpress/data';
import {
BlockControls,
InspectorControls,
Expand Down Expand Up @@ -134,7 +134,6 @@ export default function Image( {
const numericWidth = width ? parseInt( width, 10 ) : undefined;
const numericHeight = height ? parseInt( height, 10 ) : undefined;

const registry = useRegistry();
const imageRef = useRef();
const { allowResize = true } = context;
const { getBlock, getSettings } = useSelect( blockEditorStore );
Expand Down Expand Up @@ -497,7 +496,7 @@ export default function Image( {
lockUrlControls:
!! urlBinding &&
! urlBindingSource?.canUserEditValue?.( {
registry,
select,
context,
args: urlBinding?.args,
} ),
Expand All @@ -512,7 +511,7 @@ export default function Image( {
lockAltControls:
!! altBinding &&
! altBindingSource?.canUserEditValue?.( {
registry,
select,
context,
args: altBinding?.args,
} ),
Expand All @@ -526,7 +525,7 @@ export default function Image( {
lockTitleControls:
!! titleBinding &&
! titleBindingSource?.canUserEditValue?.( {
registry,
select,
context,
args: titleBinding?.args,
} ),
Expand Down
4 changes: 2 additions & 2 deletions packages/e2e-tests/plugins/block-bindings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const getValues = ( { bindings } ) => {
}
return newValues;
};
const setValues = ( { registry, bindings } ) => {
const setValues = ( { dispatch, bindings } ) => {
Object.values( bindings ).forEach( ( { args, newValue } ) => {
// Example of what could be done.
registry.dispatch( 'core' ).editEntityRecord( 'postType', 'post', 1, {
dispatch( 'core' ).editEntityRecord( 'postType', 'post', 1, {
meta: { [ args?.key ]: newValue },
} );
} );
Expand Down
Loading

0 comments on commit 4e532d0

Please sign in to comment.