Skip to content

Commit

Permalink
Add pasteWhiteSpaceFormatParser and integrate it into sanitizing context
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanValverdeU committed Nov 26, 2024
1 parent 480c729 commit ec8f039
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { containerSizeFormatParser } from 'roosterjs-content-model-core/lib/override/containerSizeFormatParser';
import { createDomToModelContext } from 'roosterjs-content-model-dom/lib';
import { createPasteEntityProcessor } from 'roosterjs-content-model-core/lib/override/pasteEntityProcessor';
import { createPasteGeneralProcessor } from 'roosterjs-content-model-core/lib/override/pasteGeneralProcessor';
import { DefaultSanitizingOption } from './createDomToModelContextForSanitizing';
import { getRootComputedStyleForContext } from 'roosterjs-content-model-core/lib/coreApi/createEditorContext/getRootComputedStyleForContext';
import { pasteBlockEntityParser } from 'roosterjs-content-model-core/lib/override/pasteCopyBlockEntityParser';
import { pasteDisplayFormatParser } from 'roosterjs-content-model-core/lib/override/pasteDisplayFormatParser';
import { pasteTextProcessor } from 'roosterjs-content-model-core/lib/override/pasteTextProcessor';
import type {
ContentModelSegmentFormat,
DomToModelOption,
DomToModelOptionForSanitizing,
DomToModelContext,
} from 'roosterjs-content-model-types/lib';

/**
* @internal
*/

export function createDomToModelContextForSanitizing(
document: Document,
defaultFormat?: ContentModelSegmentFormat,
defaultOption?: DomToModelOption,
additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing>
): DomToModelContext {
const sanitizingOption: DomToModelOptionForSanitizing = {
...DefaultSanitizingOption,
...additionalSanitizingOption,
};

return createDomToModelContext(
{
defaultFormat,
...getRootComputedStyleForContext(document),
experimentalFeatures: [],
},
defaultOption,
{
processorOverride: {
'#text': pasteTextProcessor,
entity: createPasteEntityProcessor(sanitizingOption),
'*': createPasteGeneralProcessor(sanitizingOption),
},
formatParserOverride: {
display: pasteDisplayFormatParser,
whiteSpace: (format, element, context, defaultStyle) => {
if (element.style.whiteSpace != 'pre') {
context.defaultFormatParsers.whiteSpace?.(
format,
element,
context,
defaultStyle
);
}
},
},
additionalFormatParsers: {
container: [containerSizeFormatParser],
entity: [pasteBlockEntityParser],
},
},
sanitizingOption
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getRootComputedStyleForContext } from '../../coreApi/createEditorContex
import { pasteBlockEntityParser } from '../../override/pasteCopyBlockEntityParser';
import { pasteDisplayFormatParser } from '../../override/pasteDisplayFormatParser';
import { pasteTextProcessor } from '../../override/pasteTextProcessor';
import { pasteWhiteSpaceFormatParser } from '../../override/pasteWhiteSpaceFormatParser';
import type {
ContentModelSegmentFormat,
DomToModelContext,
Expand Down Expand Up @@ -52,6 +53,7 @@ export function createDomToModelContextForSanitizing(
},
formatParserOverride: {
display: pasteDisplayFormatParser,
whiteSpace: pasteWhiteSpaceFormatParser,
},
additionalFormatParsers: {
container: [containerSizeFormatParser],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { convertInlineCss, retrieveCssRules } from './convertInlineCss';
import { createDomToModelContextForSanitizing } from './createDomToModelContextForSanitizing';
import { createDomToModelContextForSanitizing } from './createDomToModelContextForSanitizing.1';
import { createEmptyModel, domToContentModel, parseFormat } from 'roosterjs-content-model-dom';
import type {
ContentModelDocument,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing';
import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing.1';
import {
ChangeSource,
EmptySegmentFormat,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { FormatParser, WhiteSpaceFormat } from 'roosterjs-content-model-types/lib';

const WhiteSpacePre = 'pre';

export const pasteWhiteSpaceFormatParser: FormatParser<WhiteSpaceFormat> = (
format,
element,
context,
defaultStyle
) => {
if (element.style.whiteSpace != WhiteSpacePre) {
context.defaultFormatParsers.whiteSpace?.(format, element, context, defaultStyle);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { pasteWhiteSpaceFormatParser } from '../../lib/override/pasteWhiteSpaceFormatParser';
import { WhiteSpaceFormat } from 'roosterjs-content-model-types/lib';

describe('pasteWhiteSpaceFormatParser', () => {
let format: WhiteSpaceFormat;
let element: HTMLElement;
let context: any;
let defaultStyle: any;
let defaultParserSpy: jasmine.Spy;

beforeEach(() => {
format = {};
element = document.createElement('div');
defaultParserSpy = jasmine.createSpy();
context = {
defaultFormatParsers: {
whiteSpace: defaultParserSpy,
},
};
defaultStyle = {};
});

it('should call default whiteSpace parser when element.style.whiteSpace is not "pre"', () => {
element.style.whiteSpace = 'normal';
pasteWhiteSpaceFormatParser(format, element, context, defaultStyle);
expect(context.defaultFormatParsers.whiteSpace).toHaveBeenCalledWith(
format,
element,
context,
defaultStyle
);
});

it('should not call default whiteSpace parser when element.style.whiteSpace is "pre"', () => {
element.style.whiteSpace = 'pre';
pasteWhiteSpaceFormatParser(format, element, context, defaultStyle);
expect(context.defaultFormatParsers.whiteSpace).not.toHaveBeenCalled();
});
});

0 comments on commit ec8f039

Please sign in to comment.