Skip to content

Commit

Permalink
Fix #2160 (#2167)
Browse files Browse the repository at this point in the history
* Fix #2160

* fix build
  • Loading branch information
JiuqingSong authored Oct 27, 2023
1 parent 4123318 commit 95bdb1c
Show file tree
Hide file tree
Showing 5 changed files with 1,249 additions and 967 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,19 @@ export interface MergeModelOption {

/**
* @internal
* Merge source model into target mode
* @param target Target Content Model that will merge content into
* @param source Source Content Model will be merged to target model
* @param context Format context. When call this function inside formatWithContentModel, provide this context so that formatWithContentModel will do extra handling to the result
* @param options More options, see MergeModelOption
* @returns Insert point after merge, or null if there is no insert point
*/
export function mergeModel(
target: ContentModelDocument,
source: ContentModelDocument,
context?: FormatWithContentModelContext,
options?: MergeModelOption
) {
): InsertPoint | null {
const insertPosition =
options?.insertPosition ?? deleteSelection(target, [], context).insertPoint;

Expand Down Expand Up @@ -119,6 +125,8 @@ export function mergeModel(
}

normalizeContentModel(target);

return insertPosition;
}

function mergeParagraph(
Expand Down Expand Up @@ -186,7 +194,7 @@ function mergeTable(
newTable: ContentModelTable,
source: ContentModelDocument
) {
const { tableContext } = markerPosition;
const { tableContext, marker } = markerPosition;

if (tableContext && source.blocks.length == 1 && source.blocks[0] == newTable) {
const { table, colIndex, rowIndex } = tableContext;
Expand Down Expand Up @@ -226,10 +234,19 @@ function mergeTable(
}
}

const oldCell = table.rows[rowIndex + i].cells[colIndex + j];
table.rows[rowIndex + i].cells[colIndex + j] = newCell;

if (i == 0 && j == 0) {
addSegment(newCell, createSelectionMarker());
const newMarker = createSelectionMarker(marker.format);
const newPara = addSegment(newCell, newMarker);

if (markerPosition.path[0] == oldCell) {
// Update insert point to match the change result
markerPosition.path[0] = newCell;
markerPosition.marker = newMarker;
markerPosition.paragraph = newPara;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ChangeSource } from '../../publicTypes/event/ContentModelContentChanged
import { formatWithContentModel } from './formatWithContentModel';
import { GetContentMode, PasteType as OldPasteType, PluginEventType } from 'roosterjs-editor-types';
import { mergeModel } from '../../modelApi/common/mergeModel';
import { setPendingFormat } from '../../modelApi/format/pendingFormat';
import type { InsertPoint } from '../../publicTypes/selection/InsertPoint';
import type {
ContentModelDocument,
ContentModelSegmentFormat,
Expand Down Expand Up @@ -35,6 +37,19 @@ const PasteTypeMap: Record<PasteType, OldPasteType> = {
mergeFormat: OldPasteType.MergeFormat,
normal: OldPasteType.Normal,
};
const EmptySegmentFormat: Required<ContentModelSegmentFormat> = {
backgroundColor: '',
fontFamily: '',
fontSize: '',
fontWeight: '',
italic: false,
letterSpacing: '',
lineHeight: '',
strikethrough: false,
superOrSubScriptSequence: '',
textColor: '',
underline: false,
};

/**
* Paste into editor using a clipboardData object
Expand All @@ -55,6 +70,7 @@ export default function paste(
}

editor.focus();
let originalFormat: ContentModelSegmentFormat | undefined;

formatWithContentModel(
editor,
Expand All @@ -81,14 +97,18 @@ export default function paste(
createDomToModelContext(undefined /*editorContext*/, domToModelOption)
);

mergePasteContent(
const insertPoint = mergePasteContent(
model,
context,
pasteModel,
pasteType == 'mergeFormat',
customizedMerge
);

if (insertPoint) {
originalFormat = insertPoint.marker.format;
}

return true;
},

Expand All @@ -97,6 +117,17 @@ export default function paste(
getChangeData: () => clipboardData,
}
);

const pos = editor.getFocusedPosition();

if (originalFormat && pos) {
setPendingFormat(
editor,
{ ...EmptySegmentFormat, ...originalFormat }, // Use empty format as initial value to clear any other format inherits from pasted content
pos.node,
pos.offset
);
}
}

/**
Expand All @@ -110,16 +141,14 @@ export function mergePasteContent(
applyCurrentFormat: boolean,
customizedMerge:
| undefined
| ((source: ContentModelDocument, target: ContentModelDocument) => void)
) {
if (customizedMerge) {
customizedMerge(model, pasteModel);
} else {
mergeModel(model, pasteModel, context, {
mergeFormat: applyCurrentFormat ? 'keepSourceEmphasisFormat' : 'none',
mergeTable: shouldMergeTable(pasteModel),
});
}
| ((source: ContentModelDocument, target: ContentModelDocument) => InsertPoint | null)
): InsertPoint | null {
return customizedMerge
? customizedMerge(model, pasteModel)
: mergeModel(model, pasteModel, context, {
mergeFormat: applyCurrentFormat ? 'keepSourceEmphasisFormat' : 'none',
mergeTable: shouldMergeTable(pasteModel),
});
}

function shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { InsertPoint } from '../selection/InsertPoint';
import type { ContentModelDocument, DomToModelOption } from 'roosterjs-content-model-types';
import type {
BeforePasteEvent,
Expand All @@ -16,7 +17,10 @@ export interface ContentModelBeforePasteEventData extends BeforePasteEventData {
/**
* customizedMerge Customized merge function to use when merging the paste fragment into the editor
*/
customizedMerge?: (target: ContentModelDocument, source: ContentModelDocument) => void;
customizedMerge?: (
target: ContentModelDocument,
source: ContentModelDocument
) => InsertPoint | null;
}

/**
Expand Down
Loading

0 comments on commit 95bdb1c

Please sign in to comment.