Skip to content

Commit

Permalink
use a different diff with vnodes and dom
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrsh committed Mar 26, 2017
1 parent b7a16d3 commit 3b240cf
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 23 deletions.
40 changes: 29 additions & 11 deletions dist/moon.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,12 @@
// Add all event listeners
addEventListeners(el, vnode, instance);
}
// Setup Props (With Cache)
el.__moon__props__ = extend({}, vnode.props.attrs);
// Setup Props
diffProps(el, {}, vnode, vnode.props.attrs);

// Setup Cached NodeName
el.__moon__nodeName__ = vnode.type;
// Setup Cache
el.__moon__vnode__ = vnode;

return el;
};

Expand Down Expand Up @@ -443,7 +443,6 @@
for (var vnodePropName in vnodeProps) {
if (!nodeProps.hasOwnProperty(vnodePropName) || nodeProps[vnodePropName] !== vnodeProps[vnodePropName]) {
isSVG ? node.setAttributeNS(null, vnodePropName, vnodeProps[vnodePropName]) : node.setAttribute(vnodePropName, vnodeProps[vnodePropName]);
node.__moon__props__[vnodePropName] = vnodeProps[vnodePropName];
}
}
}
Expand All @@ -456,7 +455,6 @@
directives[nodePropName](node, vnodeProps[nodePropName], vnode);
}
isSVG ? node.removeAttributeNS(null, nodePropName) : node.removeAttribute(nodePropName);
delete node.__moon__props__[nodePropName];
}
}
}
Expand All @@ -482,9 +480,11 @@
*/
var diff = function (node, vnode, parent, instance) {
var nodeName = null;
var oldVNode = null;

if (node && vnode) {
nodeName = node.__moon__nodeName__ || node.nodeName.toLowerCase();
oldVNode = node.__moon__vnode__;
nodeName = oldVNode && oldVNode.type || node.nodeName.toLowerCase();
}

if (!node) {
Expand All @@ -499,10 +499,13 @@
} else if (!vnode) {
// No vnode, remove the node
parent.removeChild(node);

// Check for Component
if (node.__moon__) {
// Component was unmounted, destroy it here
node.__moon__.destroy();
}

return null;
} else if (nodeName !== vnode.type) {
// Different types, replace it
Expand All @@ -517,7 +520,7 @@
createComponentFromVNode(newNode, vnode, vnode.meta.component);
}
return newNode;
} else if (vnode.meta.shouldRender && vnode.type === "#text" && nodeName === "#text" && vnode.val !== node.textContent) {
} else if (vnode.meta.shouldRender && vnode.type === "#text" && node.nodeType === "#text" && vnode.val !== (oldVNode && oldVNode.val || node.textContent)) {
// Both are textnodes, update the node
node.textContent = vnode.val;
return node;
Expand Down Expand Up @@ -548,14 +551,18 @@
componentInstance.build();
}
}

// Cache VNode
node.__moon__vnode__ = vnode;

// Skip diffing any children
return node;
}

// Children May have Changed

// Diff props
var nodeProps = node.__moon__props__ || extractAttrs(node);
var nodeProps = node.__moon__vnode__ && node.__moon__vnode__.props.attrs || extractAttrs(node);
diffProps(node, nodeProps, vnode, vnode.props.attrs);

// Add initial event listeners (done once)
Expand All @@ -565,26 +572,37 @@

// Check if innerHTML was changed, don't diff children
if (vnode.props.dom && vnode.props.dom.innerHTML) {
// Cache VNode
node.__moon__vnode__ = vnode;

// Exit
return node;
}

// Diff Children
var currentChildNode = node.firstChild;
var currentChildVNode = currentChildNode && currentChildNode.__moon__vnode__;
// Optimization:
// If the vnode contains just one text vnode, create it here
if (vnode.children.length === 1 && vnode.children[0].type === "#text" && currentChildNode && !currentChildNode.nextSibling && currentChildNode.nodeName === "#text") {
if (vnode.children[0].val !== currentChildNode.textContent) {
var currentChildNodeTextContent = currentChildVNode ? currentChildVNode.val : currentChildNode.textContent;
if (vnode.children[0].val !== currentChildNodeTextContent) {
currentChildNode.textContent = vnode.children[0].val;
currentChildNode.__moon__vnode__ = vnode.children[0];
}
} else {
// Iterate through all children
for (var i = 0; i < vnode.children.length || currentChildNode; i++) {
var next = currentChildNode ? currentChildNode.nextSibling : null;
var next = currentChildNode && currentChildNode.nextSibling;
diff(currentChildNode, vnode.children[i], node, instance);
currentChildNode = next;
}
}

// Cache VNode
node.__moon__vnode__ = vnode;

// Exit
return node;
} else {
// Nothing Changed
Expand Down
Loading

0 comments on commit 3b240cf

Please sign in to comment.