RTC: Inject content function from remote changes to fix save button state#76848
Conversation
…itly execute on a non-undo transaction
|
Warning: Type of PR label mismatch To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.
Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task. |
|
Warning: Type of PR label mismatch To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.
Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task. |
|
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. |
5661d30 to
d0ec2a8
Compare
7a64545
into
fix/save-button-visibility
|
This PR does not target trunk, so the |
* Correctly sync the content changes, even if its a function * Ensure the function is checked and add tests * Fix the type issue in the test * Switch to a timeout value and add the necessary tests * Add a new comment explaining this * RTC: Inject content function from remote changes to fix save button state (#76848) * Return deferrer operations from applyPostChangesToCRDTDoc() to explicitly execute on a non-undo transaction * Don't compute content changes, instead locally inject a content function when blocks change to match dirty state * Fix WPBlock type --------- Co-authored-by: ingeniumed <ingeniumed@git.wordpress.org> Co-authored-by: alecgeatches <alecgeatches@git.wordpress.org> Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
What?
Fixes the save button not consistently appearing for RTC collaborators when another user edits blocks. Replaces the content serialization approach in #76796 with a lazy content function injection on the receiving side.
Why?
When blocks change in the editor, Gutenberg passes
contentas a function rather than a string inuseEntityBlockEditor(). This is an optimization that defers the block serialization until it's actually needed on save. In RTC, this means thecontentvalue in the CRDT doc is often stale because these lazy functions aren't serialized and synced. Sinceblocksis a transient edit, block changes alone don't trigger the save button for collaborators.The original fix (PR #76796) solved this by eagerly evaluating the content function and syncing the result via
setTimeout(0). However, this has some performance costs that we'd like to avoid if possible.How?
Instead of eagerly recomputing content on the sending side, the fix works on the receiving side. When
getPostChangesFromCRDTDoc()detects that blocks have changed from a remote peer but content hasn't, it injects a lazy content function into the returned changes:This uses the exact same deferred serialization pattern that Gutenberg uses for local
contentchanges. The function-valued content edit makes the entity dirty (so the save button appears), but the serialization itself is deferred until save or code editor view. This defers serialization cost forcontentas the editor currently does.Testing Instructions
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Used for: Understanding the lazy save pattern and implementing changes