Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

U/bvalverde/add paste dom to model options #2904

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@ export function generatePasteOptionFromPlugins(
htmlFromClipboard: HtmlFromClipboard,
pasteType: PasteType
): BeforePasteEvent {
const domToModelOption: DomToModelOptionForSanitizing = {
additionalAllowedTags: [],
additionalDisallowedTags: [],
additionalFormatParsers: {},
formatParserOverride: {},
processorOverride: {},
styleSanitizers: {},
attributeSanitizers: {},
};

const event: BeforePasteEvent = {
eventType: 'beforePaste',
clipboardData,
Expand All @@ -35,11 +25,24 @@ export function generatePasteOptionFromPlugins(
htmlAfter: htmlFromClipboard.htmlAfter ?? '',
htmlAttributes: htmlFromClipboard.metadata,
pasteType: pasteType,
domToModelOption,
domToModelOption: createDomToModelOption(editor),
containsBlockElements: !!htmlFromClipboard.containsBlockElements,
};

return pasteType == 'asPlainText'
? event
: editor.triggerEvent('beforePaste', event, true /* broadcast */);
}
function createDomToModelOption(editor: IEditor): DomToModelOptionForSanitizing {
const pasteDomToModel = editor.getEnvironment().domToModelSettings.paste;
const emptyDomToModelOption: Readonly<DomToModelOptionForSanitizing> = {
additionalAllowedTags: [],
additionalDisallowedTags: [],
additionalFormatParsers: {},
formatParserOverride: {},
processorOverride: {},
styleSanitizers: {},
attributeSanitizers: {},
};
return Object.assign({}, emptyDomToModelOption, pasteDomToModel);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,27 @@ import {
listLevelMetadataApplier,
} from '../../override/listMetadataApplier';
import type {
ContentModelSettings,
DomToModelOption,
DomToModelSettings,
ModelToDomOption,
ModelToDomSettings,
EditorOptions,
ModelToDomSetting,
DomToModelSetting,
} from 'roosterjs-content-model-types';

/**
* @internal
* Create default DOM to Content Model conversion settings for an editor
* @param options The editor options
*/
export function createDomToModelSettings(
options: EditorOptions
): ContentModelSettings<DomToModelOption, DomToModelSettings> {
export function createDomToModelSettings(options: EditorOptions): DomToModelSetting {
const builtIn: DomToModelOption = {};
const customized: DomToModelOption = options.defaultDomToModelOptions ?? {};

return {
builtIn,
customized,
calculated: createDomToModelConfig([builtIn, customized]),
paste: options.pasteOptionDomToModel ?? {},
};
}

Expand All @@ -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<ModelToDomOption, ModelToDomSettings> {
export function createModelToDomSettings(options: EditorOptions): ModelToDomSetting {
const builtIn: ModelToDomOption = {
metadataAppliers: {
listItem: listItemMetadataApplier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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([
{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Colors, ColorTransformFunction } from '../context/DarkColorHandler
import type { EditorPlugin } from './EditorPlugin';
import type { ContentModelSegmentFormat } from '../contentModel/format/ContentModelSegmentFormat';
import type { CoreApiMap } from './EditorCore';
import type { DomToModelOption } from '../context/DomToModelOption';
import type { DomToModelOption, DomToModelOptionForSanitizing } from '../context/DomToModelOption';
import type { ModelToDomOption } from '../context/ModelToDomOption';
import type {
ContentModelDocument,
Expand Down Expand Up @@ -82,6 +82,11 @@ export interface ContentModelOptions {
* @deprecated
*/
disableCache?: boolean;

/**
* Paste options for sanitizing HTML before paste
*/
pasteOptionDomToModel?: Partial<DomToModelOptionForSanitizing>;
}

/**
Expand Down
7 changes: 6 additions & 1 deletion packages/roosterjs-content-model-types/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,26 @@ export interface ContentModelSettings<OptionType, ConfigType> {
* 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<DomToModelOption, DomToModelSettings>;

/**
* Settings used by Content Model to DOM conversion
*/
export type ModelToDomSetting = Omit<
ContentModelSettings<ModelToDomOption, ModelToDomSettings>,
'paste'
>;

/**
* Current running environment
*/
Expand Down Expand Up @@ -52,10 +70,10 @@ export interface EditorEnvironment {
/**
* Settings used by DOM to Content Model conversion
*/
readonly domToModelSettings: ContentModelSettings<DomToModelOption, DomToModelSettings>;
readonly domToModelSettings: DomToModelSetting;

/**
* Settings used by Content Model to DOM conversion
*/
readonly modelToDomSettings: ContentModelSettings<ModelToDomOption, ModelToDomSettings>;
readonly modelToDomSettings: ModelToDomSetting;
}
Loading