All files / roosterjs-content-model-api/lib/modelApi/selection adjustSegmentSelection.ts

100% Statements 28/28
96.15% Branches 25/26
100% Functions 3/3
100% Lines 25/25

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 651x                   1x                       31x     31x   31x 44x 25x   25x 24x   24x 17x 9x 9x   8x 8x         25x 21x 42x 34x 34x   8x 8x           31x 20x     31x    
import { getSelectedParagraphs, setSelection } from 'roosterjs-content-model-dom';
import type {
    ReadonlyContentModelDocument,
    ReadonlyContentModelParagraph,
    ReadonlyContentModelSegment,
} from 'roosterjs-content-model-types';
 
/**
 * @internal
 */
export function adjustSegmentSelection(
    model: ReadonlyContentModelDocument,
    firstMatcher: (
        target: ReadonlyContentModelSegment,
        paragraph: ReadonlyContentModelParagraph
    ) => boolean,
    siblingMatcher: (
        target: ReadonlyContentModelSegment,
        ref: ReadonlyContentModelSegment,
        paragraph: ReadonlyContentModelParagraph
    ) => boolean
): boolean {
    const paragraphs = getSelectedParagraphs(model);
    let first: ReadonlyContentModelSegment | undefined;
    let last: ReadonlyContentModelSegment | undefined;
    let changed = false;
 
    paragraphs.forEach(p => {
        const index = first ? 0 : p.segments.findIndex(x => firstMatcher(x, p));
        const segments = p.segments;
 
        if (!first) {
            first = segments[index];
 
            for (let i = index; i > 0; i--) {
                if (siblingMatcher(segments[i - 1], first, p)) {
                    first = segments[i - 1];
                    changed = changed || !segments[i - 1].isSelected;
                } else {
                    changed = changed || !!segments[i - 1].isSelected;
                    break;
                }
            }
        }
 
        if (first) {
            for (let i = index; i < p.segments.length; i++) {
                if (i == index || siblingMatcher(segments[i], last || segments[index], p)) {
                    last = segments[i];
                    changed = changed || !segments[i].isSelected;
                } else {
                    changed = changed || !!segments[i].isSelected;
                    break;
                }
            }
        }
    });
 
    if (first && last) {
        setSelection(model, first, last);
    }
 
    return changed;
}