diff --git a/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/childProcessorTest.ts b/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/childProcessorTest.ts index 4a92fb4a3c8..4e67d6eae04 100644 --- a/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/childProcessorTest.ts +++ b/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/childProcessorTest.ts @@ -185,7 +185,8 @@ describe('childProcessor', () => { isSelected: true, format: {}, }, - { segmentType: 'Text', text: 'test2test3', format: {} }, + { segmentType: 'Text', text: 'test2', format: {} }, + { segmentType: 'Text', text: 'test3', format: {} }, ], isImplicit: true, format: {}, diff --git a/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/generalProcessorTest.ts b/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/generalProcessorTest.ts index 7e72033bc69..4bcaf20b1fa 100644 --- a/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/generalProcessorTest.ts +++ b/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/generalProcessorTest.ts @@ -257,7 +257,13 @@ describe('generalProcessor', () => { segments: [ { segmentType: 'Text', - text: 'tes', + text: 't', + format: {}, + isSelected: true, + }, + { + segmentType: 'Text', + text: 'es', format: {}, isSelected: true, }, diff --git a/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/textProcessorTest.ts b/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/textProcessorTest.ts index 5217d221f35..2ca74cd5ebb 100644 --- a/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/textProcessorTest.ts +++ b/packages-content-model/roosterjs-content-model-dom/test/domToModel/processors/textProcessorTest.ts @@ -95,7 +95,12 @@ describe('textProcessor', () => { segments: [ { segmentType: 'Text', - text: 'test0test1', + text: 'test0', + format: {}, + }, + { + segmentType: 'Text', + text: 'test1', format: {}, }, ], @@ -255,7 +260,13 @@ describe('textProcessor', () => { segments: [ { segmentType: 'Text', - text: 'test1test2', + text: 'test1', + isSelected: true, + format: {}, + }, + { + segmentType: 'Text', + text: 'test2', isSelected: true, format: {}, }, @@ -441,7 +452,14 @@ describe('textProcessor', () => { expect(doc).toEqual({ blockGroupType: 'Document', - blocks: [], + blocks: [ + { + blockType: 'Paragraph', + segments: [], + format: {}, + isImplicit: true, + }, + ], }); }); @@ -453,7 +471,14 @@ describe('textProcessor', () => { expect(doc).toEqual({ blockGroupType: 'Document', - blocks: [], + blocks: [ + { + blockType: 'Paragraph', + segments: [], + format: {}, + isImplicit: true, + }, + ], }); }); @@ -494,7 +519,12 @@ describe('textProcessor', () => { { segmentType: 'Text', format: {}, - text: 'test ', + text: 'test', + }, + { + segmentType: 'Text', + format: {}, + text: ' ', }, ], }, diff --git a/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/createContentModel.ts b/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/createContentModel.ts index 1a2dbd8f3ee..24ab34a8fc4 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/createContentModel.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/createContentModel.ts @@ -1,6 +1,5 @@ import { cloneModel } from '../../modelApi/common/cloneModel'; -import { contentModelDomIndexer } from '../utils/contentModelDomIndexer'; -import { DomToModelContext, DomToModelOption } from 'roosterjs-content-model-types'; +import { DomToModelOption } from 'roosterjs-content-model-types'; import { SelectionRangeEx } from 'roosterjs-editor-types'; import { createDomToModelContext, @@ -48,21 +47,9 @@ function internalCreateContentModel( option?: DomToModelOption ) { const editorContext = core.api.createEditorContext(core); - let domToModelContext: DomToModelContext; - - if (option) { - domToModelContext = createDomToModelContext( - editorContext, - ...(core.defaultDomToModelOptions || []), - option - ); - } else { - editorContext.domIndexer = contentModelDomIndexer; - domToModelContext = createDomToModelContextWithConfig( - core.defaultDomToModelConfig, - editorContext - ); - } + const domToModelContext = option + ? createDomToModelContext(editorContext, ...(core.defaultDomToModelOptions || []), option) + : createDomToModelContextWithConfig(core.defaultDomToModelConfig, editorContext); return domToContentModel(core.contentDiv, domToModelContext, selection); } diff --git a/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/setContentModel.ts b/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/setContentModel.ts index 589d2450f7e..6db0f28c104 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/setContentModel.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/editor/coreApi/setContentModel.ts @@ -1,5 +1,3 @@ -import { contentModelDomIndexer } from '../utils/contentModelDomIndexer'; -import { ModelToDomContext } from 'roosterjs-content-model-types'; import { SetContentModel } from '../../publicTypes/ContentModelEditorCore'; import { contentModelToDom, @@ -14,29 +12,17 @@ import { * @param model The content model to set * @param option Additional options to customize the behavior of Content Model to DOM conversion */ -export const setContentModel: SetContentModel = (core, model, option) => { +export const setContentModel: SetContentModel = (core, model, option, onNodeCreated) => { const editorContext = core.api.createEditorContext(core); - let modelToDomContext: ModelToDomContext; - - if (option) { - modelToDomContext = createModelToDomContext( - editorContext, - ...(core.defaultModelToDomOptions || []), - option - ); - } else { - editorContext.domIndexer = contentModelDomIndexer; - modelToDomContext = createModelToDomContextWithConfig( - core.defaultModelToDomConfig, - editorContext - ); - } - + const modelToDomContext = option + ? createModelToDomContext(editorContext, ...(core.defaultModelToDomOptions || []), option) + : createModelToDomContextWithConfig(core.defaultModelToDomConfig, editorContext); const range = contentModelToDom( core.contentDiv.ownerDocument, core.contentDiv, model, - modelToDomContext + modelToDomContext, + onNodeCreated ); core.contentDiv.normalize(); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/editor/corePlugins/ContentModelCachePlugin.ts b/packages-content-model/roosterjs-content-model-editor/lib/editor/corePlugins/ContentModelCachePlugin.ts index 21da0c77227..da110762b72 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/editor/corePlugins/ContentModelCachePlugin.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/editor/corePlugins/ContentModelCachePlugin.ts @@ -107,12 +107,11 @@ export default class ContentModelCachePlugin { const { contentModel, rangeEx } = event as ContentModelContentChangedEvent; - if (contentModel) { + if (contentModel && this.state.domIndexer) { this.state.cachedModel = contentModel; this.state.cachedRangeEx = rangeEx; } else { this.editor.invalidateCache(); - this.editor.createContentModel(); } } diff --git a/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/createEditorContextTest.ts b/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/createEditorContextTest.ts index f0b6708b0a3..e97cf7af383 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/createEditorContextTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/createEditorContextTest.ts @@ -27,6 +27,7 @@ describe('createEditorContext', () => { defaultFormat, darkColorHandler, addDelimiterForEntity, + cache: {}, } as any) as ContentModelEditorCore; const context = createEditorContext(core); @@ -37,6 +38,7 @@ describe('createEditorContext', () => { defaultFormat, addDelimiterForEntity, allowCacheElement: true, + domIndexer: undefined, }); }); }); @@ -71,6 +73,7 @@ describe('createEditorContext - checkZoomScale', () => { defaultFormat, darkColorHandler, addDelimiterForEntity, + cache: {}, } as any) as ContentModelEditorCore; }); @@ -89,6 +92,7 @@ describe('createEditorContext - checkZoomScale', () => { addDelimiterForEntity, zoomScale: 1, allowCacheElement: true, + domIndexer: undefined, }); }); @@ -107,6 +111,7 @@ describe('createEditorContext - checkZoomScale', () => { addDelimiterForEntity, zoomScale: 2, allowCacheElement: true, + domIndexer: undefined, }); }); @@ -125,6 +130,7 @@ describe('createEditorContext - checkZoomScale', () => { addDelimiterForEntity, zoomScale: 0.5, allowCacheElement: true, + domIndexer: undefined, }); }); }); @@ -159,6 +165,7 @@ describe('createEditorContext - checkRootDir', () => { defaultFormat, darkColorHandler, addDelimiterForEntity, + cache: {}, } as any) as ContentModelEditorCore; }); @@ -175,6 +182,7 @@ describe('createEditorContext - checkRootDir', () => { darkColorHandler, addDelimiterForEntity, allowCacheElement: true, + domIndexer: undefined, }); }); @@ -192,6 +200,7 @@ describe('createEditorContext - checkRootDir', () => { addDelimiterForEntity, isRootRtl: true, allowCacheElement: true, + domIndexer: undefined, }); }); }); diff --git a/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/setContentModelTest.ts b/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/setContentModelTest.ts index 91afa5bd6b9..1c8c5cc5d70 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/setContentModelTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/editor/coreApi/setContentModelTest.ts @@ -19,6 +19,7 @@ describe('setContentModel', () => { let createModelToDomContextWithConfigSpy: jasmine.Spy; let select: jasmine.Spy; let getSelectionRange: jasmine.Spy; + let normalizeSpy: jasmine.Spy; beforeEach(() => { contentModelToDomSpy = spyOn(contentModelToDom, 'contentModelToDom').and.returnValue( @@ -37,6 +38,9 @@ describe('setContentModel', () => { ).and.returnValue(mockedContext); select = jasmine.createSpy('select'); getSelectionRange = jasmine.createSpy('getSelectionRange'); + normalizeSpy = jasmine.createSpy('normalize'); + + mockedDiv.normalize = normalizeSpy; core = ({ contentDiv: mockedDiv, @@ -67,6 +71,8 @@ describe('setContentModel', () => { undefined ); expect(select).toHaveBeenCalledWith(core, mockedRange); + expect(normalizeSpy).toHaveBeenCalledTimes(1); + expect(normalizeSpy).toHaveBeenCalledWith(); }); it('with default option, no shadow edit', () => { @@ -84,6 +90,8 @@ describe('setContentModel', () => { undefined ); expect(select).toHaveBeenCalledWith(core, mockedRange); + expect(normalizeSpy).toHaveBeenCalledTimes(1); + expect(normalizeSpy).toHaveBeenCalledWith(); }); it('with default option, no shadow edit, with additional option', () => { @@ -106,6 +114,8 @@ describe('setContentModel', () => { undefined ); expect(select).toHaveBeenCalledWith(core, mockedRange); + expect(normalizeSpy).toHaveBeenCalledTimes(1); + expect(normalizeSpy).toHaveBeenCalledWith(); }); it('no default option, with shadow edit', () => { @@ -125,5 +135,7 @@ describe('setContentModel', () => { undefined ); expect(select).not.toHaveBeenCalled(); + expect(normalizeSpy).toHaveBeenCalledTimes(1); + expect(normalizeSpy).toHaveBeenCalledWith(); }); }); diff --git a/packages-content-model/roosterjs-content-model-editor/test/editor/createContentModelEditorCoreTest.ts b/packages-content-model/roosterjs-content-model-editor/test/editor/createContentModelEditorCoreTest.ts index 2a054c43a49..89bf2123e87 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/editor/createContentModelEditorCoreTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/editor/createContentModelEditorCoreTest.ts @@ -125,7 +125,7 @@ describe('createContentModelEditorCore', () => { contentDiv: { style: {}, }, - cache: {}, + cache: { domIndexer: undefined }, copyPaste: { allowedCustomPasteType: [] }, } as any); }); @@ -270,7 +270,7 @@ describe('createContentModelEditorCore', () => { contentDiv: { style: {}, }, - cache: {}, + cache: { domIndexer: undefined }, copyPaste: { allowedCustomPasteType: [] }, } as any); }); @@ -330,7 +330,7 @@ describe('createContentModelEditorCore', () => { contentDiv: { style: {}, }, - cache: {}, + cache: { domIndexer: undefined }, copyPaste: { allowedCustomPasteType: [] }, } as any); }); @@ -397,7 +397,7 @@ describe('createContentModelEditorCore', () => { contentDiv: { style: {}, }, - cache: {}, + cache: { domIndexer: undefined }, copyPaste: { allowedCustomPasteType: [] }, } as any); }); diff --git a/packages-content-model/roosterjs-content-model-editor/test/editor/plugins/paste/processPastedContentFromWacTest.ts b/packages-content-model/roosterjs-content-model-editor/test/editor/plugins/paste/processPastedContentFromWacTest.ts index b20f5c1981a..60a6f9ef408 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/editor/plugins/paste/processPastedContentFromWacTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/editor/plugins/paste/processPastedContentFromWacTest.ts @@ -1577,7 +1577,7 @@ describe('wordOnlineHandler', () => { it('Remove temp marker from Word Online', () => { runTest( '
it went:
Test
Test.
it went:
Test
Test.
it went:
Test
Test.