<commit_before>const createNodeFactory = tag => {
    return function(attrs, events, ...children) {
        const jdom = {
            tag: tag,
        };
        if (attrs !== undefined) jdom.attrs = attrs;
        if (events !== undefined) jdom.events = events;
        if (children.length > 0) jdom.children = children;
        return jdom;
    }
}

const div = createNodeFactory('div');
const h1 = createNodeFactory('h1');
const h2 = createNodeFactory('h2');
const h3 = createNodeFactory('h3');
const p = createNodeFactory('p');
const a = createNodeFactory('a');
const emph = createNodeFactory('emph');
const strong = createNodeFactory('strong');
const img = createNodeFactory('img');
const button = createNodeFactory('button');
const input = createNodeFactory('input');

const normalizeJDOM = jdom => {
    if (typeof jdom === 'object') {
        if (!('tag' in jdom)) jdom.tag = 'div';
        if (!('attrs' in jdom)) jdom.attrs = {};
        if (!('events' in jdom)) jdom.events = {};
        if (!('children' in jdom)) jdom.children = [];
    }
    return jdom;
}

const renderJDOM = (node, previous, next) => {
    function erasePreviousNode() {
        if (node !== undefined) {
            if (node.parentNode) node.parentNode.removeChild(node);
            for (const eventName in previous.events) {
                node.removeEventListener(eventName);
            }
        }
    };

    if (next === null) {
        if (previous === null) {
            // both are comments, do nothing
        } else {
            erasePreviousNode();
            node = document.createComment('');
        }
    } else if (typeof next === 'string') {
        erasePreviousNode();
        node = document.createTextNode(next);
    } else if (typeof next === 'object') {
        if (previous === undefined) {
            // Creating a brand-new node.
            previous = {
                tag: null,
            };
        }
        normalizeJDOM(previous);
        normalizeJDOM(next);

        // Compare tag
        if (previous.tag !== next.tag) {
            erasePreviousNode();
            node = document.createElement(next.tag);
        }

        // Compare attrs
        for (const attrName in next.attrs) {
            if (next.attrs[attrName] !== previous.attrs[attrName]) {
                node.setAttribute(attrName, next.attrs[attrName]);
            }
        }
        for (const attrName in previous.attrs) {
            if (!(attrName in next.attrs)) {
                node.removeAttribute(attrName);
            }
        }

        // Compare events
        for (const eventName in next.events) {
            if (next.events[eventName] !== previous.events[eventName]) {
                node.removeEventListener(eventName);
                node.addEventListener(eventName, next.events[eventName]);
            }
        }
        for (const eventName in previous.events) {
            if (!(eventName in next.events)) {<commit_msg>Fix some bugs resolving children diffs in the render logic<commit_after>const createNodeFactory = tag => {
    return function(attrs, events, ...children) {
        const jdom = {
            tag: tag,
        };
        if (attrs !== undefined) jdom.attrs = attrs;
        if (events !== undefined) jdom.events = events;
        if (children.length > 0) jdom.children = children;
        return jdom;
    }
}

const div = createNodeFactory('div');
const h1 = createNodeFactory('h1');
const h2 = createNodeFactory('h2');
const h3 = createNodeFactory('h3');
const p = createNodeFactory('p');
const a = createNodeFactory('a');
const em = createNodeFactory('em');
const strong = createNodeFactory('strong');
const img = createNodeFactory('img');
const button = createNodeFactory('button');
const input = createNodeFactory('input');

const normalizeJDOM = jdom => {
    if (typeof jdom === 'object') {
        if (!('tag' in jdom)) jdom.tag = 'div';
        if (!('attrs' in jdom)) jdom.attrs = {};
        if (!('events' in jdom)) jdom.events = {};
        if (!('children' in jdom)) jdom.children = [];
    }
    return jdom;
}

const renderJDOM = (node, previous, next) => {
    function replacePreviousNode(newNode) {
        if (node !== undefined) {
            for (const eventName in previous.events) {
                node.removeEventListener(eventName);
            }

            const parentNode = node.parentNode;
            const nextSibling = node.nextSibling;
            if (parentNode) {
                parentNode.removeChild(node);
                if (nextSibling) {
                    parentNode.insertBefore(newNode, nextSibling);
                } else {
                    parentNode.appendChild(newNode);
                }
            }
        }

        node = newNode;
    };

    if (next === null) {
        if (previous === null) {
            // both are comments, do nothing
        } else {
            replacePreviousNode(document.createComment(''));
        }
    } else if (typeof next === 'string') {
        replacePreviousNode(document.createTextNode(next));
    } else if (typeof next === 'object') {
        if (previous === undefined) {
            // Creating a brand-new node.
            previous = {
                tag: null,
            };
        }
        normalizeJDOM(previous);
        normalizeJDOM(next);

        // Compare tag
        if (previous.tag !== next.tag) {
            replacePreviousNode(document.createElement(next.tag));
        }

        // Compare attrs
        for (const attrName in next.attrs) {
            if (next.attrs[attrName] !== previous.attrs[attrName]) {
                node.setAttribute(attrName, next.attrs[attrName]);
            }
        }
        for (const attrName in previous.attrs) {
            if (!(attrName in next.attrs)) {
                node.removeAttribute(attrName);
            }
        }

        // Compare events
        for (const eventName in next.events) {
            if (next.events[eventName] !== previous.events[eventName]) {
                node.removeEventListener(eventName);
                node.addEventListener(eventName, next.events[eventName]);
            }
        }
        for (const eventName in previous.events) {
            if (!(eventName in next.events)) {
{'fraction_non_alphanumeric': 0.1301424683848247, 'fraction_numerical': 0.002241075716343845, 'mean_word_length': 1.9639468690702087, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1605483', 'n_tokens_mistral': 1703, 'n_tokens_neox': 1673, 'n_words': 421}