All files / roosterjs-content-model-dom/lib/domToModel/processors listItemProcessor.ts

100% Statements 29/29
100% Branches 15/15
100% Functions 2/2
100% Lines 28/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 791x 1x 1x 1x           1x 368x 368x 368x   368x 368x   368x   368x 9x     9x     368x           368x             368x 368x             368x   368x             368x   368x   368x         319x 319x         368x 9x     368x      
import { createListItem } from '../../modelApi/creators/createListItem';
import { createListLevel } from '../../modelApi/creators/createListLevel';
import { parseFormat } from '../utils/parseFormat';
import { stackFormat } from '../utils/stackFormat';
import type { ElementProcessor } from 'roosterjs-content-model-types';
 
/**
 * @internal
 */
export const listItemProcessor: ElementProcessor<HTMLLIElement> = (group, element, context) => {
    const { listFormat } = context;
    const originalListParent = listFormat.listParent;
    let shouldPopListLevel = false;
 
    try {
        listFormat.listParent = listFormat.listParent ?? group;
 
        const listParent = listFormat.listParent;
 
        if (listFormat.levels.length == 0) {
            listFormat.levels.push(
                createListLevel(listFormat.potentialListType || 'UL', context.blockFormat)
            );
            shouldPopListLevel = true;
        }
 
        stackFormat(
            context,
            {
                segment: 'shallowCloneForBlock',
            },
            () => {
                parseFormat(
                    element,
                    context.formatParsers.segmentOnBlock,
                    context.segmentFormat,
                    context
                );
 
                const listItem = createListItem(listFormat.levels, context.segmentFormat);
                parseFormat(
                    element,
                    context.formatParsers.listItemElement,
                    listItem.format,
                    context
                );
 
                listParent.blocks.push(listItem);
 
                parseFormat(
                    element,
                    context.formatParsers.listItemThread,
                    listItem.levels[listItem.levels.length - 1].format,
                    context
                );
 
                context.elementProcessors.child(listItem, element, context);
 
                const firstChild = listItem.blocks[0];
 
                if (
                    listItem.blocks.length == 1 &&
                    firstChild.blockType == 'Paragraph' &&
                    firstChild.isImplicit
                ) {
                    Object.assign(listItem.format, firstChild.format);
                    firstChild.format = {};
                }
            }
        );
    } finally {
        if (shouldPopListLevel) {
            listFormat.levels.pop();
        }
 
        listFormat.listParent = originalListParent;
    }
};