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 104 105 | 1x 1x 1x 1x 20x 20x 20x 20x 20x 20x 20x 20x 4x 20x 4x 4x 16x 16x 16x 12x 12x 12x 12x 12x 20x 20x 20x 20x 20x | import { BorderColorKeyMap, BorderKeys } from '../../formatHandlers/utils/borderKeys';
import { isElementOfType } from '../isElementOfType';
import {
adaptColor,
getColor,
getLightModeColor,
setColor,
} from '../../formatHandlers/utils/color';
import type { DarkColorHandler } from 'roosterjs-content-model-types';
/**
* Configuration options for controlling which elements and styles undergo color transformation.
* By default, text and background colors are transformed for all elements.
*/
export interface TransformColorOptions {
tableBorders: boolean;
}
/**
* Edit and transform color of elements between light mode and dark mode
* By default, text and background colors are transformed for all elements.
* @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
* @param transformColorOptions Configuration options for controlling which elements and styles undergo color transformation.
*/
export function transformColor(
rootNode: Node,
includeSelf: boolean,
direction: 'lightToDark' | 'darkToLight',
darkColorHandler?: DarkColorHandler,
transformColorOptions?: TransformColorOptions
) {
const toDarkMode = direction == 'lightToDark';
const tableBorders = transformColorOptions?.tableBorders || false;
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);
if (tableBorders) {
transformBorderColor(element, toDarkMode, darkColorHandler);
}
};
iterateElements(rootNode, transformer, includeSelf);
}
function transformBorderColor(
element: HTMLElement,
toDarkMode: boolean,
darkColorHandler?: DarkColorHandler
) {
Eif (isElementOfType(element, 'td') || isElementOfType(element, 'th')) {
BorderKeys.forEach(key => {
const borderColorProperty = BorderColorKeyMap[key];
const style = element.style.getPropertyValue(borderColorProperty);
if (style) {
const lightColor = getLightModeColor(style, !toDarkMode, darkColorHandler);
Eif (lightColor) {
const transformedColor = adaptColor(
element,
lightColor,
'border',
toDarkMode,
darkColorHandler
);
Eif (transformedColor) {
element.style.setProperty(borderColorProperty, transformedColor);
}
}
}
});
}
}
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;
}
|