Skip to content

Commit

Permalink
Allow skipping marking hasNewContent in formatContentModel (#2933)
Browse files Browse the repository at this point in the history
  • Loading branch information
JiuqingSong authored Jan 31, 2025
1 parent 555c239 commit 5f67c49
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ export const formatContentModel: FormatContentModel = (

if (changed) {
const isNested = core.undo.isNested;
const shouldAddSnapshot = !skipUndoSnapshot && !isNested;
const shouldAddSnapshot =
(!skipUndoSnapshot || skipUndoSnapshot == 'DoNotSkip') && !isNested;
const shouldMarkNewContent =
(skipUndoSnapshot === true || skipUndoSnapshot == 'MarkNewContent') && !isNested;
let selection: DOMSelection | undefined;

if (shouldAddSnapshot) {
Expand Down Expand Up @@ -94,7 +97,9 @@ export const formatContentModel: FormatContentModel = (

if (shouldAddSnapshot) {
core.api.addUndoSnapshot(core, false /*canUndoByBackspace*/, entityStates);
} else {
}

if (shouldMarkNewContent) {
core.undo.snapshotsManager.hasNewContent = true;
}
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('formatContentModel', () => {
expect(announce).not.toHaveBeenCalled();
});

it('Skip undo snapshot', () => {
it('Skip undo snapshot = true', () => {
const callback = jasmine.createSpy('callback').and.callFake((model, context) => {
context.skipUndoSnapshot = true;
return true;
Expand Down Expand Up @@ -157,6 +157,155 @@ describe('formatContentModel', () => {
true
);
expect(announce).not.toHaveBeenCalled();
expect(core.undo.snapshotsManager.hasNewContent).toBeTrue();
});

it('Skip undo snapshot = false', () => {
const callback = jasmine.createSpy('callback').and.callFake((model, context) => {
context.skipUndoSnapshot = false;
return true;
});

formatContentModel(core, callback, { apiName });

expect(callback).toHaveBeenCalledWith(mockedModel, {
newEntities: [],
deletedEntities: [],
rawEvent: undefined,
skipUndoSnapshot: false,
newImages: [],
});
expect(createContentModel).toHaveBeenCalledTimes(1);
expect(addUndoSnapshot).toHaveBeenCalledTimes(2);
expect(setContentModel).toHaveBeenCalledTimes(1);
expect(setContentModel).toHaveBeenCalledWith(core, mockedModel, undefined, undefined);
expect(triggerEvent).toHaveBeenCalledTimes(1);
expect(triggerEvent).toHaveBeenCalledWith(
core,
{
eventType: 'contentChanged',
contentModel: mockedModel,
selection: mockedSelection,
source: ChangeSource.Format,
data: undefined,
formatApiName: apiName,
changedEntities: [],
},
true
);
expect(announce).not.toHaveBeenCalled();
expect(core.undo.snapshotsManager.hasNewContent).toBeFalsy();
});

it('Skip undo snapshot = DoNotSkip', () => {
const callback = jasmine.createSpy('callback').and.callFake((model, context) => {
context.skipUndoSnapshot = 'DoNotSkip';
return true;
});

formatContentModel(core, callback, { apiName });

expect(callback).toHaveBeenCalledWith(mockedModel, {
newEntities: [],
deletedEntities: [],
rawEvent: undefined,
skipUndoSnapshot: 'DoNotSkip',
newImages: [],
});
expect(createContentModel).toHaveBeenCalledTimes(1);
expect(addUndoSnapshot).toHaveBeenCalledTimes(2);
expect(setContentModel).toHaveBeenCalledTimes(1);
expect(setContentModel).toHaveBeenCalledWith(core, mockedModel, undefined, undefined);
expect(triggerEvent).toHaveBeenCalledTimes(1);
expect(triggerEvent).toHaveBeenCalledWith(
core,
{
eventType: 'contentChanged',
contentModel: mockedModel,
selection: mockedSelection,
source: ChangeSource.Format,
data: undefined,
formatApiName: apiName,
changedEntities: [],
},
true
);
expect(announce).not.toHaveBeenCalled();
expect(core.undo.snapshotsManager.hasNewContent).toBeFalsy();
});

it('Skip undo snapshot = MarkNewContent', () => {
const callback = jasmine.createSpy('callback').and.callFake((model, context) => {
context.skipUndoSnapshot = 'MarkNewContent';
return true;
});

formatContentModel(core, callback, { apiName });

expect(callback).toHaveBeenCalledWith(mockedModel, {
newEntities: [],
deletedEntities: [],
rawEvent: undefined,
skipUndoSnapshot: 'MarkNewContent',
newImages: [],
});
expect(createContentModel).toHaveBeenCalledTimes(1);
expect(addUndoSnapshot).toHaveBeenCalledTimes(0);
expect(setContentModel).toHaveBeenCalledTimes(1);
expect(setContentModel).toHaveBeenCalledWith(core, mockedModel, undefined, undefined);
expect(triggerEvent).toHaveBeenCalledTimes(1);
expect(triggerEvent).toHaveBeenCalledWith(
core,
{
eventType: 'contentChanged',
contentModel: mockedModel,
selection: mockedSelection,
source: ChangeSource.Format,
data: undefined,
formatApiName: apiName,
changedEntities: [],
},
true
);
expect(announce).not.toHaveBeenCalled();
expect(core.undo.snapshotsManager.hasNewContent).toBeTruthy();
});

it('Skip undo snapshot = SkipAll', () => {
const callback = jasmine.createSpy('callback').and.callFake((model, context) => {
context.skipUndoSnapshot = 'SkipAll';
return true;
});

formatContentModel(core, callback, { apiName });

expect(callback).toHaveBeenCalledWith(mockedModel, {
newEntities: [],
deletedEntities: [],
rawEvent: undefined,
skipUndoSnapshot: 'SkipAll',
newImages: [],
});
expect(createContentModel).toHaveBeenCalledTimes(1);
expect(addUndoSnapshot).toHaveBeenCalledTimes(0);
expect(setContentModel).toHaveBeenCalledTimes(1);
expect(setContentModel).toHaveBeenCalledWith(core, mockedModel, undefined, undefined);
expect(triggerEvent).toHaveBeenCalledTimes(1);
expect(triggerEvent).toHaveBeenCalledWith(
core,
{
eventType: 'contentChanged',
contentModel: mockedModel,
selection: mockedSelection,
source: ChangeSource.Format,
data: undefined,
formatApiName: apiName,
changedEntities: [],
},
true
);
expect(announce).not.toHaveBeenCalled();
expect(core.undo.snapshotsManager.hasNewContent).toBeFalsy();
});

it('Customize change source', () => {
Expand Down Expand Up @@ -1028,9 +1177,7 @@ describe('formatContentModel', () => {
expect(setContentModel).toHaveBeenCalledWith(core, mockedModel, undefined, undefined);
expect(core.undo).toEqual({
isNested: true,
snapshotsManager: {
hasNewContent: true,
},
snapshotsManager: {},
} as any);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@ export interface FormatContentModelContext {
* @optional
* When pass true, skip adding undo snapshot when write Content Model back to DOM.
* Need to be set by the formatter function
* Default value is false, which means add undo snapshot
* When set to true, it will skip adding undo snapshot but mark "hasNewContent" so that next undo snapshot will be added, this is same with "MarkNewContent"
* When set to 'DoNotSkip', it will add undo snapshot (default behavior)
* When set to 'MarkNewContent', it will skip adding undo snapshot but mark "hasNewContent" so that next undo snapshot will be added
* When set to 'SkipAll', it will skip adding undo snapshot and not mark "hasNewContent", as if no change is made
*/
skipUndoSnapshot?: boolean;
skipUndoSnapshot?: boolean | 'DoNotSkip' | 'MarkNewContent' | 'SkipAll';

/**
* @optional
Expand Down

0 comments on commit 5f67c49

Please sign in to comment.