All files / roosterjs-content-model-dom/lib/modelToDom/optimizers mergeNode.ts

100% Statements 20/20
100% Branches 14/14
100% Functions 2/2
100% Lines 18/18

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 471x   1x         1x 1610x 969x   969x               30x 29x     30x   939x           37x 37x   37x 4x     33x 32x 3x       30x    
import { isNodeOfType } from '../../domUtils/isNodeOfType';
 
const OptimizeTags = ['SPAN', 'B', 'EM', 'I', 'U', 'SUB', 'SUP', 'STRIKE', 'S', 'A', 'CODE'];
 
/**
 * @internal
 */
export function mergeNode(root: Node) {
    for (let child = root.firstChild; child; ) {
        const next = child.nextSibling;
 
        if (
            next &&
            isNodeOfType(child, 'ELEMENT_NODE') &&
            isNodeOfType(next, 'ELEMENT_NODE') &&
            child.tagName == next.tagName &&
            OptimizeTags.indexOf(child.tagName) >= 0 &&
            hasSameAttributes(child, next)
        ) {
            while (next.firstChild) {
                child.appendChild(next.firstChild);
            }
 
            next.parentNode!.removeChild(next);
        } else {
            child = next;
        }
    }
}
 
function hasSameAttributes(element1: HTMLElement, element2: HTMLElement) {
    const attr1 = element1.attributes;
    const attr2 = element2.attributes;
 
    if (attr1.length != attr2.length) {
        return false;
    }
 
    for (let i = 0; i < attr1.length; i++) {
        if (attr1[i].name != attr2[i].name || attr1[i].value != attr2[i].value) {
            return false;
        }
    }
 
    return true;
}