Skip to content

Commit

Permalink
Directly create Content Model editor (#2206)
Browse files Browse the repository at this point in the history
  • Loading branch information
JiuqingSong authored Nov 14, 2023
1 parent 6cec1cc commit 32280bf
Show file tree
Hide file tree
Showing 46 changed files with 762 additions and 1,423 deletions.
3 changes: 1 addition & 2 deletions demo/scripts/controls/ContentModelEditorMainPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { arrayPush } from 'roosterjs-editor-dom';
import { ContentModelEditor } from 'roosterjs-content-model-editor';
import { ContentModelEditPlugin } from 'roosterjs-content-model-plugins';
import { ContentModelRibbonPlugin } from './ribbonButtons/contentModel/ContentModelRibbonPlugin';
import { createContentModelEditorCore } from 'roosterjs-content-model-core';
import { createEmojiPlugin, createPasteOptionPlugin, RibbonPlugin } from 'roosterjs-react';
import { EditorOptions, EditorPlugin } from 'roosterjs-editor-types';
import { PartialTheme } from '@fluentui/react/lib/Theme';
Expand Down Expand Up @@ -184,7 +183,7 @@ class ContentModelEditorMainPane extends MainPaneBase {
this.toggleablePlugins = null;
this.setState({
editorCreator: (div: HTMLDivElement, options: EditorOptions) =>
new ContentModelEditor(div, createContentModelEditorCore, {
new ContentModelEditor(div, {
...options,
cacheModel: this.state.initState.cacheModel,
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import insertLink from '../../../lib/publicApi/link/insertLink';
import { ChangeSource } from 'roosterjs-content-model-core';
import { ContentModelEditor } from 'roosterjs-content-model-editor';
import { createContentModelEditorCore } from 'roosterjs-content-model-core';
import { IStandaloneEditor } from 'roosterjs-content-model-types';
import { PluginEventType } from 'roosterjs-editor-types';
import {
Expand Down Expand Up @@ -331,7 +330,7 @@ describe('insertLink', () => {
getName: () => 'mock',
onPluginEvent: onPluginEvent,
};
const editor = new ContentModelEditor(div, createContentModelEditorCore, {
const editor = new ContentModelEditor(div, {
plugins: [mockedPlugin],
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { areSameSelection } from './utils/areSameSelection';
import { contentModelDomIndexer } from './utils/contentModelDomIndexer';
import { isCharacterValue } from '../publicApi/domUtils/eventUtils';
import { PluginEventType } from 'roosterjs-editor-types';
import type {
ContentModelCachePluginState,
ContentModelContentChangedEvent,
IStandaloneEditor,
StandaloneEditorOptions,
} from 'roosterjs-content-model-types';
import type {
IEditor,
Expand All @@ -16,15 +18,18 @@ import type {
/**
* ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary
*/
export class ContentModelCachePlugin implements PluginWithState<ContentModelCachePluginState> {
class ContentModelCachePlugin implements PluginWithState<ContentModelCachePluginState> {
private editor: (IEditor & IStandaloneEditor) | null = null;
private state: ContentModelCachePluginState;

/**
* Construct a new instance of ContentModelEditPlugin class
* @param state State of this plugin
* @param option The editor option
*/
constructor(private state: ContentModelCachePluginState) {
// TODO: Remove tempState parameter once we have standalone Content Model editor
constructor(option: StandaloneEditorOptions) {
this.state = {
domIndexer: option.cacheModel ? contentModelDomIndexer : undefined,
};
}

/**
Expand Down Expand Up @@ -188,9 +193,10 @@ export class ContentModelCachePlugin implements PluginWithState<ContentModelCach
/**
* @internal
* Create a new instance of ContentModelCachePlugin class.
* This is mostly for unit test
* @param state State of this plugin
* @param option The editor option
*/
export function createContentModelCachePlugin(state: ContentModelCachePluginState) {
return new ContentModelCachePlugin(state);
export function createContentModelCachePlugin(
option: StandaloneEditorOptions
): PluginWithState<ContentModelCachePluginState> {
return new ContentModelCachePlugin(option);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,26 @@ import type {
IEditor,
PluginWithState,
ClipboardData,
EditorOptions,
} from 'roosterjs-editor-types';

/**
* Copy and paste plugin for handling onCopy and onPaste event
*/
export class ContentModelCopyPastePlugin implements PluginWithState<CopyPastePluginState> {
class ContentModelCopyPastePlugin implements PluginWithState<CopyPastePluginState> {
private editor: (IStandaloneEditor & IEditor) | null = null;
private disposer: (() => void) | null = null;
private state: CopyPastePluginState;

/**
* Construct a new instance of CopyPastePlugin
* @param options The editor options
* @param option The editor option
*/
constructor(private state: CopyPastePluginState) {}
constructor(option: EditorOptions) {
this.state = {
allowedCustomPasteType: option.allowedCustomPasteType || [],
};
}

/**
* Get a friendly name of this plugin
Expand Down Expand Up @@ -289,8 +295,10 @@ export const onNodeCreated: OnNodeCreated = (_, node): void => {
/**
* @internal
* Create a new instance of ContentModelCopyPastePlugin
* @param state The plugin state object
* @param option The editor option
*/
export function createContentModelCopyPastePlugin(state: CopyPastePluginState) {
return new ContentModelCopyPastePlugin(state);
export function createContentModelCopyPastePlugin(
option: EditorOptions
): PluginWithState<CopyPastePluginState> {
return new ContentModelCopyPastePlugin(option);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { IEditor, PluginEvent, PluginWithState } from 'roosterjs-editor-typ
import type {
ContentModelFormatPluginState,
IStandaloneEditor,
StandaloneEditorOptions,
} from 'roosterjs-content-model-types';

// During IME input, KeyDown event will have "Process" as key
Expand All @@ -27,16 +28,30 @@ const CursorMovingKeys = new Set<string>([
* This includes:
* 1. Handle pending format changes when selection is collapsed
*/
export class ContentModelFormatPlugin implements PluginWithState<ContentModelFormatPluginState> {
class ContentModelFormatPlugin implements PluginWithState<ContentModelFormatPluginState> {
private editor: (IStandaloneEditor & IEditor) | null = null;
private hasDefaultFormat = false;
private state: ContentModelFormatPluginState;

/**
* Construct a new instance of ContentModelEditPlugin class
* @param state State of this plugin
* @param option The editor option
*/
constructor(private state: ContentModelFormatPluginState) {
// TODO: Remove tempState parameter once we have standalone Content Model editor
constructor(option: StandaloneEditorOptions) {
const format = option.defaultFormat || {};
this.state = {
defaultFormat: {
fontWeight: format.bold ? 'bold' : undefined,
italic: format.italic || undefined,
underline: format.underline || undefined,
fontFamily: format.fontFamily || undefined,
fontSize: format.fontSize || undefined,
textColor: format.textColors?.lightModeColor || format.textColor || undefined,
backgroundColor:
format.backgroundColors?.lightModeColor || format.backgroundColor || undefined,
},
pendingFormat: null,
};
}

/**
Expand Down Expand Up @@ -163,8 +178,10 @@ export class ContentModelFormatPlugin implements PluginWithState<ContentModelFor
/**
* @internal
* Create a new instance of ContentModelFormatPlugin.
* This is mostly for unit test
* @param option The editor option
*/
export function createContentModelFormatPlugin(state: ContentModelFormatPluginState) {
return new ContentModelFormatPlugin(state);
export function createContentModelFormatPlugin(
option: StandaloneEditorOptions
): PluginWithState<ContentModelFormatPluginState> {
return new ContentModelFormatPlugin(option);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createContentModelCachePlugin } from './ContentModelCachePlugin';
import { createContentModelCopyPastePlugin } from './ContentModelCopyPastePlugin';
import { createContentModelFormatPlugin } from './ContentModelFormatPlugin';
import type {
StandaloneEditorCorePlugins,
StandaloneEditorOptions,
} from 'roosterjs-content-model-types';

/**
* Create core plugins for standalone editor
* @param options Options of editor
*/
export function createStandaloneEditorCorePlugins(
options: StandaloneEditorOptions
): StandaloneEditorCorePlugins {
return {
cache: createContentModelCachePlugin(options),
format: createContentModelFormatPlugin(options),
copyPaste: createContentModelCopyPastePlugin(options),
typeInContainer: null!, // TODO: remove this plugin since we don't need it any more
};
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { createDomToModelConfig, createModelToDomConfig } from 'roosterjs-content-model-dom';
import { listItemMetadataApplier, listLevelMetadataApplier } from '../metadata/updateListMetadata';
import { tablePreProcessor } from '../override/tablePreProcessor';
import type {
DomToModelOption,
ModelToDomOption,
StandaloneEditorDefaultSettings,
StandaloneEditorOptions,
} from 'roosterjs-content-model-types';

/**
* Create default DOM and Content Model conversion settings for a standalone editor
* @param options The editor options
*/
export function createStandaloneEditorDefaultSettings(
options: StandaloneEditorOptions
): StandaloneEditorDefaultSettings {
const defaultDomToModelOptions: (DomToModelOption | undefined)[] = [
{
processorOverride: {
table: tablePreProcessor,
},
},
options.defaultDomToModelOptions,
];
const defaultModelToDomOptions: (ModelToDomOption | undefined)[] = [
{
metadataAppliers: {
listItem: listItemMetadataApplier,
listLevel: listLevelMetadataApplier,
},
},
options.defaultModelToDomOptions,
];

return {
defaultDomToModelOptions,
defaultModelToDomOptions,
defaultDomToModelConfig: createDomToModelConfig(defaultDomToModelOptions),
defaultModelToDomConfig: createModelToDomConfig(defaultModelToDomOptions),
};
}
Loading

0 comments on commit 32280bf

Please sign in to comment.