Skip to content

Commit a08268b

Browse files
priethorMamadukaannezazu
authored andcommitted
Visual revisions: Make the autosave notice work with the visual revisions UI (#79947)
Co-authored-by: priethor <priethor@git.wordpress.org> Co-authored-by: Mamaduka <mamaduka@git.wordpress.org> Co-authored-by: annezazu <annezazu@git.wordpress.org>
1 parent 4874ec3 commit a08268b

4 files changed

Lines changed: 100 additions & 1 deletion

File tree

‎packages/editor/CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- Add an "Attachments" source to the block inserter's Media tab, listing images attached to the current post with the ability to attach and detach them ([#79336](https://github.com/WordPress/gutenberg/pull/79336)).
88

9+
### Enhancements
10+
11+
- The "View the autosave" notice now opens the autosave in the visual revisions view with its changes highlighted, instead of the classic revisions screen. It falls back to the classic screen when visual revisions are disabled ([#79947](https://github.com/WordPress/gutenberg/pull/79947)).
12+
913
### Bug Fixes
1014

1115
- External images are now sideloaded on the server when uploaded to the media library, via a new `mediaSideloadFromUrl` block editor setting, so the upload works when the editor is cross-origin isolated (e.g. with client-side media processing enabled) ([#79409](https://github.com/WordPress/gutenberg/pull/79409)).

‎packages/editor/src/components/provider/index.js‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import { store as noticesStore } from '@wordpress/notices';
2323
import { privateApis as editPatternsPrivateApis } from '@wordpress/patterns';
2424
import { createBlock } from '@wordpress/blocks';
25+
import { getQueryArg } from '@wordpress/url';
2526

2627
/**
2728
* Internal dependencies
@@ -309,6 +310,7 @@ export const ExperimentalEditorProvider = withRegistryProvider(
309310
setCurrentTemplateId,
310311
setEditedPost,
311312
setRenderingMode,
313+
setCurrentRevisionId,
312314
} = unlock( useDispatch( editorStore ) );
313315
const { editEntityRecord } = useDispatch( coreStore );
314316
const registry = useRegistry();
@@ -344,6 +346,11 @@ export const ExperimentalEditorProvider = withRegistryProvider(
344346
setupEditor( post, initialEdits, settings.template );
345347
}
346348
if ( settings.autosave ) {
349+
// The only place core exposes the autosave ID is the edit
350+
// link, always `revision.php?revision=<autosave ID>`.
351+
const autosaveId = Number(
352+
getQueryArg( settings.autosave.editLink, 'revision' )
353+
);
347354
createWarningNotice(
348355
__(
349356
'There is an autosave of this post that is more recent than the version below.'
@@ -353,7 +360,28 @@ export const ExperimentalEditorProvider = withRegistryProvider(
353360
actions: [
354361
{
355362
label: __( 'View the autosave' ),
356-
url: settings.autosave.editLink,
363+
...( autosaveId
364+
? {
365+
onClick: () => {
366+
// `disableVisualRevisions`
367+
// is only set after mount,
368+
// so read it at click time.
369+
const {
370+
disableVisualRevisions,
371+
} = registry
372+
.select( editorStore )
373+
.getEditorSettings();
374+
if ( disableVisualRevisions ) {
375+
window.location.href =
376+
settings.autosave.editLink;
377+
return;
378+
}
379+
setCurrentRevisionId(
380+
autosaveId
381+
);
382+
},
383+
}
384+
: { url: settings.autosave.editLink } ),
357385
},
358386
],
359387
}

‎packages/editor/src/store/private-actions.js‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,13 @@ export const restoreRevision =
746746

747747
// Save the post to persist the restored revision.
748748
await dispatch.savePost();
749+
if ( select.didPostSaveRequestFail() ) {
750+
return;
751+
}
752+
753+
// The saved post is now newer than any autosave, so the
754+
// autosave notice is stale.
755+
registry.dispatch( noticesStore ).removeNotice( 'autosave-exists' );
749756

750757
// Show success notice.
751758
registry.dispatch( noticesStore ).createSuccessNotice(

‎test/e2e/specs/editor/various/autosave.spec.js‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,66 @@ test.describe( 'Autosave', () => {
336336
);
337337
} );
338338

339+
test( 'opens the visual revisions view from the autosave notice', async ( {
340+
editor,
341+
page,
342+
} ) => {
343+
await editor.canvas
344+
.getByRole( 'button', { name: 'Add default block' } )
345+
.click();
346+
await page.keyboard.type( 'before save' );
347+
await editor.publishPost();
348+
349+
const paragraph = editor.canvas.getByRole( 'document', {
350+
name: 'Block: Paragraph',
351+
} );
352+
await paragraph.click();
353+
// Type slowly so the autosave happens more than 1s after publish.
354+
await page.keyboard.type( ' after save', { delay: 100 } );
355+
356+
// Trigger a server-side autosave newer than the saved version.
357+
await page.evaluate( () =>
358+
window.wp.data.dispatch( 'core/editor' ).autosave()
359+
);
360+
361+
await expect
362+
.poll( async () => {
363+
return await page.evaluate( () => {
364+
const postId = window.wp.data
365+
.select( 'core/editor' )
366+
.getCurrentPostId();
367+
const autosaves = window.wp.data
368+
.select( 'core' )
369+
.getAutosaves( 'post', postId );
370+
371+
return autosaves?.length ?? 0;
372+
} );
373+
} )
374+
.toBeGreaterThanOrEqual( 1 );
375+
376+
// Reload so the autosave notice appears.
377+
await page.reload();
378+
await page.waitForFunction( () => window?.wp?.data );
379+
380+
const autosaveNotice = page
381+
.locator( '.components-notice__content' )
382+
.filter( {
383+
hasText:
384+
'There is an autosave of this post that is more recent than the version below.',
385+
} );
386+
await expect( autosaveNotice ).toBeVisible();
387+
388+
// Opening the autosave switches to the visual revisions view in place.
389+
await page.getByRole( 'button', { name: 'View the autosave' } ).click();
390+
await expect(
391+
page.getByRole( 'button', { name: 'Exit' } )
392+
).toBeVisible();
393+
394+
// Restoring the autosave dismisses the notice.
395+
await page.getByRole( 'button', { name: 'Restore' } ).click();
396+
await expect( autosaveNotice ).toBeHidden();
397+
} );
398+
339399
test.skip( 'should clear sessionStorage upon user logout', async ( {
340400
page,
341401
pageUtils,

0 commit comments

Comments
 (0)