Skip to content

Commit

Permalink
trusted HTML refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
juliaroldi committed Dec 5, 2024
1 parent cb829f2 commit de05dc5
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { convertInlineCss, retrieveCssRules } from './convertInlineCss';
import { createDOMCreator } from '../../utils/domCreator';
import { createDomToModelContextForSanitizing } from './createDomToModelContextForSanitizing';
import { createEmptyModel, domToContentModel, parseFormat } from 'roosterjs-content-model-dom';
import { domCreator } from '../../utils/domCreator';
import type {
ContentModelDocument,
ContentModelSegmentFormat,
Expand All @@ -22,7 +22,7 @@ export function createModelFromHtml(
trustedHTMLHandler?: TrustedHTMLHandler,
defaultSegmentFormat?: ContentModelSegmentFormat
): ContentModelDocument {
const doc = html ? domCreator(trustedHTMLHandler).htmlToDOM(html) : null;
const doc = html ? createDOMCreator(trustedHTMLHandler).htmlToDOM(html) : null;

if (doc?.body) {
const context = createDomToModelContextForSanitizing(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { coreApiMap } from '../../coreApi/coreApiMap';
import { createDarkColorHandler } from './DarkColorHandlerImpl';
import { createDOMCreator, createTrustedHTMLHandler } from '../../utils/domCreator';
import { createDOMHelper } from './DOMHelperImpl';
import { createDomToModelSettings, createModelToDomSettings } from './createEditorDefaultSettings';
import { createEditorCorePlugins } from '../../corePlugin/createEditorCorePlugins';
import { defaultTrustHtmlHandler, domCreator, isDOMCreator } from '../../utils/domCreator';
import type {
EditorEnvironment,
PluginState,
Expand All @@ -19,6 +19,9 @@ import type {
*/
export function createEditorCore(contentDiv: HTMLDivElement, options: EditorOptions): EditorCore {
const corePlugins = createEditorCorePlugins(options, contentDiv);
const domCreator = createDOMCreator(options.trustedHTMLHandler);
const trustedHTMLHandler = createTrustedHTMLHandler(domCreator);

return {
physicalRoot: contentDiv,
logicalRoot: contentDiv,
Expand All @@ -43,11 +46,8 @@ export function createEditorCore(contentDiv: HTMLDivElement, options: EditorOpti
options.knownColors,
options.generateColorKey
),
trustedHTMLHandler:
options.trustedHTMLHandler && !isDOMCreator(options.trustedHTMLHandler)
? options.trustedHTMLHandler
: defaultTrustHtmlHandler,
domCreator: domCreator(options.trustedHTMLHandler),
trustedHTMLHandler: trustedHTMLHandler,
domCreator: domCreator,
domHelper: createDOMHelper(contentDiv),
...getPluginState(corePlugins),
disposeErrorHandler: options.disposeErrorHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import type {
/**
* @internal
*/
export function domCreator(trustedHTMLHandler?: TrustedHTMLHandler): DOMCreator {
export const createTrustedHTMLHandler = (domCreator: DOMCreator): LegacyTrustedHTMLHandler => {
return (html: string) => domCreator.htmlToDOM(html).body.innerHTML;
};

/**
* @internal
*/
export function createDOMCreator(trustedHTMLHandler?: TrustedHTMLHandler): DOMCreator {
return trustedHTMLHandler && isDOMCreator(trustedHTMLHandler)
? trustedHTMLHandler
: trustedHTMLHandlerToDOMCreator(trustedHTMLHandler as LegacyTrustedHTMLHandler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import * as DarkColorHandlerImpl from '../../../lib/editor/core/DarkColorHandler
import * as domCreator from '../../../lib/utils/domCreator';
import * as DOMHelperImpl from '../../../lib/editor/core/DOMHelperImpl';
import { coreApiMap } from '../../../lib/coreApi/coreApiMap';
import { EditorCore, EditorOptions } from 'roosterjs-content-model-types';
import { createEditorCore, getDarkColorFallback } from '../../../lib/editor/core/createEditorCore';
import { DOMCreator, EditorCore, EditorOptions } from 'roosterjs-content-model-types';

describe('createEditorCore', () => {
function createMockedPlugin(stateName: string): any {
Expand Down Expand Up @@ -38,7 +38,10 @@ describe('createEditorCore', () => {
const mockedDomToModelSettings = 'DOMTOMODEL' as any;
const mockedModelToDomSettings = 'MODELTODOM' as any;
const mockedDOMHelper = 'DOMHELPER' as any;
const mockedHtmlToDOM = 'HTMLTODOM' as any;
const mockedDOMCreator: DOMCreator = {
htmlToDOM: mockedDOMHelper,
};
const mockedTrustHtmlHandler = 'TRUSTED' as any;

beforeEach(() => {
spyOn(createEditorCorePlugins, 'createEditorCorePlugins').and.returnValue(mockedPlugins);
Expand All @@ -52,7 +55,8 @@ describe('createEditorCore', () => {
mockedModelToDomSettings
);
spyOn(DOMHelperImpl, 'createDOMHelper').and.returnValue(mockedDOMHelper);
spyOn(domCreator, 'domCreator').and.returnValue(mockedHtmlToDOM);
spyOn(domCreator, 'createDOMCreator').and.returnValue(mockedDOMCreator);
spyOn(domCreator, 'createTrustedHTMLHandler').and.returnValue(mockedTrustHtmlHandler);
});

function runTest(
Expand Down Expand Up @@ -87,8 +91,8 @@ describe('createEditorCore', () => {
modelToDomSettings: mockedModelToDomSettings,
},
darkColorHandler: mockedDarkColorHandler,
trustedHTMLHandler: domCreator.defaultTrustHtmlHandler,
domCreator: mockedHtmlToDOM,
trustedHTMLHandler: mockedTrustHtmlHandler,
domCreator: mockedDOMCreator,
cache: 'cache' as any,
format: 'format' as any,
copyPaste: 'copyPaste' as any,
Expand Down Expand Up @@ -146,7 +150,7 @@ describe('createEditorCore', () => {
const mockedPlugin1 = 'P1' as any;
const mockedPlugin2 = 'P2' as any;
const mockedGetDarkColor = 'DARK' as any;
const mockedTrustHtmlHandler = 'TRUST' as any;
const mockedTrustHtmlHandler = 'OPTIONAL TRUSTED' as any;
const mockedDisposeErrorHandler = 'DISPOSE' as any;
const mockedGenerateColorKey = 'KEY' as any;
const mockedKnownColors = 'COLORS' as any;
Expand All @@ -164,6 +168,8 @@ describe('createEditorCore', () => {
onFixUpModel: mockedOnFixUpModel,
} as any;

spyOn(domCreator, 'createTrustedHTMLHandler').and.returnValue(mockedTrustHtmlHandler);

runTest(mockedDiv, mockedOptions, {
physicalRoot: mockedDiv,
logicalRoot: mockedDiv,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { domCreator, isDOMCreator } from '../../lib/utils/domCreator';
import { createDOMCreator, isDOMCreator } from '../../lib/utils/domCreator';

describe('domCreator', () => {
it('isDOMCreator - True', () => {
Expand All @@ -13,26 +13,26 @@ describe('domCreator', () => {
expect(isDOMCreator(trustedHTMLHandler)).toBe(false);
});

it('domCreator - isDOMCreator', () => {
it('createDOMCreator - isDOMCreator', () => {
const trustedHTMLHandler = {
htmlToDOM: (html: string) => new DOMParser().parseFromString(html, 'text/html'),
};
const result = domCreator(trustedHTMLHandler);
const result = createDOMCreator(trustedHTMLHandler);
expect(result).toEqual(trustedHTMLHandler);
});

it('domCreator - undefined', () => {
it('createDOMCreator - undefined', () => {
const doc = document.implementation.createHTMLDocument();
doc.body.appendChild(document.createTextNode('test'));
const result = domCreator(undefined).htmlToDOM('test');
const result = createDOMCreator(undefined).htmlToDOM('test');
expect(result.lastChild).toEqual(doc.lastChild);
});

it('domCreator - trustedHTML', () => {
it('createDOMCreator - trustedHTML', () => {
const doc = document.implementation.createHTMLDocument();
doc.body.appendChild(document.createTextNode('test trusted'));
const trustedHTMLHandler = (html: string) => html + ' trusted';
const result = domCreator(trustedHTMLHandler).htmlToDOM('test');
const result = createDOMCreator(trustedHTMLHandler).htmlToDOM('test');
expect(result.lastChild).toEqual(doc.lastChild);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* @deprecated Use DOMCreator instead
* A handler type to convert HTML string to a trust HTML string
*/
export type LegacyTrustedHTMLHandler = (html: string) => string;
Expand Down

0 comments on commit de05dc5

Please sign in to comment.