Suggest mode 6a: Capture and apply block-remove suggestions (mechanism)#77968
Suggest mode 6a: Capture and apply block-remove suggestions (mechanism)#77968adamsilverstein wants to merge 3 commits intosuggest-mode-6-foundationsfrom
Conversation
In Suggest mode a removeBlock dispatch must not actually remove the
block — the apply-and-tag flow re-inserts the subtree at its previous
position and stamps a metadata.suggestion = { type: 'pending-remove' }
marker on the re-inserted top-level block. Auto-save (in a follow-up)
reads the marker and persists it as a block-remove operation; Apply
later runs the real removeBlock, Reject just clears the marker.
The interceptor maintains a per-tick tree snapshot so the previous
position (parent + index) and full subtree are recoverable after the
block has already been dropped from the live tree. Re-insertion is
limited to top-level removed blocks — descendants of another removed
block ride along with their parent, and re-inserting them separately
would duplicate them.
`metadata.suggestion` is added to SYSTEM_METADATA_KEYS so subsequent
fires fold the marker into the snapshot rather than reverting it,
and so it never leaks into the user-pending overlay.
Refs #77434.
Wires the pending-remove marker through to the existing auto-save and apply/reject paths so a removal in Suggest mode produces a real note comment that the post author can Apply or Reject. - overlay-context: adds a SET_STRUCTURAL_OP reducer action and a setStructuralOp helper. Structural ops live alongside attribute-set diffs in the overlay entry; the interceptor calls setStructuralOp immediately after tagging the live block. - auto-save: operationsForEntry merges any structural op with the existing attribute-set diff before fingerprinting. The structural op leads so a Reject reverts to the pre-suggestion shape. - provider: applySuggestion branches on findStructuralOp; for block- remove it clears the marker, drops the overlay, and dispatches removeBlock — three bypass-guarded dispatches so the interceptor doesn't fight the apply. rejectSuggestion accepts an optional clientId/payload and clears the marker for structural rejects so the dimmed/struck visual treatment goes away. - collab-sidebar suggestion-actions: passes clientId + payload to rejectSuggestion so the marker-clear path runs. Refs #77434.
|
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. |
|
Size Change: +632 B (+0.01%) Total Size: 7.92 MB 📦 View Changed
ℹ️ View Unchanged
|
|
Flaky tests detected in 008eb74. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/25406047322
|
…ging When another client accepts a pending-remove suggestion, the marker-clear plus the removeBlock arrive on this client through sync, typically batched into a single block-editor update. The interceptor's removal-detection branch was treating the disappearance as a fresh user delete — re-inserting the block and tagging it pending-remove again, which then bounced back through sync and undid the apply on the accepting client a moment after they clicked. Recognize the apply landing by checking the previous-tick tree snapshot for `metadata.suggestion.type === 'pending-remove'` on the disappearing block. When the marker is still there, drop the snapshot entry and let the removal stand. The PRUNE_ORPHANS effect in overlay-context cleans up the matching overlay entry on the next render.
What
Adds the data-layer mechanism for block-remove suggestions (#77434, task 6a). In Suggest mode a removeBlock dispatch no longer drops the block — the apply-and-tag flow re-inserts the subtree at its previous position and tags it with
metadata.suggestion = { type: 'pending-remove' }. Auto-save persists the marker as ablock-removeoperation; Apply later runs the real removeBlock; Reject just clears the marker.This PR ships the mechanism only — there is no visual treatment yet. Strikethrough/dim styling, summary, and diff variants land in the next PR (#77970).
Two commits
operationsForEntryemits the structural op, provider'sapplySuggestionbranches onfindStructuralOpand dispatchesremoveBlock,rejectSuggestionclears the marker.Testing
Stack
Refs #77434, #73411.