All files / roosterjs-content-model-core/lib/override listMetadataApplier.ts

100% Statements 29/29
100% Branches 44/44
100% Functions 4/4
100% Lines 29/29

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 103 1041x                           1x             97x 67x 67x   67x   30x           185x       185x           1x           291x   291x 290x 290x   290x 104x 53x           51x                   1x           203x   203x 202x 202x   202x 81x 44x           44x 42x     37x            
import {
    ListMetadataDefinition,
    OrderedListStyleMap,
    UnorderedListStyleMap,
    getAutoListStyleType,
    getOrderedListNumberStr,
} from 'roosterjs-content-model-dom';
import type {
    ContentModelListItemFormat,
    ContentModelListItemLevelFormat,
    ListMetadataFormat,
    MetadataApplier,
} from 'roosterjs-content-model-types';
 
const OrderedMapPlaceholderRegex = /\$\{(\w+)\}/;
 
function getListStyleValue(
    listType: 'OL' | 'UL',
    listStyleType: number,
    listNumber?: number
): string | undefined {
    if (listType == 'OL') {
        const numberStr = getOrderedListNumberStr(listStyleType, listNumber ?? 1);
        const template = OrderedListStyleMap[listStyleType];
 
        return template ? template.replace(OrderedMapPlaceholderRegex, numberStr) : undefined;
    } else {
        return UnorderedListStyleMap[listStyleType];
    }
}
 
function shouldApplyToItem(listStyleType: number, listType: 'OL' | 'UL') {
    const style =
        listType == 'OL'
            ? OrderedListStyleMap[listStyleType]
            : UnorderedListStyleMap[listStyleType];
 
    return style?.indexOf('"') >= 0;
}
 
/**
 * @internal
 */
export const listItemMetadataApplier: MetadataApplier<
    ListMetadataFormat,
    ContentModelListItemFormat
> = {
    metadataDefinition: ListMetadataDefinition,
    applierFunction: (metadata, format, context) => {
        const depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index
 
        if (depth >= 0) {
            const listType = context.listFormat.nodeStack[depth + 1].listType ?? 'OL';
            const listStyleType = getAutoListStyleType(listType, metadata ?? {}, depth);
 
            if (listStyleType !== undefined) {
                if (shouldApplyToItem(listStyleType, listType)) {
                    format.listStyleType = getListStyleValue(
                        listType,
                        listStyleType,
                        context.listFormat.threadItemCounts[depth]
                    );
                } else {
                    delete format.listStyleType;
                }
            }
        }
    },
};
 
/**
 * @internal
 */
export const listLevelMetadataApplier: MetadataApplier<
    ListMetadataFormat,
    ContentModelListItemLevelFormat
> = {
    metadataDefinition: ListMetadataDefinition,
    applierFunction: (metadata, format, context) => {
        const depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index
 
        if (depth >= 0) {
            const listType = context.listFormat.nodeStack[depth + 1].listType ?? 'OL';
            const listStyleType = getAutoListStyleType(listType, metadata ?? {}, depth);
 
            if (listStyleType !== undefined) {
                if (!shouldApplyToItem(listStyleType, listType)) {
                    const listStyleTypeFormat = getListStyleValue(
                        listType,
                        listStyleType,
                        context.listFormat.threadItemCounts[depth]
                    );
 
                    if (listStyleTypeFormat) {
                        format.listStyleType = listStyleTypeFormat;
                    }
                } else {
                    delete format.listStyleType;
                }
            }
        }
    },
};