-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Fix Synced Patterns non-overridden content being editable in write mode #66949
Conversation
- Remove the prev. React effect for managing pattern block editing modes - Implement higher order reducer in the block editor store ... it: - Tracks the clientIds of pattern blocks. - Uses the pattern block clientIds to manage block editing modes for pattern blocks and their inner blocks. - Updates both on any actions that change block lists.
Size Change: +297 B (+0.02%) Total Size: 1.82 MB
ℹ️ View Unchanged
|
Flaky tests detected in 4c7653a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/11812251734
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
@@ -3071,6 +3071,10 @@ export const getBlockEditingMode = createRegistrySelector( | |||
return 'disabled'; | |||
} | |||
|
|||
if ( state?.patternBlockEditingModes?.has( clientId ) ) { | |||
return state?.patternBlockEditingModes.get( clientId ); | |||
} |
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.
What I find odd is that the denormalization only applies in the case of the "pattern block editing modes", why not just make a global state.blockEditingModes ?
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 see you mentioned in the description that you have follow-up for "zoom-out" editing modes too. I think we should ideally just have the selector return directly the state value in the end, but I'm ok with going in steps.
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.
One challenge is going to be that the selector depends on editorMode
which is not within the reducer itself. So it's possible that in the end we'll have two values in the state for each block, a block editing mode for "write" and another one for "design" and the selector would pick the right value depending on the active mode.
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.
What I find odd is that the denormalization only applies in the case of the "pattern block editing modes", why not just make a global state.blockEditingModes ?
Yeah, it's a tricky one. In the case of switching from design to write mode, we don't need to recalculate every pattern block, so storing it separately is useful in that case, we can retain the info across editor mode switches.
Similarly, we need to retain back compat for the block editing modes that might be set via setBlockEditingMode
, so I think those also need to be stored in separate state so that we don't accidentally clear them when switching editor modes.
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 yes, I mistakenly used the same name, we do need this to be separate from the original setBlockEditingMode
state.
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.
One challenge is going to be that the selector depends on editorMode which is not within the reducer itself.
My other PR does handle this by dispatching an action for switching editor mode to ensure the reducer re-runs:
https://github.com/WordPress/gutenberg/pull/66919/files#diff-d1fbd3af72ee0220c5c3ab2952a24d818174aed711b9a50b57c9544218a63988R1681
but it still reads the mode from the preferences store:
https://github.com/WordPress/gutenberg/pull/66919/files#diff-3c4b969f7547d02bc04a2c554e0f7d21da07c3f779714acf02800ee0341b50d9R279-R281
I'm not sure if this is the best approach. The reducer also needs access to the blocks
store to check for role: content
attributes, so it's not the only place where it selects from other stores and I saw there was some precedence for this in the block editor reducer.
|
||
return nextState; | ||
}; | ||
}; |
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.
Do you think this is the kind of code that deserves some unit testing?
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 can do, though I think the other PR (#66919) shows that unit testing only the reducer or only the selectors isn't a great approach. That PR is a refactor, the store as a whole should be working the same, but I'll have to rewrite all the tests, which is a lot of work and could introduce some margin of error.
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 should also add some e2e tests.
This is superceded by #67026, which I'd be happy to receive reviews on. I plan to add some more tests to it, but I'm happy enough with the shape of the code. |
What?
Fixes #66424
Alternative to #65408
In Write Mode, parts of synced patterns that are supposed to be non-editable are editable.
Why?
This happens because Write Mode overrides the
blockEditingMode
of a synced pattern's inner blocks.Pattern blocks try calling
setBlockEditingMode
for child blocks directly, but when write mode is active a different value is returned directly from thegetBlockEditingMode
selector, one that doesn't take into account how synced patterns should work.How?
This PR fixes the issue by moving the pattern block editing modes to the block editor store, so that it can work harmoniously with the way Write Mode and Zoom Out mode determine the block editing mode.
Initially #65408 attempted this by adding code directly to the getBlockEditingMode` selector, but this caused a performance issue so it was reverted. That selector is called a lot, so it's sensitive to any new code that might cause some overhead.
This PR follows the suggestion of @youknowriad - #65408 (comment).
A higher order reducer instead calculates the block editing modes whenever there are changes to the block list. This doesn't seem to cause any noticeable performance issues. The approach taken in the higher order reducer is to first track and added/removed pattern blocks (
core/block
block types) and then build up aSet
of editing modes for those blocks and their children.I also have another PR that aims to move the zoomed out/write mode code from the selector to a higher order reducer, which I can follow up on if this approach looks good.
Testing Instructions
Screenshots or screencast
Before
Kapture.2024-11-13.at.17.24.45.mp4
After
Kapture.2024-11-13.at.17.28.44.mp4