All files / roosterjs-content-model-dom/lib/formatHandlers/segment fontSizeFormatHandler.ts

96.55% Statements 28/29
92.86% Branches 39/42
100% Functions 3/3
96.55% Lines 28/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 881x 1x             1x   2862x 2862x       2862x 558x 547x         11x 11x         1985x 233x           1x                               547x 547x   547x 8x 539x             12x 4x   8x       8x 8x   1x   1x   6x       527x     527x      
import { isSuperOrSubScript } from './superOrSubScriptFormatHandler';
import { parseValueWithUnit } from '../utils/parseValueWithUnit';
import type { EditorContext, FontSizeFormat } from 'roosterjs-content-model-types';
import type { FormatHandler } from '../FormatHandler';
 
/**
 * @internal
 */
export const fontSizeFormatHandler: FormatHandler<FontSizeFormat> = {
    parse: (format, element, context, defaultStyle) => {
        const fontSize = element.style.fontSize || defaultStyle.fontSize;
        const verticalAlign = element.style.verticalAlign || defaultStyle.verticalAlign;
 
        // when font size is 'smaller' and the style is for superscript/subscript,
        // the font size will be handled by superOrSubScript handler
        if (fontSize && !isSuperOrSubScript(fontSize, verticalAlign) && fontSize != 'inherit') {
            if (element.style.fontSize) {
                format.fontSize = normalizeFontSize(
                    fontSize,
                    context.segmentFormat.fontSize,
                    context
                );
            } else Eif (defaultStyle.fontSize) {
                format.fontSize = fontSize;
            }
        }
    },
    apply: (format, element, context) => {
        if (format.fontSize && format.fontSize != context.implicitFormat.fontSize) {
            element.style.fontSize = format.fontSize;
        }
    },
};
 
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-size
const KnownFontSizes: Record<string, string> = {
    'xx-small': '6.75pt',
    'x-small': '7.5pt',
    small: '9.75pt',
    medium: '12pt',
    large: '13.5pt',
    'x-large': '18pt',
    'xx-large': '24pt',
    'xxx-large': '36pt',
};
 
function normalizeFontSize(
    fontSize: string,
    contextFont: string | undefined,
    context: EditorContext
): string | undefined {
    const knownFontSize = KnownFontSizes[fontSize];
    const isRemUnit = fontSize.endsWith('rem');
 
    if (knownFontSize) {
        return knownFontSize;
    } else if (
        fontSize == 'smaller' ||
        fontSize == 'larger' ||
        fontSize.endsWith('em') ||
        fontSize.endsWith('%') ||
        isRemUnit
    ) {
        if (!contextFont && !isRemUnit) {
            return undefined;
        } else {
            const existingFontSize = isRemUnit
                ? context.rootFontSize
                : parseValueWithUnit(contextFont);
 
            Eif (existingFontSize) {
                switch (fontSize) {
                    case 'smaller':
                        return Math.round((existingFontSize * 500) / 6) / 100 + 'px';
                    case 'larger':
                        return Math.round((existingFontSize * 600) / 5) / 100 + 'px';
                    default:
                        return parseValueWithUnit(fontSize, existingFontSize, 'px') + 'px';
                }
            }
        }
    } else Iif (fontSize == 'inherit' || fontSize == 'revert' || fontSize == 'unset') {
        return undefined;
    } else {
        return fontSize;
    }
}