Skip to content

Commit

Permalink
Editor: Avoid scheduling autosave if same edit reference as last comp…
Browse files Browse the repository at this point in the history
…letion
  • Loading branch information
aduth committed Jan 24, 2019
1 parent 9d7846d commit 6a91586
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
25 changes: 23 additions & 2 deletions packages/editor/src/components/autosave-monitor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,33 @@ import { withSelect, withDispatch } from '@wordpress/data';

export class AutosaveMonitor extends Component {
componentDidUpdate( prevProps ) {
const { isDirty, editsReference, isAutosaveable } = this.props;
const { isDirty, editsReference, isAutosaveable, isAutosaving } = this.props;

// The edits reference is held for comparison to avoid scheduling an
// autosave if an edit has not been made since the last autosave
// completion. This is assigned when the autosave completes, and reset
// when an edit occurs.
//
// See: https://github.com/WordPress/gutenberg/issues/12318

if ( editsReference !== prevProps.editsReference ) {
this.didAutosaveForEditsReference = false;
}

if ( ! isAutosaving && prevProps.isAutosaving ) {
this.didAutosaveForEditsReference = true;
}

if (
prevProps.isDirty !== isDirty ||
prevProps.isAutosaveable !== isAutosaveable ||
prevProps.editsReference !== editsReference
) {
this.toggleTimer( isDirty && isAutosaveable );
this.toggleTimer(
isDirty &&
isAutosaveable &&
! this.didAutosaveForEditsReference
);
}
}

Expand Down Expand Up @@ -45,6 +64,7 @@ export default compose( [
isEditedPostAutosaveable,
getEditorSettings,
getReferenceByDistinctEdits,
isAutosavingPost,
} = select( 'core/editor' );

const { autosaveInterval } = getEditorSettings();
Expand All @@ -53,6 +73,7 @@ export default compose( [
isDirty: isEditedPostDirty(),
isAutosaveable: isEditedPostAutosaveable(),
editsReference: getReferenceByDistinctEdits(),
isAutosaving: isAutosavingPost(),
autosaveInterval,
};
} ),
Expand Down
22 changes: 22 additions & 0 deletions packages/editor/src/components/autosave-monitor/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ describe( 'AutosaveMonitor', () => {

expect( toggleTimer ).toHaveBeenCalledWith( false );
} );

it( 'should avoid scheduling autosave if still dirty but already autosaved for edits', () => {
// Explanation: When a published post is autosaved, it's still in a
// dirty state since the edits are not saved to the post until the
// user clicks "Update". To avoid recurring autosaves, ensure that
// an edit has occurred since the last autosave had completed.

const beforeReference = [];
const afterReference = [];

// A post is non-dirty while autosave is in-flight.
wrapper.setProps( { isDirty: false, isAutosaving: true, isAutosaveable: true, editsReference: beforeReference } );
toggleTimer.mockClear();
wrapper.setProps( { isDirty: true, isAutosaving: false, isAutosaveable: true, editsReference: beforeReference } );

expect( toggleTimer ).toHaveBeenCalledWith( false );

// Once edit occurs after autosave, resume scheduling.
wrapper.setProps( { isDirty: true, isAutosaving: false, isAutosaveable: true, editsReference: afterReference } );

expect( toggleTimer.mock.calls[ 1 ][ 0 ] ).toBe( true );
} );
} );

describe( '#componentWillUnmount()', () => {
Expand Down

0 comments on commit 6a91586

Please sign in to comment.