export default function applyTextStyle()

in packages/roosterjs-editor-dom/lib/inlineElements/applyTextStyle.ts [18:80]


export default function applyTextStyle(
    container: Node,
    styler: (node: HTMLElement, isInnerNode?: boolean) => any,
    from: NodePosition = new Position(container, PositionType.Begin).normalize(),
    to: NodePosition = new Position(container, PositionType.End).normalize()
) {
    let formatNodes: Node[] = [];

    while (from && to && to.isAfter(from)) {
        let formatNode = from.node;
        let parentTag = getTagOfNode(formatNode.parentNode);

        // The code below modifies DOM. Need to get the next sibling first otherwise you won't be able to reliably get a good next sibling node
        let nextNode = getNextLeafSibling(container, formatNode);

        if (formatNode.nodeType == NodeType.Text && ['TR', 'TABLE'].indexOf(parentTag) < 0) {
            if (formatNode == to.node && !to.isAtEnd) {
                formatNode = splitTextNode(<Text>formatNode, to.offset, true /*returnFirstPart*/);
            }

            if (from.offset > 0) {
                formatNode = splitTextNode(
                    <Text>formatNode,
                    from.offset,
                    false /*returnFirstPart*/
                );
            }

            formatNodes.push(formatNode);
        }

        from = nextNode && new Position(nextNode, PositionType.Begin);
    }

    if (formatNodes.length > 0) {
        if (formatNodes.every(node => node.parentNode == formatNodes[0].parentNode)) {
            let newNode = formatNodes.shift();
            formatNodes.forEach(node => {
                newNode.nodeValue += node.nodeValue;
                node.parentNode.removeChild(node);
            });
            formatNodes = [newNode];
        }

        formatNodes.forEach(node => {
            // When apply style within style tags like B/I/U/..., we split the tag and apply outside them
            // So that the inner style tag such as U, STRIKE can inherit the style we added
            while (
                getTagOfNode(node) != 'SPAN' &&
                STYLET_AGS.indexOf(getTagOfNode(node.parentNode)) >= 0
            ) {
                callStylerWithInnerNode(node, styler);
                node = splitBalancedNodeRange(node);
            }

            if (getTagOfNode(node) != 'SPAN') {
                callStylerWithInnerNode(node, styler);
                node = wrap(node, 'SPAN');
            }
            styler(<HTMLElement>node);
        });
    }
}