Skip to content

Commit

Permalink
Improve
Browse files Browse the repository at this point in the history
  • Loading branch information
JiuqingSong committed Nov 20, 2024
1 parent 928c632 commit b41ba36
Show file tree
Hide file tree
Showing 49 changed files with 632 additions and 584 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,6 @@ describe('insertLink', () => {
const editor = new Editor(div, {
plugins: [mockedPlugin],
});
const firstDiv = div.firstChild as HTMLElement;

editor.focus();

Expand All @@ -349,8 +348,6 @@ describe('insertLink', () => {
contentModel: jasmine.anything(),
selection: jasmine.anything(),
changedEntities: [],
addedBlockElements: [div.firstChild],
removedBlockElements: [firstDiv],
});

document.body.removeChild(div);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
FormatContentModel,
FormatContentModelContext,
EditorCore,
DomManipulationContext,
} from 'roosterjs-content-model-types';

/**
Expand Down Expand Up @@ -60,15 +59,12 @@ export const formatContentModel: FormatContentModel = (
try {
handleImages(core, context);

const domManipulationResult: Partial<DomManipulationContext> = {};

selection =
core.api.setContentModel(
core,
model,
hasFocus ? undefined : { ignoreSelection: true }, // If editor did not have focus before format, do not set focus after format
onNodeCreated,
domManipulationResult
onNodeCreated
) ?? undefined;

handlePendingFormat(core, context, selection);
Expand All @@ -85,8 +81,6 @@ export const formatContentModel: FormatContentModel = (
data: getChangeData?.(),
formatApiName: options?.apiName,
changedEntities: getChangedEntities(context, rawEvent),
addedBlockElements: domManipulationResult.addedBlockElements,
removedBlockElements: domManipulationResult.removedBlockElements,
};

core.api.triggerEvent(core, eventData, true /*broadcast*/);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import type { SetContentModel } from 'roosterjs-content-model-types';
* @param core The editor core object
* @param model The content model to set
* @param option Additional options to customize the behavior of Content Model to DOM conversion
* @param domManipulationResult Used for receiving added and removed block elements during this operation
* @param onNodeCreated An optional callback that will be called when a DOM node is created
* @param isInitializing True means editor is being initialized then it will save modification nodes onto
* lifecycleState instead of triggering events, false means other cases
*/
export const setContentModel: SetContentModel = (
core,
model,
option,
onNodeCreated,
domManipulationResult
isInitializing
) => {
const editorContext = core.api.createEditorContext(core, true /*saveIndex*/);
const modelToDomContext = option
Expand Down Expand Up @@ -56,9 +58,19 @@ export const setContentModel: SetContentModel = (
}
}

if (domManipulationResult) {
domManipulationResult.addedBlockElements = modelToDomContext.addedBlockElements;
domManipulationResult.removedBlockElements = modelToDomContext.removedBlockElements;
if (isInitializing) {
// When initialize, we should not trigger event until all plugins are initialized, so put these node in lifecycle state temporarily
core.lifecycle.domModification = modelToDomContext.domModification;
} else {
// Otherwise, trigger DomModification event immediately
core.api.triggerEvent(
core,
{
eventType: 'domModification',
...modelToDomContext.domModification,
},
true /*broadcast*/
);
}

return selection;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChangeSource, iterateSelections, moveChildNodes } from 'roosterjs-content-model-dom';
import type { DomManipulationContext, SwitchShadowEdit } from 'roosterjs-content-model-types';
import { iterateSelections, moveChildNodes } from 'roosterjs-content-model-dom';
import type { SwitchShadowEdit } from 'roosterjs-content-model-types';

/**
* @internal
Expand Down Expand Up @@ -48,29 +48,9 @@ export const switchShadowEdit: SwitchShadowEdit = (editorCore, isOn): void => {
// Force clear cached element from selected block
iterateSelections(core.cache.cachedModel, () => {});

const domManipulationResult: Partial<DomManipulationContext> = {};
const selection = core.api.setContentModel(
core,
core.cache.cachedModel,
{
ignoreSelection: true, // Do not set focus and selection when quit shadow edit, focus may remain in UI control (picker, ...)
},
undefined /*onNodeCreated*/,
domManipulationResult
);

core.api.triggerEvent(
core,
{
eventType: 'contentChanged',
source: ChangeSource.LeftShadowEdit,
contentModel: core.cache.cachedModel,
selection: selection ?? undefined,
addedBlockElements: domManipulationResult.addedBlockElements,
removedBlockElements: domManipulationResult.removedBlockElements,
},
false /*broadcast*/
);
core.api.setContentModel(core, core.cache.cachedModel, {
ignoreSelection: true, // Do not set focus and selection when quit shadow edit, focus may remain in UI control (picker, ...)
});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
PluginEvent,
PluginWithState,
EditorOptions,
DomModification,
} from 'roosterjs-content-model-types';

const ContentEditableAttributeName = 'contenteditable';
Expand Down Expand Up @@ -73,6 +74,15 @@ class LifecyclePlugin implements PluginWithState<LifecyclePluginState> {
// Set editor background color for dark mode
this.adjustColor();

// Let other plugins know that we are ready
const domModification: DomModification = this.state.domModification ?? {
addedBlockElements: [],
removedBlockElements: [],
};

this.editor.triggerEvent('editorReady', domModification, true /*broadcast*/);
delete this.state.domModification;

// Initialize the Announce container.
this.state.announceContainer = createAriaLiveElement(editor.getDocument());
}
Expand Down
14 changes: 1 addition & 13 deletions packages/roosterjs-content-model-core/lib/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import type {
DomToModelOptionForCreateModel,
AnnounceData,
ExperimentalFeature,
DomManipulationContext,
} from 'roosterjs-content-model-types';

/**
Expand All @@ -50,26 +49,15 @@ export class Editor implements IEditor {
this.core = createEditorCore(contentDiv, options);

const initialModel = options.initialModel ?? createEmptyModel(options.defaultSegmentFormat);
const domManipulationResult: Partial<DomManipulationContext> = {};

this.core.api.setContentModel(
this.core,
initialModel,
{ ignoreSelection: true },
undefined /*onNodeCreated*/,
domManipulationResult
true /*isInitializing*/
);
this.core.plugins.forEach(plugin => plugin.initialize(this));

// Let other plugins know that we are ready
this.triggerEvent(
'editorReady',
{
addedBlockElements: domManipulationResult.addedBlockElements,
removedBlockElements: domManipulationResult.removedBlockElements,
},
true /*broadcast*/
);
}

/**
Expand Down
Loading

0 comments on commit b41ba36

Please sign in to comment.