-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove select() hack from getBlockEditingMode() #51359
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,8 @@ import createSelector from 'rememo'; | |
/** | ||
* WordPress dependencies | ||
*/ | ||
import { select } from '@wordpress/data'; | ||
import { store as blocksStore } from '@wordpress/blocks'; | ||
import { createRegistrySelector } from '@wordpress/data'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -72,40 +72,35 @@ export function getLastInsertedBlocksClientIds( state ) { | |
* @return {BlockEditingMode} The block editing mode. One of `'disabled'`, | ||
* `'contentOnly'`, or `'default'`. | ||
*/ | ||
export const getBlockEditingMode = createSelector( | ||
( state, clientId = '' ) => { | ||
if ( state.blockEditingModes.has( clientId ) ) { | ||
return state.blockEditingModes.get( clientId ); | ||
} | ||
if ( ! clientId ) { | ||
return 'default'; | ||
} | ||
const rootClientId = getBlockRootClientId( state, clientId ); | ||
const templateLock = getTemplateLock( state, rootClientId ); | ||
if ( templateLock === 'contentOnly' ) { | ||
const name = getBlockName( state, clientId ); | ||
// TODO: Terrible hack! We're calling the global select() function | ||
// here instead of using createRegistrySelector(). The problem with | ||
// using createRegistrySelector() is that then the public | ||
// block-editor selectors (e.g. canInsertBlockTypeUnmemoized) can't | ||
// call this private block-editor selector due to a bug in | ||
// @wordpress/data. See | ||
// https://github.com/WordPress/gutenberg/pull/50985. | ||
const isContent = | ||
select( blocksStore ).__experimentalHasContentRoleAttribute( | ||
name | ||
); | ||
return isContent ? 'contentOnly' : 'disabled'; | ||
} | ||
const parentMode = getBlockEditingMode( state, rootClientId ); | ||
return parentMode === 'contentOnly' ? 'default' : parentMode; | ||
}, | ||
( state ) => [ | ||
state.blockEditingModes, | ||
state.blocks.parents, | ||
state.settings.templateLock, | ||
state.blockListSettings, | ||
] | ||
export const getBlockEditingMode = createRegistrySelector( ( select ) => | ||
createSelector( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This memoization won't work because
createRegistrySelector = ( selectorFactory ) => ( ...args ) => selectorFactory( registry.select )( ...args ); I don't know how to solve this, maybe we'll need to patch |
||
( state, clientId = '' ) => { | ||
if ( state.blockEditingModes.has( clientId ) ) { | ||
return state.blockEditingModes.get( clientId ); | ||
} | ||
if ( ! clientId ) { | ||
return 'default'; | ||
} | ||
const rootClientId = getBlockRootClientId( state, clientId ); | ||
const templateLock = getTemplateLock( state, rootClientId ); | ||
if ( templateLock === 'contentOnly' ) { | ||
const name = getBlockName( state, clientId ); | ||
const isContent = | ||
select( blocksStore ).__experimentalHasContentRoleAttribute( | ||
name | ||
); | ||
return isContent ? 'contentOnly' : 'disabled'; | ||
} | ||
const parentMode = getBlockEditingMode( state, rootClientId ); | ||
return parentMode === 'contentOnly' ? 'default' : parentMode; | ||
}, | ||
( state ) => [ | ||
state.blockEditingModes, | ||
state.blocks.parents, | ||
state.settings.templateLock, | ||
state.blockListSettings, | ||
] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if memoizing this selector is even a good idea. This particular implementation won't catch changes in The selector doesn't do any very complex calculation, and the return value is a string, which doesn't need an unique identity. Let's just remove the |
||
) | ||
); | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to keep the legacy
registerStore
here. Otherwise thepersist
plugin won't be active. It works by overriding theregisterStore
method of theregistry
and reading thepersist
option. If you callregister
, the plugin won't catch it.This will be solved once we finish migration of the
block-editor
store to thepreferences
package. It's being worked on in #39632.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, bummer, I see.
I don't think we can remove this workaround yet then because if we do this:
Then the private selectors are not callable from public selectors as they are not bound to the store that's created by
registerStore
.(When I try it I get a
Uncaught TypeError: selector.registry is undefined
error on load.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we will wait until #39632 is merged!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did start looking at #39632 one again. I've rebased it and hope to push some further options this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, there are two gotchas at work here:
store
object is a noop, because the store is not instantiated from that object! It's just a store descriptor object that's exported so that users can pass it to functions likeselect( store )
ordispatch( store )
. The descriptor has an.instantiate
method, but it's never called. TheregisterStore
function creates a second store descriptor fromSTORE_NAME
andstoreConfig
, and uses that internal one to actually instantiate the store. But that descriptor doesn't have any private selectors registered.createReduxStore
and before the.instantiate
function is called, butregisterStore
calls them both within one statement:gutenberg/packages/data/src/registry.js
Line 310 in 4d0f303