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 47 48 49 50 51 52 53 54 55 56
| function diff(oldTree, newTree) { let patches = {} let index = 0 walk(oldTree, newTree, index, patches) return patches }
function walk(oldNode, newNode, index, patches) { let current = [] if (!newNode) { current.push({ type: 'REMOVE', index }) } else if (_.isString(oldNode) && _.isString(newNode)) { if (oldNode !== newNode) { current.push({ type: 'TEXT', text: newNode }) } } else if (oldNode.type === newNode.type) { let attr = diffAttr(oldNode.props, newNode.props) if (Object.keys(attr).length > 0) { current.push({ type: 'ATTR', attr }) } diffChildren(oldNode.children, newNode.children, patches) } else { current.push({ type: 'REPLACE', newNode }) }
if (current.length) { patches[index] = current } }
function diffAttr(oldAttrs, newAttrs) { let patch = {} for (let key in oldAttrs) { if (oldAttrs[key] !== newAttrs[key]) { patch[key] = newAttrs[key] } } for (let key in newAttrs) { if (!oldAttrs.hasOwnProperty(key)) { patch[key] = newAttrs[key] } } return patch }
let num = 0 function diffChildren(oldChildren, newChildren, patches) { oldChildren.forEach((child, index) => { walk(child, newChildren[index], ++num, patches) }) }
|