All files / roosterjs-content-model-dom/lib/modelApi/common isEmpty.ts

93.1% Statements 27/29
92.86% Branches 26/28
100% Functions 8/8
92.86% Lines 26/28

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 102                  1x 4140x   3102x     190x     838x     5x     6x             1x 920x     97x     810x         13x                   1x       2045x   1522x     523x               1x     116x 48x 68x 62x 6x 6x                 6x           68x           116x    
import type {
    ReadonlyContentModelBlock,
    ReadonlyContentModelBlockGroup,
    ReadonlyContentModelSegment,
} from 'roosterjs-content-model-types';
 
/**
 * @internal
 */
export function isBlockEmpty(block: ReadonlyContentModelBlock): boolean {
    switch (block.blockType) {
        case 'Paragraph':
            return block.segments.length == 0;
 
        case 'Table':
            return block.rows.every(row => row.cells.length == 0);
 
        case 'BlockGroup':
            return isBlockGroupEmpty(block);
 
        case 'Entity':
            return false;
 
        default:
            return false;
    }
}
 
/**
 * @internal
 */
export function isBlockGroupEmpty(group: ReadonlyContentModelBlockGroup): boolean {
    switch (group.blockGroupType) {
        case 'FormatContainer':
            // Format Container of DIV is a container for style, so we always treat it as not empty
            return group.tagName == 'div' ? false : group.blocks.every(isBlockEmpty);
 
        case 'ListItem':
            return group.blocks.every(isBlockEmpty);
 
        case 'Document':
        case 'General':
        case 'TableCell':
            return false;
 
        default:
            return true;
    }
}
 
/**
 * @internal
 */
export function isSegmentEmpty(
    segment: ReadonlyContentModelSegment,
    treatAnchorAsNotEmpty?: boolean
): boolean {
    switch (segment.segmentType) {
        case 'Text':
            return !segment.text && (!treatAnchorAsNotEmpty || !segment.link?.format.name);
 
        default:
            return false;
    }
}
 
/**
 * Get whether the model is empty.
 * @returns true if the model is empty.
 */
export function isEmpty(
    model: ReadonlyContentModelBlock | ReadonlyContentModelBlockGroup | ReadonlyContentModelSegment
): boolean {
    if (isBlockGroup(model)) {
        return isBlockGroupEmpty(model);
    } else if (isBlock(model)) {
        return isBlockEmpty(model);
    } else Eif (isSegment(model)) {
        return isSegmentEmpty(model);
    }
 
    return false;
}
 
function isSegment(
    model: ReadonlyContentModelBlock | ReadonlyContentModelBlockGroup | ReadonlyContentModelSegment
): model is ReadonlyContentModelSegment {
    return typeof (<ReadonlyContentModelSegment>model).segmentType === 'string';
}
 
function isBlock(
    model: ReadonlyContentModelBlock | ReadonlyContentModelBlockGroup | ReadonlyContentModelSegment
): model is ReadonlyContentModelBlock {
    return typeof (<ReadonlyContentModelBlock>model).blockType === 'string';
}
 
function isBlockGroup(
    model: ReadonlyContentModelBlock | ReadonlyContentModelBlockGroup | ReadonlyContentModelSegment
): model is ReadonlyContentModelBlockGroup {
    return typeof (<ReadonlyContentModelBlockGroup>model).blockGroupType === 'string';
}