Skip to content

Commit

Permalink
Merge branch 'u/bvalverde/pocForPasteEvent' of https://github.com/mic…
Browse files Browse the repository at this point in the history
…rosoft/roosterjs into u/bvalverde/pocForWordProcessing
  • Loading branch information
BryanValverdeU committed Apr 17, 2023
2 parents fab7cb2 + db38f17 commit 89e8e73
Show file tree
Hide file tree
Showing 46 changed files with 729 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { EditorContext } from '../publicTypes/context/EditorContext';
import { normalizeContentModel } from '../modelApi/common/normalizeContentModel';
import { parseFormat } from './utils/parseFormat';
import { rootDirectionFormatHandler } from '../formatHandlers/root/rootDirectionFormatHandler';
import { safeInstanceOf } from 'roosterjs-editor-dom';
import { zoomScaleFormatHandler } from '../formatHandlers/root/zoomScaleFormatHandler';

/**
Expand All @@ -17,27 +18,31 @@ import { zoomScaleFormatHandler } from '../formatHandlers/root/zoomScaleFormatHa
* @returns A ContentModelDocument object that contains all the models created from the give root element
*/
export default function domToContentModel(
root: HTMLElement,
root: HTMLElement | DocumentFragment,
editorContext: EditorContext,
option: DomToModelOption
): ContentModelDocument {
const model = createContentModelDocument(editorContext.defaultFormat);
const context = createDomToModelContext(editorContext, option);

// For root element, use computed style as initial value of segment formats
parseFormat(root, [computedSegmentFormatHandler.parse], context.segmentFormat, context);
if (safeInstanceOf(root, 'DocumentFragment')) {
context.elementProcessors.child(model, root, context);
} else {
// For root element, use computed style as initial value of segment formats
parseFormat(root, [computedSegmentFormatHandler.parse], context.segmentFormat, context);

// Need to calculate direction (ltr or rtl), use it as initial value
parseFormat(root, [rootDirectionFormatHandler.parse], context.blockFormat, context);
// Need to calculate direction (ltr or rtl), use it as initial value
parseFormat(root, [rootDirectionFormatHandler.parse], context.blockFormat, context);

// Need to calculate zoom scale value from root element, use this value to calculate sizes for elements
parseFormat(root, [zoomScaleFormatHandler.parse], context.zoomScaleFormat, context);
// Need to calculate zoom scale value from root element, use this value to calculate sizes for elements
parseFormat(root, [zoomScaleFormatHandler.parse], context.zoomScaleFormat, context);

const processor = option.includeRoot
? context.elementProcessors.element
: context.elementProcessors.child;
const processor = option.includeRoot
? context.elementProcessors.element
: context.elementProcessors.child;

processor(model, root, context);
processor(model, root, context);
}

normalizeContentModel(model);

Expand Down
23 changes: 15 additions & 8 deletions packages/roosterjs-content-model/lib/editor/ContentModelEditor.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ClipboardData, GetContentMode } from 'roosterjs-editor-types';
import { ChangeSource, ClipboardData, GetContentMode } from 'roosterjs-editor-types';
import { ContentModelDocument } from '../publicTypes/group/ContentModelDocument';
import { ContentModelEditorCore } from '../publicTypes/ContentModelEditorCore';
import { createContentModelEditorCore } from './createContentModelEditorCore';
import { EditorBase } from 'roosterjs-editor-core';
import { formatWithContentModel } from '../publicApi/utils/formatWithContentModel';
import { mergeModel } from '../modelApi/common/mergeModel';
import { Position } from 'roosterjs-editor-dom';
import {
Expand Down Expand Up @@ -90,7 +91,7 @@ export default class ContentModelEditor

const range = this.getSelectionRange();
const pos = range && Position.getStart(range);
const model = core.api.createPasteModel(
const pasteModel = core.api.createPasteModel(
core,
clipboardData,
pos,
Expand All @@ -99,12 +100,18 @@ export default class ContentModelEditor
pasteAsImage
);

if (model) {
const currentModel = this.createContentModel();

mergeModel(currentModel, model);

this.setContentModel(currentModel);
if (pasteModel) {
formatWithContentModel(
this,
'Paste',
model => {
mergeModel(model, pasteModel);
return true;
},
{
changeSource: ChangeSource.Paste,
}
);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import ContentModelBeforePasteEvent from '../../publicTypes/event/ContentModelBeforePasteEvent';
import domToContentModel from '../../domToModel/domToContentModel';
import { ClipboardData, EditorCore, NodePosition, PluginEventType } from 'roosterjs-editor-types';
import { ContentModelEditorCore, CreatePasteModel } from '../../publicTypes/ContentModelEditorCore';
import {
createDefaultHtmlSanitizerOptions,
createFragmentFromClipboardData,
wrap,
} from 'roosterjs-editor-dom';
import { ClipboardData, EditorCore, PluginEventType, NodePosition } from 'roosterjs-editor-types';

export const createPasteModel: CreatePasteModel = (
core: ContentModelEditorCore,
Expand All @@ -16,10 +15,6 @@ export const createPasteModel: CreatePasteModel = (
applyCurrentStyle: boolean,
pasteAsImage: boolean = false
) => {
if (!clipboardData) {
return null;
}

// Step 1: Prepare BeforePasteEvent object
const event = createBeforePasteEvent(core, clipboardData);

Expand All @@ -33,7 +28,7 @@ export const createPasteModel: CreatePasteModel = (
event
);

return domToContentModel(wrap(fragment, 'span'), core.api.createEditorContext(core), {
return domToContentModel(fragment, core.api.createEditorContext(core), {
processorOverride: {
element: (group, element, context) => {
const wasHandled =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function promoteToContentModelEditorCore(
(cmCore.api.createEditorContext = createEditorContext);
cmCore.api.createContentModel = createContentModel;
cmCore.api.setContentModel = setContentModel;
cmCore.api.createPasteModel = createPasteModel;

if (reuseModel) {
// Only use Content Model shadow edit when reuse model is enabled because it relies on cached model for the original model
Expand All @@ -58,7 +59,7 @@ export function promoteToContentModelEditorCore(
cmCore.originalApi.createEditorContext = createEditorContext;
cmCore.originalApi.createContentModel = createContentModel;
cmCore.originalApi.setContentModel = setContentModel;
cmCore.api.createPasteModel = createPasteModel;
cmCore.originalApi.createPasteModel = createPasteModel;
}

function getDefaultSegmentFormat(core: EditorCore): ContentModelSegmentFormat {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import domToContentModel from '../../domToModel/domToContentModel';
import { ContentModelDocument } from '../../publicTypes/group/ContentModelDocument';
import { mergeModel } from '../../modelApi/common/mergeModel';
import { safeInstanceOf, wrap } from 'roosterjs-editor-dom';
import { safeInstanceOf } from 'roosterjs-editor-dom';
import { setSelection } from '../../modelApi/selection/setSelection';

/**
Expand All @@ -12,11 +12,7 @@ export function insertContent(
htmlContent: DocumentFragment | HTMLElement | ContentModelDocument,
isFromDarkMode?: boolean
) {
if (safeInstanceOf(htmlContent, 'DocumentFragment')) {
htmlContent = wrap(htmlContent, 'span');
}

if (safeInstanceOf(htmlContent, 'HTMLElement')) {
if (safeInstanceOf(htmlContent, 'Node')) {
htmlContent = domToContentModel(
htmlContent,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export function createModelToDomContext(
editorContext?: EditorContext,
options?: ModelToDomOption
): ModelToDomContext {
options = options || {};

return {
...(editorContext || {
isDarkMode: false,
Expand All @@ -34,19 +36,20 @@ export function createModelToDomContext(
},
implicitFormat: {},
formatAppliers: getFormatAppliers(
options?.formatApplierOverride,
options?.additionalFormatAppliers
options.formatApplierOverride,
options.additionalFormatAppliers
),
modelHandlers: {
...defaultContentModelHandlers,
...(options?.modelHandlerOverride || {}),
...(options.modelHandlerOverride || {}),
},
defaultImplicitFormatMap: {
...defaultImplicitFormatMap,
...(options?.defaultImplicitFormatOverride || {}),
...(options.defaultImplicitFormatOverride || {}),
},

defaultModelHandlers: defaultContentModelHandlers,
defaultFormatAppliers: defaultFormatAppliers,
onNodeCreated: options.onNodeCreated,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export const handleBr: ContentModelHandler<ContentModelBr> = (
applyFormat(element, context.formatAppliers.segment, segment.format, context);

context.modelHandlers.segmentDecorator(doc, br, segment, context);
context.onNodeCreated?.(segment, br);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ export const handleDivider: ContentModelBlockHandler<ContentModelDivider> = (
context: ModelToDomContext,
refNode: Node | null
) => {
const element = divider.cachedElement;
let element = divider.cachedElement;

if (element) {
refNode = reuseCachedElement(parent, element, refNode);
} else {
const element = doc.createElement(divider.tagName);
element = doc.createElement(divider.tagName);

divider.cachedElement = element;
parent.insertBefore(element, refNode);

applyFormat(element, context.formatAppliers.divider, divider.format, context);
}

context.onNodeCreated?.(divider, element);

return refNode;
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,7 @@ export const handleEntity: ContentModelBlockHandler<ContentModelEntity> = (
context.regularSelection.current.segment = after;
}

context.onNodeCreated?.(entityModel, wrapper);

return refNode;
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,21 @@ export const handleFormatContainer: ContentModelBlockHandler<ContentModelFormatC

context.modelHandlers.blockGroupChildren(doc, element, container, context);
} else if (!isBlockGroupEmpty(container)) {
const blockQuote = doc.createElement(container.tagName);
element = doc.createElement(container.tagName);

container.cachedElement = blockQuote;
parent.insertBefore(blockQuote, refNode);
container.cachedElement = element;
parent.insertBefore(element, refNode);

stackFormat(context, container.tagName, () => {
applyFormat(blockQuote, context.formatAppliers.block, container.format, context);
applyFormat(
blockQuote,
context.formatAppliers.segmentOnBlock,
container.format,
context
);
applyFormat(element!, context.formatAppliers.block, container.format, context);
applyFormat(element!, context.formatAppliers.segmentOnBlock, container.format, context);
});

context.modelHandlers.blockGroupChildren(doc, blockQuote, container, context);
context.modelHandlers.blockGroupChildren(doc, element, container, context);
}

if (element) {
context.onNodeCreated?.(container, element);
}

return refNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,7 @@ export const handleGeneralModel: ContentModelBlockHandler<ContentModelGeneralBlo

context.modelHandlers.blockGroupChildren(doc, element, group, context);

context.onNodeCreated?.(group, element);

return refNode;
};
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ export const handleImage: ContentModelHandler<ContentModelImage> = (
image: img,
};
}

context.onNodeCreated?.(imageModel, img);
};
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export const handleList: ContentModelBlockHandler<ContentModelListItem> = (
handleMetadata(level, newList, context);

nodeStack.push({ node: newList, ...level });

context.onNodeCreated?.(level, newList);
}

return refNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ export const handleListItem: ContentModelBlockHandler<ContentModelListItem> = (
unwrap(li);
}

context.onNodeCreated?.(listItem, li);

return refNode;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export const handleParagraph: ContentModelBlockHandler<ContentModelParagraph> =
context: ModelToDomContext,
refNode: Node | null
) => {
const element = paragraph.cachedElement;
let container = paragraph.cachedElement;

if (element) {
refNode = reuseCachedElement(parent, element, refNode);
if (container) {
refNode = reuseCachedElement(parent, container, refNode);
} else {
stackFormat(context, paragraph.decorator?.tagName || null, () => {
const needParagraphWrapper =
Expand All @@ -30,7 +30,7 @@ export const handleParagraph: ContentModelBlockHandler<ContentModelParagraph> =
(getObjectKeys(paragraph.format).length > 0 &&
paragraph.segments.some(segment => segment.segmentType != 'SelectionMarker'));

let container = doc.createElement(paragraph.decorator?.tagName || DefaultParagraphTag);
container = doc.createElement(paragraph.decorator?.tagName || DefaultParagraphTag);

parent.insertBefore(container, refNode);

Expand All @@ -53,7 +53,7 @@ export const handleParagraph: ContentModelBlockHandler<ContentModelParagraph> =
};

paragraph.segments.forEach(segment => {
context.modelHandlers.segment(doc, container, segment, context);
context.modelHandlers.segment(doc, container!, segment, context);
});

if (needParagraphWrapper) {
Expand All @@ -64,5 +64,9 @@ export const handleParagraph: ContentModelBlockHandler<ContentModelParagraph> =
});
}

if (container) {
context.onNodeCreated?.(paragraph, container);
}

return refNode;
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const handleSegmentDecorator: ContentModelHandler<ContentModelSegment> =

applyFormat(a, context.formatAppliers.link, link.format, context);
applyFormat(a, context.formatAppliers.dataset, link.dataset, context);

context.onNodeCreated?.(link, a);
});
}

Expand All @@ -29,6 +31,8 @@ export const handleSegmentDecorator: ContentModelHandler<ContentModelSegment> =
const codeNode = wrap(parent, 'code');

applyFormat(codeNode, context.formatAppliers.code, code.format, context);

context.onNodeCreated?.(code, codeNode);
});
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export const handleTable: ContentModelBlockHandler<ContentModelTable> = (

applyFormat(tableNode, context.formatAppliers.tableBorder, table.format, context);

context.onNodeCreated?.(table, tableNode);

const tbody = doc.createElement('tbody');
tableNode.appendChild(tbody);

Expand Down Expand Up @@ -106,6 +108,8 @@ export const handleTable: ContentModelBlockHandler<ContentModelTable> = (
}

context.modelHandlers.blockGroupChildren(doc, td, cell, context);

context.onNodeCreated?.(cell, td);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ export const handleText: ContentModelHandler<ContentModelText> = (
applyFormat(element, context.formatAppliers.segment, segment.format, context);

context.modelHandlers.segmentDecorator(doc, txt, segment, context);

context.onNodeCreated?.(segment, txt);
};
Loading

0 comments on commit 89e8e73

Please sign in to comment.