All files / roosterjs-content-model-plugins/lib/markdown/utils setFormat.ts

100% Statements 20/20
83.33% Branches 15/18
100% Functions 3/3
100% Lines 20/20

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 781x                         1x           11x     11x 9x 9x 9x           9x 9x 9x       9x       7x             7x 7x       7x 2x         7x 7x       4x                     9x    
import {
    formatTextSegmentBeforeSelectionMarker,
    splitTextSegment,
} from 'roosterjs-content-model-api';
import type {
    ContentModelCodeFormat,
    ContentModelSegmentFormat,
    IEditor,
} from 'roosterjs-content-model-types';
 
/**
 * @internal
 */
export function setFormat(
    editor: IEditor,
    character: string,
    format: ContentModelSegmentFormat,
    codeFormat?: ContentModelCodeFormat
) {
    formatTextSegmentBeforeSelectionMarker(
        editor,
        (_model, previousSegment, paragraph, markerFormat, context) => {
            if (previousSegment.text[previousSegment.text.length - 1] == character) {
                const textSegment = previousSegment.text;
                const textBeforeMarker = textSegment.slice(0, -1);
                context.newPendingFormat = {
                    ...markerFormat,
                    strikethrough: !!markerFormat.strikethrough,
                    italic: !!markerFormat.italic,
                    fontWeight: markerFormat?.fontWeight ? 'bold' : undefined,
                };
                Eif (textBeforeMarker.indexOf(character) > -1) {
                    const lastCharIndex = textSegment.length;
                    const firstCharIndex = textSegment
                        .substring(0, lastCharIndex - 1)
                        .lastIndexOf(character);
 
                    if (
                        hasSpaceBeforeFirstCharacter(textSegment, firstCharIndex) &&
                        lastCharIndex - firstCharIndex > 2
                    ) {
                        const formattedText = splitTextSegment(
                            previousSegment,
                            paragraph,
                            firstCharIndex,
                            lastCharIndex
                        );
 
                        formattedText.text = formattedText.text.replace(character, '').slice(0, -1);
                        formattedText.format = {
                            ...formattedText.format,
                            ...format,
                        };
                        if (codeFormat) {
                            formattedText.code = {
                                format: codeFormat,
                            };
                        }
 
                        context.canUndoByBackspace = true;
                        return true;
                    }
                }
            }
            return false;
        }
    );
}
 
/**
 * The markdown should not be trigger inside a word, then check if exist a space before the trigger character
 * Should trigger markdown example: _one two_
 * Should not trigger markdown example: one_two_
 */
function hasSpaceBeforeFirstCharacter(text: string, index: number) {
    return !text[index - 1] || text[index - 1].trim().length == 0;
}