Skip to content
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 @@ -9,13 +9,19 @@ import {
normalizeTable,
setSelection,
MIN_ALLOWED_TABLE_CELL_WIDTH,
cloneModel,
iterateSelections,
createTableCell,
createTableRow,
} from 'roosterjs-content-model-dom';
import type {
ContentModelTable,
ContentModelTableFormat,
IEditor,
TableMetadataFormat,
ContentModelTableCellFormat,
ContentModelDocument,
ContentModelBlockGroup,
} from 'roosterjs-content-model-types';

/**
Expand All @@ -40,15 +46,24 @@ export function insertTable(

editor.formatContentModel(
(model, context) => {
const insertPosition = deleteSelection(model, [], context).insertPoint;
const copiedModel = cloneModel(model);
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The model is cloned on line 49 unconditionally, but the cloned model is only used on line 64 if there was a range selection (hasSelection is true). This means the clone operation is wasted when inserting a table without a prior selection. Consider moving the cloneModel call inside the conditional block on line 63 to avoid unnecessary performance overhead when there's no selected content to insert.

Copilot uses AI. Check for mistakes.
const deleteSelectionResult = deleteSelection(model, [], context);
const insertPosition = deleteSelectionResult.insertPoint;

if (insertPosition) {
const doc = createContentModelDocument();
const hasSelection = deleteSelectionResult.deleteResult == 'range';

const table = createTableStructure(doc, columns, rows, customCellFormat);

if (format) {
table.format = { ...format };
}

if (hasSelection) {
insertTableContent(copiedModel, table, columns, customCellFormat);
}

normalizeTable(table, editor.getPendingFormat() || insertPosition.marker.format);
initCellWidth(table);

Expand Down Expand Up @@ -102,3 +117,42 @@ function getTableCellWidth(columns: number): number {
return 70;
}
}

function insertTableContent(
model: ContentModelDocument,
table: ContentModelTable,
colNumber: number,
customCellFormat?: ContentModelTableCellFormat
) {
let index = 0;
let lastBlock: ContentModelBlockGroup | undefined = undefined;
iterateSelections(model, (path, _tableContext, block) => {
if (!table.rows[index]) {
const row = createTableRow();
for (let i = 0; i < colNumber; i++) {
const cell = createTableCell(
undefined /*spanLeftOrColSpan */,
undefined /*spanAboveOrRowSpan */,
undefined /* isHeader */,
customCellFormat
);
row.cells.push(cell);
}
table.rows.push(row);
}

if (path.length == 1 && block) {
table.rows[index].cells[0].blocks = [block];
index++;
} else if (
block &&
path[0].blockGroupType !== 'TableCell' &&
path[0].blockGroupType !== 'Document' &&
path[0] !== lastBlock
) {
table.rows[index].cells[0].blocks = [path[0]];
lastBlock = path[0];
index++;
Comment on lines +144 to +155
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function mutates the blocks array of table cells by directly assigning table.rows[index].cells[0].blocks = [block] or table.rows[index].cells[0].blocks = [path[0]]. This overwrites any existing blocks that may have been created by createTableCell. While this appears intentional, it would be more explicit and maintainable to clear the blocks first or add a comment explaining that the default blocks are being replaced with selected content.

Copilot uses AI. Check for mistakes.
}
});
}
Loading
Loading