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

100% Statements 16/16
100% Branches 21/21
100% Functions 4/4
100% Lines 15/15

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 631x                         1x 183x   183x 325x   325x 49x 276x 253x   23x 23x 23x                 93x                       26x                         24x    
import { areSameFormats } from '../../domToModel/utils/areSameFormats';
import type {
    ContentModelText,
    ReadonlyContentModelCode,
    ReadonlyContentModelLink,
    ReadonlyContentModelSegment,
    ShallowMutableContentModelParagraph,
} from 'roosterjs-content-model-types';
 
/**
 * Find continuous text segments that have the same format and decorators, merge them, So we can reduce total count of segments
 * @param block The parent paragraph to check.
 */
export function mergeTextSegments(block: ShallowMutableContentModelParagraph) {
    let lastText: ContentModelText | null = null;
 
    for (let i = 0; i < block.segments.length; i++) {
        const segment = block.segments[i];
 
        if (segment.segmentType != 'Text') {
            lastText = null;
        } else if (!lastText || !segmentsWithSameFormat(lastText, segment)) {
            lastText = segment;
        } else {
            lastText.text += segment.text;
            block.segments.splice(i, 1);
            i--;
        }
    }
}
 
function segmentsWithSameFormat(
    seg1: ReadonlyContentModelSegment,
    seg2: ReadonlyContentModelSegment
) {
    return (
        !!seg1.isSelected == !!seg2.isSelected &&
        areSameFormats(seg1.format, seg2.format) &&
        areSameLinks(seg1.link, seg2.link) &&
        areSameCodes(seg1.code, seg2.code)
    );
}
 
function areSameLinks(
    link1: ReadonlyContentModelLink | undefined,
    link2: ReadonlyContentModelLink | undefined
) {
    return (
        (!link1 && !link2) ||
        (link1 &&
            link2 &&
            areSameFormats(link1.format, link2.format) &&
            areSameFormats(link1.dataset, link2.dataset))
    );
}
 
function areSameCodes(
    code1: ReadonlyContentModelCode | undefined,
    code2: ReadonlyContentModelCode | undefined
) {
    return (!code1 && !code2) || (code1 && code2 && areSameFormats(code1.format, code2.format));
}