const REPLACE = 0
const ATTRS = 1
const TEXT = 2
const REORDER = 3
//diff å
¥å£ï¼æ¯è¾æ°æ§ä¸¤æ£µæ çå·®å¼
function diff (oldTree,newTree){
let index = 0
let patches = {}//ç¨æ¥è®°å½æ¯ä¸ä¸ªèç¹å·®å¼çè¡¥ä¸å¯¹è±¡
walk(oldTree,newTree,index,patches)
return patches
}
/**
* walk é忥æ¾èç¹å·®å¼
* @param { Object } oldNode
* @param { Object } newNode
* @param { Number } index - currentNodeIndex
* @param { Object } patches - è®°å½èç¹å·®å¼ç对象
*/
function walk(oldNode,newNode,index,patches){
let currenPatch = []
if (newNode === null || newNode === undefined) {
// å
ä¸åæä½, å
·ä½äº¤ç» list diff å¤ç
}else if (_.isString(oldNode)&&_.isString(newNode)){
// æ¯è¾ææ¬ä¹é´çä¸å
if (newNode !== oldNode) currenPatch.push({type:TEXT,content:newNode})
}else if (oldNode.tagName === newNode.tagName && oldNode.key === newNode.key){
// æ¯è¾attrsçä¸å
let attrsPatches = diffAttrs(oldNode,newNode)
if(attrsPatches){
currentPatch.push({ type: ATTRS, attrs: attrsPatches })
}
// éå½è¿è¡åèç¹çdiffæ¯è¾
diffChildren(oldNode.children, newNode.children, index, patches)
}else {
currentPatch.push({ type: REPLACE, node: newNode})
}
if(currenPatch.length){
patches[index] = currenPatch
}
}
function diffAttrs(oldNode,newNode){
let count = 0
let oldAttrs = oldNode.attrs
let newAttrs = newNode.attrs
let key,value
let attrsPatches = {}
// 妿åå¨ä¸åç attrs
for( key in oldAttrs){
value = oldAttrs[key]
// 妿 oldAttrs ç§»é¤æä¸äº attrs, newAttrs[key] === undefined
if(newAttrs[key]!==value){
count++
attrsPatches[key] = newAttrs[key]
}
}
// 妿å卿°ç attr
for (key in newAttrs) {
value = newAttrs[key]
if (!oldAttrs.hasOwnProperty(key)) {
count++
attrsPatches[key] = value
}
}
if (count === 0) {
return null
}
return attrsPatches
}
// 设置èç¹å¯ä¸æ è¯
let key_id = 0
function diffChildren(oldChildren, newChildren, index, patches) {
// åæ¾å½ånodeçæ è¯ï¼åå§åå¼ä¸º 0
let currentNodeIndex = index
oldChildren.forEach((child,i)=>{
key_id++
let newChild = newChildren[i]
currentNodeIndex = key_id
// éå½ç»§ç»æ¯è¾
walk(child, newChild, currentNodeIndex, patches)
})
}
/**
* Diff two list in O(N).
* @param {Array} oldList - åå§å表
* @param {Array} newList - ç»è¿ä¸äºæä½çå¾åºçæ°å表
* @return {Object} - {moves: