All files / roosterjs-content-model-plugins/lib/announce tableSelectionUtils.ts

100% Statements 34/34
100% Branches 20/20
100% Functions 2/2
100% Lines 32/32

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                1x 42x 14x   14x 13x 13x 13x 13x   13x 18x 33x 33x 31x           14x                     1x       18x 6x               48x             48x   12x 12x 12x   12x 12x 12x     12x           2x     10x 2x 8x 4x     4x      
import type { TableSelectionInfo, TableSelection } from 'roosterjs-content-model-types';
 
/**
 * @internal
 * Retrieves text content from selected table cells in a parsed table structure
 * @param tsInfo Table selection information containing the parsed table and coordinates
 * @returns Combined text content from all selected cells, separated by spaces
 */
export function retrieveStringFromParsedTable(tsInfo: TableSelectionInfo): string {
    const { parsedTable, firstCo, lastCo } = tsInfo;
    let result = '';
 
    if (lastCo) {
        const firstCol = Math.min(firstCo.col, lastCo.col);
        const lastCol = Math.max(firstCo.col, lastCo.col);
        const firstRow = Math.min(firstCo.row, lastCo.row);
        const lastRow = Math.max(firstCo.row, lastCo.row);
 
        for (let r = firstRow; r <= lastRow; r++) {
            for (let c = firstCol; c <= lastCol; c++) {
                const cell = parsedTable[r] && parsedTable[r][c];
                if (cell && typeof cell != 'string') {
                    result += ' ' + cell.innerText + ',';
                }
            }
        }
    }
 
    return result;
}
 
/**
 * @internal
 * Determines whether the table selection is expanding (selecting more) or contracting (selecting less)
 * @param prevTableSelection Previous table selection object containing firstRow, lastRow, firstColumn, and lastColumn properties
 * @param firstCo Current first coordinate of the selection (with row, col properties)
 * @param lastCo Current last coordinate of the selection (with row, col properties)
 * @returns 'selecting' if expanding selection, 'unselecting' if contracting, or null if no change
 */
export function getIsSelectingOrUnselecting(
    prevTableSelection: TableSelection | null,
    newTableSelection: TableSelection
): 'selecting' | 'unselecting' | null {
    if (!prevTableSelection) {
        return 'selecting';
    }
 
    const {
        firstRow: prevFirstRow,
        lastRow: prevLastRow,
        firstColumn: prevFirstColumn,
        lastColumn: prevLastColumn,
    } = prevTableSelection;
 
    const {
        firstRow: newFirstRow,
        lastRow: newLastRow,
        firstColumn: newFirstColumn,
        lastColumn: newLastColumn,
    } = newTableSelection;
 
    const prevRowSpan = Math.abs(prevLastRow - prevFirstRow) + 1;
    const prevColSpan = Math.abs(prevLastColumn - prevFirstColumn) + 1;
    const prevArea = prevRowSpan * prevColSpan;
 
    const newRowSpan = Math.abs(newLastRow - newFirstRow) + 1;
    const newColSpan = Math.abs(newLastColumn - newFirstColumn) + 1;
    const newArea = newRowSpan * newColSpan;
 
    // Check if selections are identical
    if (
        prevFirstRow === newFirstRow &&
        prevLastRow === newLastRow &&
        prevFirstColumn === newFirstColumn &&
        prevLastColumn === newLastColumn
    ) {
        return null;
    }
 
    if (newArea > prevArea) {
        return 'selecting';
    } else if (newArea < prevArea) {
        return 'unselecting';
    } else {
        // Same area but different positions
        return 'selecting';
    }
}