Skip to content

Editor: Make autosave restorations non-destructive - #80504

Open
sidhant-tomar-003 wants to merge 8 commits into
WordPress:trunkfrom
sidhant-tomar-003:feature/autosave-overwrite-fix
Open

sidhant-tomar-003 wants to merge 8 commits into
WordPress:trunkfrom
sidhant-tomar-003:feature/autosave-overwrite-fix

Conversation

@sidhant-tomar-003

@sidhant-tomar-003 sidhant-tomar-003 commented Jul 21, 2026 •

Copy link
Copy Markdown

What?

Closes #79777

Makes restoring both local (not remote autosaves) a non-destructive action. Users can now restore an autosave inline, view the changes in the editor, and undo them if needed, all before making a hard save to the server.

Why?

Previously, restoring an autosave was a destructive action. For local autosaves, it would replace the editor content silently with no way to undo. This caused users to accidentally lose active work.

How?

  • Local Autosaves: Updated LocalAutosaveMonitor to group edits in a registry.batch() and trigger a success snackbar with an Undo button (coreStore.undo()).
  • Revisions UI: Removed the forced await dispatch.savePost() call from restoreRevision in private-actions.js, allowing users to preview applied revisions before manually hitting "Update".
  • Tests: Added dedicated E2E tests for the Undo functionality in autosave.spec.js.

Testing Instructions

Testing Local Autosave Restore:

  1. Open a new post and type "Version A".
  2. Wait for the draft to save (or save it manually).
  3. Type "Version B". Wait a few seconds for the local browser autosave to trigger (or run wp.data.dispatch( 'core/editor' ).autosave( { local: true } ) in the console).
  4. Refresh the page without saving.
  5. You should see a notice saying "The backup of this post in your browser is different...".
  6. Click "Restore the backup". The content should change to "Version B".
  7. A snackbar will appear. Click "Undo" in the snackbar, and verify the text reverts to "Version A".

Testing Instructions for Keyboard

  1. Follow the same setup steps above.
  2. When the autosave notice appears, use Tab to navigate to the "Restore..." button and press Enter.
  3. Use Tab to navigate to the "Undo" button inside the resulting snackbar and press Enter. Verify the content reverts correctly.

Screenshots or screencast

image

Use of AI Tools

This PR was authored with the assistance of an AI coding agent (Google Antigravity), and manually reviewed and tested by me.

@github-actions github-actions Bot added the [Package] Editor /packages/editor label Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026 •

Copy link
Copy Markdown

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 props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @gracie.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: gracie.

Co-authored-by: sidhant-tomar-003 <sidhanttomar@git.wordpress.org>
Co-authored-by: priethor <priethor@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions Bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Jul 21, 2026
@github-actions

Copy link
Copy Markdown

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @sidhant-tomar-003! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@Mamaduka Mamaduka added [Type] Enhancement A suggestion for improvement. [Feature] History History, undo, redo, revisions, autosave. labels Jul 21, 2026
@Mamaduka

Copy link
Copy Markdown
Member

The remote autosave is treated as a revision (#79947), and it has a less destructive UI for restoration, unless the user chooses to override the content. That's why I don't think changes in packages/editor/src/store/private-actions.js are required.

The batching and undo for local autosaves are a nice touch; this could improve the UX. The e2e test failures are related to changes in this PR.

@Mamaduka
Mamaduka requested review from Mamaduka and priethor July 21, 2026 12:55
…rwrite-fix

# Conflicts:
#	packages/editor/src/store/private-actions.js
@sidhant-tomar-003
sidhant-tomar-003 force-pushed the feature/autosave-overwrite-fix branch from e98d095 to d24a585 Compare July 21, 2026 18:27
@sidhant-tomar-003

Copy link
Copy Markdown
Author

@Mamaduka Hey just pushed changes to remove the remote autosave stuff. Now the only changes remaining are the batching and undo for local autosave 👍

@priethor priethor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple of comments. Small note: the PR description still mentions the remote autosave changes that were removed in the latest update.

resetEditorBlocks( parse( edits.content ) );
removeNotice( id );

registry.batch( () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

editPost and resetEditorBlocks seem to create separate core-data undo entries, even inside the batch, am I understanding it correctly? So if the backup includes changes to both the title and content, I think one click on Undo would only restore the content. If that’s right, could all the restored fields be grouped into a single undo step? It might also be worth covering title in the E2E test.

@sidhant-tomar-003 sidhant-tomar-003 Jul 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clubbed them together into one batch, and also added coverage for this in the E2E test.

Also tested and confirmed that the undo would revert both changes to post body and post title.

Comment on lines +137 to +140
onClick: () => {
registry
.dispatch( coreStore )
.undo();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this calls the global undo() when the button is clicked, could an edit made after the restore be undone by mistake? For example, restore the backup, insert a block, then click Undo in the snackbar.

If so, would it make sense to limit the action to the restore itself, or at least hide it once a newer edit is added to the undo history?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this was indeed an issue. Fixed this by dismissing the snackbar undo button if the user makes any changes to the post. The autosave changes will still be in the Undo queue so the user can still choose to unapply them.

Hope this fix works 👍

This commit addresses reviewer feedback by grouping `editPost` and `resetEditorBlocks` into a single `editPost` call in `local-autosave-monitor/index.js`. This ensures that both the content blocks and the title are grouped in a single core-data undo level, rather than being handled as separate steps. The E2E tests have been updated to cover title restoration as well.
When restoring an autosave, a snackbar with an 'Undo' action appears. Previously, if a user made a new edit while the snackbar was still visible, clicking 'Undo' would incorrectly revert the new edit (since it just fired the global undo action). This automatically dismisses the snackbar as soon as new edits are detected to prevent unintended undo actions. This also fixes an infinite dispatch loop that occurred when dismissing the snackbar.
Comment on lines +135 to +166
const postType = registry
.select( editorStore )
.getCurrentPostType();

const initialEdits = registry
.select( coreStore )
.getEntityRecordNonTransientEdits(
'postType',
postType,
postId
);
const unsubscribe = registry.subscribe( () => {
const currentEdits = registry
.select( coreStore )
.getEntityRecordNonTransientEdits(
'postType',
postType,
postId
);
if ( currentEdits !== initialEdits ) {
// Safely unsubscribe first to prevent loops
unsubscribe();
// Defer dispatch to avoid nested dispatch issues
setTimeout( () => {
registry
.dispatch( noticesStore )
.removeNotice(
'wpEditorAutosaveRestored'
);
}, 0 );
}
} );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really love all this complexity (like usage of registry.subscribe). There should be a simpler way. Maybe we should go back to UX and see if communications can be improved in other ways.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could just leave it as it was, because if a user decided to make some changes within the 10 seconds of the undo button being on the snackbar, they probably weren't planning on using the button to begin with. And the changes do remain in queue for the session so theoretically the changes can still be reverted.

Other than that, I don't really see any way to have the Undo button on the Toast message only undo the autosave changes that would be simpler than this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @sidhant-tomar-003!

I left a more general comment on issue #79777. I think there are other areas we can improve. No action required at the moment, just discussion and decision.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to help if needed regarding this 😄

This reverts the complex registry.subscribe and setTimeout logic introduced in the previous commit. Based on maintainer feedback, the complexity of manually intercepting undo actions and dismissing the snackbar was deemed too high. We are returning to the standard, simple global undo behavior.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] History History, undo, redo, revisions, autosave. First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Package] Editor /packages/editor [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Autosave "Restore" can revert to an older version and lose current content

3 participants