diff --git a/packages/roosterjs-content-model-core/lib/command/paste/generatePasteOptionFromPlugins.ts b/packages/roosterjs-content-model-core/lib/command/paste/generatePasteOptionFromPlugins.ts index 7e89f05a180..1f2955de2e7 100644 --- a/packages/roosterjs-content-model-core/lib/command/paste/generatePasteOptionFromPlugins.ts +++ b/packages/roosterjs-content-model-core/lib/command/paste/generatePasteOptionFromPlugins.ts @@ -7,16 +7,6 @@ import type { IEditor, } from 'roosterjs-content-model-types'; -const emptyDomToModelOption: Readonly = { - additionalAllowedTags: [], - additionalDisallowedTags: [], - additionalFormatParsers: {}, - formatParserOverride: {}, - processorOverride: {}, - styleSanitizers: {}, - attributeSanitizers: {}, -}; - /** * @internal */ @@ -25,8 +15,7 @@ export function generatePasteOptionFromPlugins( clipboardData: ClipboardData, fragment: DocumentFragment, htmlFromClipboard: HtmlFromClipboard, - pasteType: PasteType, - domToModelOption: Readonly> + pasteType: PasteType ): BeforePasteEvent { const event: BeforePasteEvent = { eventType: 'beforePaste', @@ -36,7 +25,7 @@ export function generatePasteOptionFromPlugins( htmlAfter: htmlFromClipboard.htmlAfter ?? '', htmlAttributes: htmlFromClipboard.metadata, pasteType: pasteType, - domToModelOption: Object.assign({}, emptyDomToModelOption, domToModelOption), + domToModelOption: createDomToModelOption(editor), containsBlockElements: !!htmlFromClipboard.containsBlockElements, }; @@ -44,3 +33,16 @@ export function generatePasteOptionFromPlugins( ? event : editor.triggerEvent('beforePaste', event, true /* broadcast */); } +function createDomToModelOption(editor: IEditor): DomToModelOptionForSanitizing { + const pasteDomToModel = editor.getEnvironment().domToModelSettings.paste; + const emptyDomToModelOption: Readonly = { + additionalAllowedTags: [], + additionalDisallowedTags: [], + additionalFormatParsers: {}, + formatParserOverride: {}, + processorOverride: {}, + styleSanitizers: {}, + attributeSanitizers: {}, + }; + return Object.assign({}, emptyDomToModelOption, pasteDomToModel); +} diff --git a/packages/roosterjs-content-model-core/lib/command/paste/paste.ts b/packages/roosterjs-content-model-core/lib/command/paste/paste.ts index da10c67a192..69cd08340d5 100644 --- a/packages/roosterjs-content-model-core/lib/command/paste/paste.ts +++ b/packages/roosterjs-content-model-core/lib/command/paste/paste.ts @@ -8,7 +8,6 @@ import type { ClipboardData, TrustedHTMLHandler, IEditor, - DomToModelOptionForSanitizing, } from 'roosterjs-content-model-types'; /** @@ -20,8 +19,7 @@ import type { export function paste( editor: IEditor, clipboardData: ClipboardData, - pasteTypeOrGetter: PasteTypeOrGetter = 'normal', - pasteDomToModelOption: Readonly> = {} + pasteTypeOrGetter: PasteTypeOrGetter = 'normal' ) { editor.focus(); @@ -62,8 +60,7 @@ export function paste( clipboardData, sourceFragment, htmlFromClipboard, - pasteType, - pasteDomToModelOption + pasteType ); // 5. Convert global CSS to inline CSS diff --git a/packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts b/packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts index f1723d89e87..bfc3eb63042 100644 --- a/packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts +++ b/packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts @@ -52,7 +52,6 @@ class CopyPastePlugin implements PluginWithState { allowedCustomPasteType: option.allowedCustomPasteType || [], tempDiv: null, defaultPasteType: option.defaultPasteType, - pasteOptionDomToModel: option.pasteOptionDomToModel, }; } @@ -206,12 +205,7 @@ class CopyPastePlugin implements PluginWithState { this.state.allowedCustomPasteType ).then((clipboardData: ClipboardData) => { if (!editor.isDisposed()) { - paste( - editor, - clipboardData, - this.state.defaultPasteType, - this.state.pasteOptionDomToModel - ); + paste(editor, clipboardData, this.state.defaultPasteType); } }); } diff --git a/packages/roosterjs-content-model-core/lib/editor/core/createEditorDefaultSettings.ts b/packages/roosterjs-content-model-core/lib/editor/core/createEditorDefaultSettings.ts index ffab5e66ffa..595ae162c22 100644 --- a/packages/roosterjs-content-model-core/lib/editor/core/createEditorDefaultSettings.ts +++ b/packages/roosterjs-content-model-core/lib/editor/core/createEditorDefaultSettings.ts @@ -4,12 +4,11 @@ import { listLevelMetadataApplier, } from '../../override/listMetadataApplier'; import type { - ContentModelSettings, DomToModelOption, - DomToModelSettings, ModelToDomOption, - ModelToDomSettings, EditorOptions, + ModelToDomSetting, + DomToModelSetting, } from 'roosterjs-content-model-types'; /** @@ -17,9 +16,7 @@ import type { * Create default DOM to Content Model conversion settings for an editor * @param options The editor options */ -export function createDomToModelSettings( - options: EditorOptions -): ContentModelSettings { +export function createDomToModelSettings(options: EditorOptions): DomToModelSetting { const builtIn: DomToModelOption = {}; const customized: DomToModelOption = options.defaultDomToModelOptions ?? {}; @@ -27,6 +24,7 @@ export function createDomToModelSettings( builtIn, customized, calculated: createDomToModelConfig([builtIn, customized]), + paste: options.pasteOptionDomToModel ?? {}, }; } @@ -35,9 +33,7 @@ export function createDomToModelSettings( * Create default Content Model to DOM conversion settings for an editor * @param options The editor options */ -export function createModelToDomSettings( - options: EditorOptions -): ContentModelSettings { +export function createModelToDomSettings(options: EditorOptions): ModelToDomSetting { const builtIn: ModelToDomOption = { metadataAppliers: { listItem: listItemMetadataApplier, diff --git a/packages/roosterjs-content-model-core/test/command/paste/generatePasteOptionFromPluginsTest.ts b/packages/roosterjs-content-model-core/test/command/paste/generatePasteOptionFromPluginsTest.ts index 7c434d19259..465ee386fe4 100644 --- a/packages/roosterjs-content-model-core/test/command/paste/generatePasteOptionFromPluginsTest.ts +++ b/packages/roosterjs-content-model-core/test/command/paste/generatePasteOptionFromPluginsTest.ts @@ -4,6 +4,7 @@ import { IEditor } from 'roosterjs-content-model-types'; describe('generatePasteOptionFromPlugins', () => { let editor: IEditor; let triggerPluginEventSpy: jasmine.Spy; + let getEnvironmentSpy: jasmine.Spy; const mockedClipboardData = 'CLIPBOARDDATA' as any; const mockedFragment = 'FRAGMENT' as any; @@ -19,8 +20,14 @@ describe('generatePasteOptionFromPlugins', () => { beforeEach(() => { triggerPluginEventSpy = jasmine.createSpy('triggerEvent'); + getEnvironmentSpy = jasmine.createSpy('getEnvironment').and.returnValue({ + domToModelSettings: { + paste: {}, + }, + }); editor = { triggerEvent: triggerPluginEventSpy, + getEnvironment: getEnvironmentSpy, } as any; }); diff --git a/packages/roosterjs-content-model-core/test/editor/core/createEditorDefaultSettingsTest.ts b/packages/roosterjs-content-model-core/test/editor/core/createEditorDefaultSettingsTest.ts index 942c94313df..3fd85a6c368 100644 --- a/packages/roosterjs-content-model-core/test/editor/core/createEditorDefaultSettingsTest.ts +++ b/packages/roosterjs-content-model-core/test/editor/core/createEditorDefaultSettingsTest.ts @@ -25,20 +25,24 @@ describe('createDomToModelSettings', () => { builtIn: {}, customized: {}, calculated: mockedCalculatedConfig, + paste: {}, }); expect(createDomToModelContext.createDomToModelConfig).toHaveBeenCalledWith([{}, {}]); }); it('Has options', () => { const defaultDomToModelOptions = 'MockedOptions' as any; + const pasteOptionDomToModel = 'PasteMockedOptions' as any; const settings = createDomToModelSettings({ defaultDomToModelOptions: defaultDomToModelOptions, + pasteOptionDomToModel, }); expect(settings).toEqual({ builtIn: {}, customized: defaultDomToModelOptions, calculated: mockedCalculatedConfig, + paste: pasteOptionDomToModel, }); expect(createDomToModelContext.createDomToModelConfig).toHaveBeenCalledWith([ {}, diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 215f43d77df..8fbbfb80b20 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -389,7 +389,12 @@ export { export { ContextMenuPluginState } from './pluginState/ContextMenuPluginState'; export { AutoLinkOptions } from './parameter/AutoLinkOptions'; -export { EditorEnvironment, ContentModelSettings } from './parameter/EditorEnvironment'; +export { + EditorEnvironment, + ContentModelSettings, + DomToModelSetting, + ModelToDomSetting, +} from './parameter/EditorEnvironment'; export { EntityState, DeletedEntity, diff --git a/packages/roosterjs-content-model-types/lib/parameter/EditorEnvironment.ts b/packages/roosterjs-content-model-types/lib/parameter/EditorEnvironment.ts index 2b1f64a28db..97fd0ce0970 100644 --- a/packages/roosterjs-content-model-types/lib/parameter/EditorEnvironment.ts +++ b/packages/roosterjs-content-model-types/lib/parameter/EditorEnvironment.ts @@ -23,8 +23,26 @@ export interface ContentModelSettings { * This is a cached object so that we don't need to cache it every time when we use Content Model */ calculated: ConfigType; + + /** + * Paste option used by editor + */ + paste: OptionType; } +/** + * Settings used by DOM to Content Model conversion + */ +export type DomToModelSetting = ContentModelSettings; + +/** + * Settings used by Content Model to DOM conversion + */ +export type ModelToDomSetting = Omit< + ContentModelSettings, + 'paste' +>; + /** * Current running environment */ @@ -52,10 +70,10 @@ export interface EditorEnvironment { /** * Settings used by DOM to Content Model conversion */ - readonly domToModelSettings: ContentModelSettings; + readonly domToModelSettings: DomToModelSetting; /** * Settings used by Content Model to DOM conversion */ - readonly modelToDomSettings: ContentModelSettings; + readonly modelToDomSettings: ModelToDomSetting; } diff --git a/packages/roosterjs-content-model-types/lib/pluginState/CopyPastePluginState.ts b/packages/roosterjs-content-model-types/lib/pluginState/CopyPastePluginState.ts index e2df52116f3..fe75fd40c18 100644 --- a/packages/roosterjs-content-model-types/lib/pluginState/CopyPastePluginState.ts +++ b/packages/roosterjs-content-model-types/lib/pluginState/CopyPastePluginState.ts @@ -1,4 +1,3 @@ -import type { DomToModelOptionForSanitizing } from '../context/DomToModelOption'; import type { PasteTypeOrGetter } from '../parameter/PasteTypeOrGetter'; /** @@ -20,9 +19,4 @@ export interface CopyPastePluginState { * Default paste type. By default will use the normal (as-is) paste type. */ defaultPasteType?: PasteTypeOrGetter; - - /** - * Paste options for sanitizing HTML before paste - */ - pasteOptionDomToModel?: Partial; }