All files / roosterjs-content-model-dom/lib/domUtils/style transformColor.ts

83.33% Statements 15/18
62.5% Branches 5/8
100% Functions 4/4
82.35% Lines 14/17

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 541x                   1x           10x 10x 10x 10x   10x 10x     10x               10x 10x     10x                         10x 10x    
import { getColor, setColor } from '../../formatHandlers/utils/color';
import type { DarkColorHandler } from 'roosterjs-content-model-types';
 
/**
 * Edit and transform color of elements between light mode and dark mode
 * @param rootNode The root DOM node to transform
 * @param includeSelf True to transform the root node as well, otherwise false
 * @param direction To specify the transform direction, light to dark, or dark to light
 * @param darkColorHandler The dark color handler object to help do color transformation
 */
export function transformColor(
    rootNode: Node,
    includeSelf: boolean,
    direction: 'lightToDark' | 'darkToLight',
    darkColorHandler?: DarkColorHandler
) {
    const toDarkMode = direction == 'lightToDark';
    const transformer = (element: HTMLElement) => {
        const textColor = getColor(element, false /*isBackground*/, !toDarkMode, darkColorHandler);
        const backColor = getColor(element, true /*isBackground*/, !toDarkMode, darkColorHandler);
 
        setColor(element, textColor, false /*isBackground*/, toDarkMode, darkColorHandler);
        setColor(element, backColor, true /*isBackground*/, toDarkMode, darkColorHandler);
    };
 
    iterateElements(rootNode, transformer, includeSelf);
}
 
function iterateElements(
    root: Node,
    transformer: (element: HTMLElement) => void,
    includeSelf?: boolean
) {
    Eif (includeSelf && isHTMLElement(root)) {
        transformer(root);
    }
 
    for (let child = root.firstChild; child; child = child.nextSibling) {
        if (isHTMLElement(child)) {
            transformer(child);
        }
 
        iterateElements(child, transformer);
    }
}
 
// This is not a strict check, we just need to make sure this element has style so that we can set style to it
// We don't use safeInstanceOf() here since this function will be called very frequently when extract html content
// in dark mode, so we need to make sure this check is fast enough
function isHTMLElement(node: Node): node is HTMLElement {
    const htmlElement = <HTMLElement>node;
    return node.nodeType == Node.ELEMENT_NODE && !!htmlElement.style;
}