All files / roosterjs-content-model-dom/lib/formatHandlers/block marginFormatHandler.ts

100% Statements 19/19
96.55% Branches 28/29
100% Functions 4/4
100% Lines 19/19

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 751x       1x                   1x                     1x                   1x   1709x 6836x   6836x       6836x 2082x     1592x 1592x       490x         490x           1253x 5012x 5012x   5012x 712x          
import { parseValueWithUnit } from '../utils/parseValueWithUnit';
import type { FormatHandler } from '../FormatHandler';
import type { DirectionFormat, MarginFormat } from 'roosterjs-content-model-types';
 
const MarginKeys: (keyof MarginFormat & keyof CSSStyleDeclaration)[] = [
    'marginTop',
    'marginRight',
    'marginBottom',
    'marginLeft',
];
 
const DefaultMarginKey: Record<
    'ltr' | 'rtl',
    Partial<Record<keyof MarginFormat, keyof CSSStyleDeclaration>>
> = {
    ltr: {
        marginRight: 'marginInlineEnd',
        marginLeft: 'marginInlineStart',
    },
    rtl: {
        marginRight: 'marginInlineStart',
        marginLeft: 'marginInlineEnd',
    },
};
 
const LTR: Record<keyof MarginFormat, keyof MarginFormat> = {
    marginLeft: 'marginRight',
    marginRight: 'marginLeft',
    marginTop: 'marginTop',
    marginBottom: 'marginBottom',
};
 
/**
 * @internal
 */
export const marginFormatHandler: FormatHandler<MarginFormat & DirectionFormat> = {
    parse: (format, element, _, defaultStyle) => {
        MarginKeys.forEach(key => {
            const alternativeKey = DefaultMarginKey[format.direction ?? 'ltr'][key];
            const value: string | undefined =
                element.style[key] ||
                defaultStyle[key] ||
                (alternativeKey ? defaultStyle[alternativeKey]?.toString() : '');
 
            if (value) {
                switch (key) {
                    case 'marginTop':
                    case 'marginBottom':
                        format[key] = value;
                        break;
 
                    case 'marginLeft':
                    case 'marginRight':
                        format[key] = format[key]
                            ? parseValueWithUnit(format[key] || '', element) +
                              parseValueWithUnit(value, element) +
                              'px'
                            : value;
                        break;
                }
            }
        });
    },
    apply: (format, element, context) => {
        MarginKeys.forEach(key => {
            const value = format[key];
            const ltrKey = format.direction == 'rtl' ? LTR[key] : key;
 
            if (value != context.implicitFormat[ltrKey]) {
                element.style[key] = value || '0';
            }
        });
    },
};