<commit_before>import { ATTR_KEY } from '../constants';
import { createObject, hasOwnProperty, toArray, empty, isString, isFunction } from '../util';
import { hook, deepHook } from '../hooks';
import { isSameNodeType, isNamedNode } from '.';
import { isFunctionalComponent, buildFunctionalComponent } from './functional-component';
import { buildComponentFromVNode } from './component';
import { removeNode, appendChildren, setAccessor, getRawNodeAttributes, getNodeType } from '../dom';
import { createNode, collectNode } from '../dom/recycler';
import { unmountComponent } from './component';



/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
 *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
 *	@returns {Element} dom			The created/mutated element
 *	@private
 */
export default function diff(dom, vnode, context, mountAll) {
	let originalAttributes = vnode.attributes;

	while (isFunctionalComponent(vnode)) {
		vnode = buildFunctionalComponent(vnode, context);
	}

	if (isString(vnode)) {
		if (dom) {
			if (getNodeType(dom)===3) {
				if (dom.nodeValue!==vnode) {
					dom.nodeValue = vnode;
				}
				return dom;
			}
			collectNode(dom);
		}
		return document.createTextNode(vnode);
	}

	if (isFunction(vnode.nodeName)) {
		return buildComponentFromVNode(dom, vnode, context);
	}

	let out = dom,
		nodeName = String(vnode.nodeName);

	if (!dom) {
		out = createNode(nodeName);
	}
	else if (!isNamedNode(dom, nodeName)) {
		out = createNode(nodeName);
		// move children into the replacement node
		appendChildren(out, toArray(dom.childNodes));
		// reclaim element nodes
		recollectNodeTree(dom);
	}

	diffNode(out, vnode, context, mountAll);

	diffAttributes(out, vnode);

	if (originalAttributes && originalAttributes.ref) {
		(out[ATTR_KEY].ref = originalAttributes.ref)(out);
	}

	return out;
}


/** Morph a DOM node to look like the given VNode. Creates DOM if it doesn't exist. */
function diffNode(dom, vnode, context, mountAll) {
	let vchildren = vnode.children,
		firstChild = dom.firstChild;
	if (vchildren && vchildren.length===1 && typeof vchildren[0]==='string' && firstChild instanceof Text && dom.childNodes.length===1) {
		firstChild.nodeValue = vchildren[0];
	}
	else if (vchildren || firstChild) {
		innerDiffNode(dom, vchildren, context, mountAll);
	}

}


function getKey(child) {
	let data = child[ATTR_KEY];
	if (data) return data.key;
}


/** Apply child and attribute changes between a VNode and a DOM Node to the DOM. */
function innerDiffNode(dom, vchildren, context, mountAll) {
	let originalChildren = dom.childNodes,
		children,
		keyed,
		keyedLen = 0,
		min = 0,
		vlen = vchildren && vchildren.length,
		len = originalChildren.length,
		childrenLen = 0;

	if (len) {
		children = [];
		for (let i=0; i<len; i++) {
			let child = originalChildren[i],
				key = child._component ? child._component.__key : getKey(child);
			if (key || key===0) {
				if (!keyed) keyed = createObject();
				keyed[key] = child;
				keyedLen++;
			}
			else {
				children[childrenLen++] = child;
			}
		}
	}

	if (vlen) {
		for (let i=0; i<vlen; i++) {
			let vchild = vchildren[i],<commit_msg>Performance optimization for key lookups within diff<commit_after>import { ATTR_KEY } from '../constants';
import { createObject, hasOwnProperty, toArray, empty, isString, isFunction } from '../util';
import { hook, deepHook } from '../hooks';
import { isSameNodeType, isNamedNode } from '.';
import { isFunctionalComponent, buildFunctionalComponent } from './functional-component';
import { buildComponentFromVNode } from './component';
import { removeNode, appendChildren, setAccessor, getRawNodeAttributes, getNodeType } from '../dom';
import { createNode, collectNode } from '../dom/recycler';
import { unmountComponent } from './component';



/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
 *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
 *	@returns {Element} dom			The created/mutated element
 *	@private
 */
export default function diff(dom, vnode, context, mountAll) {
	let originalAttributes = vnode.attributes;

	while (isFunctionalComponent(vnode)) {
		vnode = buildFunctionalComponent(vnode, context);
	}

	if (isString(vnode)) {
		if (dom) {
			if (getNodeType(dom)===3) {
				if (dom.nodeValue!==vnode) {
					dom.nodeValue = vnode;
				}
				return dom;
			}
			collectNode(dom);
		}
		return document.createTextNode(vnode);
	}

	if (isFunction(vnode.nodeName)) {
		return buildComponentFromVNode(dom, vnode, context);
	}

	let out = dom,
		nodeName = String(vnode.nodeName);

	if (!dom) {
		out = createNode(nodeName);
	}
	else if (!isNamedNode(dom, nodeName)) {
		out = createNode(nodeName);
		// move children into the replacement node
		appendChildren(out, toArray(dom.childNodes));
		// reclaim element nodes
		recollectNodeTree(dom);
	}

	diffNode(out, vnode, context, mountAll);

	diffAttributes(out, vnode);

	if (originalAttributes && originalAttributes.ref) {
		(out[ATTR_KEY].ref = originalAttributes.ref)(out);
	}

	return out;
}


/** Morph a DOM node to look like the given VNode. Creates DOM if it doesn't exist. */
function diffNode(dom, vnode, context, mountAll) {
	let vchildren = vnode.children,
		firstChild = dom.firstChild;
	if (vchildren && vchildren.length===1 && typeof vchildren[0]==='string' && firstChild instanceof Text && dom.childNodes.length===1) {
		firstChild.nodeValue = vchildren[0];
	}
	else if (vchildren || firstChild) {
		innerDiffNode(dom, vchildren, context, mountAll);
	}

}


function getKey(child) {
	let c = child._component;
	if (c) return c.__key;

	let data = child[ATTR_KEY];
	if (data) return data.key;
}


/** Apply child and attribute changes between a VNode and a DOM Node to the DOM. */
function innerDiffNode(dom, vchildren, context, mountAll) {
	let originalChildren = dom.childNodes,
		children,
		keyed,
		keyedLen = 0,
		min = 0,
		vlen = vchildren && vchildren.length,
		len = originalChildren.length,
		childrenLen = 0;

	if (len) {
		children = [];
		for (let i=0; i<len; i++) {
			let child = originalChildren[i],
				key = getKey(child);
			if (key || key===0) {
				if (!keyed) keyed = createObject();
				keyed[key] = child;
				keyedLen++;
			}
			else {
				children[childrenLen++] = child;
			}
		}
	}

	if (vlen) {
		for (let i=0; i<vlen; i++) {
			let vchild = vchildren[i],
{'fraction_non_alphanumeric': 0.13413715146948002, 'fraction_numerical': 0.0033157498116051245, 'mean_word_length': 4.077276205049732, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, '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': '6671348', 'n_tokens_mistral': 2340, 'n_tokens_neox': 2149, 'n_words': 616}