All files / roosterjs-content-model-api/lib/publicApi/table insertTable.ts

84.21% Statements 32/38
64.71% Branches 22/34
100% Functions 5/5
83.33% Lines 30/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 1021x 1x 1x                                                   1x             3x   3x   3x   3x 3x 3x 3x 1x     3x 3x   3x     3x 3x 3x         3x   3x 3x 3x 3x     3x                       8x   3x 8x 8x               8x 8x              
import { adjustTableIndentation } from '../../modelApi/common/adjustIndentation';
import { createTableStructure } from '../../modelApi/table/createTableStructure';
import {
    createContentModelDocument,
    createSelectionMarker,
    applyTableFormat,
    deleteSelection,
    mergeModel,
    normalizeTable,
    setSelection,
    MIN_ALLOWED_TABLE_CELL_WIDTH,
} from 'roosterjs-content-model-dom';
import type {
    ContentModelTable,
    ContentModelTableFormat,
    IEditor,
    TableMetadataFormat,
} from 'roosterjs-content-model-types';
 
/**
 * Insert table into editor at current selection
 * @param editor The editor instance
 * @param columns Number of columns in table, it also controls the default table cell width:
 * if columns <= 4, width = 120px; if columns <= 6, width = 100px; else width = 70px
 * @param rows Number of rows in table
 * @param tableMetadataFormat (Optional) The table format that are stored as metadata. If not passed, the default format will be applied: background color: #FFF; border color: #ABABAB
 * @param format (Optional) The table format used for style attributes
 */
export function insertTable(
    editor: IEditor,
    columns: number,
    rows: number,
    tableMetadataFormat?: Partial<TableMetadataFormat>,
    format?: ContentModelTableFormat
) {
    editor.focus();
 
    editor.formatContentModel(
        (model, context) => {
            const insertPosition = deleteSelection(model, [], context).insertPoint;
 
            Eif (insertPosition) {
                const doc = createContentModelDocument();
                const table = createTableStructure(doc, columns, rows);
                if (format) {
                    table.format = { ...format };
                }
 
                normalizeTable(table, editor.getPendingFormat() || insertPosition.marker.format);
                initCellWidth(table);
 
                adjustTableIndentation(insertPosition, table);
 
                // Assign default vertical align
                tableMetadataFormat = tableMetadataFormat || { verticalAlign: 'top' };
                applyTableFormat(table, tableMetadataFormat);
                mergeModel(model, doc, context, {
                    insertPosition,
                    mergeFormat: 'mergeAll',
                });
 
                const firstBlock = table.rows[0]?.cells[0]?.blocks[0];
 
                Eif (firstBlock?.blockType == 'Paragraph') {
                    const marker = createSelectionMarker(firstBlock.segments[0]?.format);
                    firstBlock.segments.unshift(marker);
                    setSelection(model, marker);
                }
 
                return true;
            } else {
                return false;
            }
        },
        {
            apiName: 'insertTable',
        }
    );
}
 
function initCellWidth(table: ContentModelTable) {
    const columns = Math.max(...table.rows.map(row => row.cells.length));
 
    for (let i = 0; i < columns; i++) {
        Eif (table.widths[i] === undefined) {
            table.widths[i] = getTableCellWidth(columns);
        } else if (table.widths[i] < MIN_ALLOWED_TABLE_CELL_WIDTH) {
            table.widths[i] = MIN_ALLOWED_TABLE_CELL_WIDTH;
        }
    }
}
 
function getTableCellWidth(columns: number): number {
    Eif (columns <= 4) {
        return 120;
    } else if (columns <= 6) {
        return 100;
    } else {
        return 70;
    }
}