Comparing version 0.1.3 to 0.1.4
@@ -80,7 +80,7 @@ var specialAttrHandlers = { | ||
var unmatchedEls = {}; | ||
var onFromNodeFound = options.onFromNodeFound || noop; | ||
var onNodeDiscarded = options.onNodeDiscarded || noop; // NOTE: This | ||
var onBeforeMorphEl = options.onBeforeMorphEl || noop; | ||
var onBeforeMorphElChildren = options.onBeforeMorphElChildren || noop; | ||
function removeNodeHelper(node) { | ||
function removeNodeHelper(node, nestedInSavedEl) { | ||
var id = node.id; | ||
@@ -92,2 +92,6 @@ // If the node has an ID then save it off since we will want | ||
savedEls[id] = node; | ||
} else if (!nestedInSavedEl) { | ||
// If we are not nested in a saved element then we know that this node has been | ||
// completely discarded and will not exist in the final DOM. | ||
onNodeDiscarded(node); | ||
} | ||
@@ -98,4 +102,3 @@ | ||
while(curChild) { | ||
onFromNodeFound(curChild); | ||
removeNodeHelper(curChild); | ||
removeNodeHelper(curChild, nestedInSavedEl || id); | ||
curChild = curChild.nextSibling; | ||
@@ -109,3 +112,5 @@ } | ||
if (!alreadyVisited) { | ||
if (alreadyVisited) { | ||
walkDiscardedNodes(node); | ||
} else { | ||
removeNodeHelper(node); | ||
@@ -115,2 +120,20 @@ } | ||
function walkDiscardedNodes(node) { | ||
onNodeDiscarded(node); | ||
if (node.nodeType === 1) { | ||
var curChild = node.firstChild; | ||
while(curChild) { | ||
if (!curChild.id) { | ||
// Stop walking the tree if we found an element with an ID | ||
// since it will be walked separately... we don't want to double | ||
// walk | ||
walkDiscardedNodes(curChild); | ||
} | ||
curChild = curChild.nextSibling; | ||
} | ||
} | ||
} | ||
function morphEl(fromNode, toNode, alreadyVisited) { | ||
@@ -144,2 +167,4 @@ if (onBeforeMorphEl(fromNode, toNode) === false) { | ||
// the ID of the current "to node" | ||
delete savedEls[curToNodeId]; | ||
fromNode.insertBefore(savedEl, curFromNodeChild); | ||
@@ -156,4 +181,2 @@ morphEl(savedEl, curToNodeChild, true); | ||
if (!alreadyVisited) { | ||
onFromNodeFound(curFromNodeChild); | ||
if (curFromNodeId && (unmatchedEl = unmatchedEls[curFromNodeId])) { | ||
@@ -212,2 +235,3 @@ unmatchedEl.parentNode.replaceChild(curFromNodeChild, unmatchedEl); | ||
if ((savedEl = savedEls[curToNodeId])) { | ||
delete savedEls[curToNodeId]; | ||
morphEl(savedEl, curToNodeChild, true); | ||
@@ -238,6 +262,2 @@ curToNodeChild = savedEl; // We want to append the saved element instead | ||
while(curFromNodeChild) { | ||
if (!alreadyVisited) { | ||
onFromNodeFound(curFromNodeChild); | ||
} | ||
fromNextSibling = curFromNodeChild.nextSibling; | ||
@@ -253,6 +273,2 @@ removeNode(curFromNodeChild, fromNode, alreadyVisited); | ||
// Invoke the callback for the top-level "from node". We'll handle all | ||
// of the nested nodes in the code that does the morph element task | ||
onFromNodeFound(fromNode); | ||
// Handle the case where we are given two DOM nodes that are not | ||
@@ -263,2 +279,3 @@ // compatible (e.g. <div> --> <span> or <div> --> TEXT) | ||
if (morphedNode.tagName !== toNode.tagName) { | ||
onNodeDiscarded(fromNode); | ||
morphedNode = moveChildren(morphedNode, document.createElement(toNode.tagName)); | ||
@@ -275,2 +292,3 @@ } | ||
} else { | ||
onNodeDiscarded(fromNode); | ||
// Text node to something else | ||
@@ -283,9 +301,9 @@ return toNode; | ||
// Fire the "onFromNodeRemoved" event for any saved elements | ||
// Fire the "onNodeDiscarded" event for any saved elements | ||
// that never found a new home in the morphed DOM | ||
// for (var savedElId in savedEls) { | ||
// if (savedEls.hasOwnProperty(savedElId)) { | ||
// onFromNodeRemoved(savedEls[savedElId]); | ||
// } | ||
// } | ||
for (var savedElId in savedEls) { | ||
if (savedEls.hasOwnProperty(savedElId)) { | ||
walkDiscardedNodes(savedEls[savedElId]); | ||
} | ||
} | ||
@@ -292,0 +310,0 @@ if (morphedNode !== fromNode && fromNode.parentNode) { |
@@ -26,6 +26,6 @@ { | ||
"mocha-phantomjs": "^3.5.3", | ||
"phantomjs": "^1.9.17" | ||
"phantomjs": "1.9.7-15" | ||
}, | ||
"dependencies": {}, | ||
"version": "0.1.3" | ||
"version": "0.1.4" | ||
} |
@@ -42,6 +42,5 @@ morphdom | ||
- *onFromNodeFound* (`Function(node)`) - A function that will called when a `Node` in the `from` tree is found | ||
- *onFromNodeRemoved* (`Function(node)`) - A function that will called when a `Node` in the `from` tree has been removed (the children of the removed node will not be traversed) | ||
- *onNodeDiscarded* (`Function(node)`) - A function that will called when a `Node` in the `from` tree has been discarded and will no longer exist in the final DOM tree. | ||
- *onBeforeMorphEl* (`Function(fromEl, toEl)`) - A function that will called when a `HTMLElement` in the `from` tree is about to be morphed. If the listener function returns `false` then the element will be skipped. | ||
- *onBeforeMorphElChildren* (`Function(fromEl, toEl)`) - A function that will called when the children of an `HTMLElement` in the `from` tree is about to be morphed. If the listener function returns `false` then the child nodes will be skipped. | ||
- *onBeforeMorphElChildren* (`Function(fromEl, toEl)`) - A function that will called when the children of an `HTMLElement` in the `from` tree are about to be morphed. If the listener function returns `false` then the child nodes will be skipped. | ||
@@ -48,0 +47,0 @@ ```javascript |
@@ -135,16 +135,30 @@ var chai = require('chai'); | ||
function onFromNodeFound(node) { | ||
if (node.$testOnFromNodeFlag) { | ||
throw new Error('Duplicate onFromNodeFound for: ' + node); | ||
function onNodeDiscarded(node) { | ||
if (node.$onNodeDiscarded) { | ||
throw new Error('Duplicate onNodeDiscarded for: ' + serializeNode(node)); | ||
} | ||
if (node.$testRemovedDescendentFlag) { | ||
throw new Error('Descendent of a removed "from" node is incorrectly being visited. Node: ' + node); | ||
node.$onNodeDiscarded = true; | ||
} | ||
function onBeforeMorphEl(node) { | ||
if (node.$onBeforeMorphEl) { | ||
throw new Error('Duplicate onBeforeMorphEl for: ' + serializeNode(node)); | ||
} | ||
node.$testOnFromNodeFlag = true; | ||
node.$onBeforeMorphEl = true; | ||
} | ||
function onBeforeMorphElChildren(node) { | ||
if (node.$onBeforeMorphElChildren) { | ||
throw new Error('Duplicate onBeforeMorphElChildren for: ' + serializeNode(node)); | ||
} | ||
node.$onBeforeMorphElChildren = true; | ||
} | ||
var morphedNode = morphdom(fromNode, toNode, { | ||
onFromNodeFound: onFromNodeFound | ||
onNodeDiscarded: onNodeDiscarded, | ||
onBeforeMorphEl: onBeforeMorphEl, | ||
onBeforeMorphElChildren: onBeforeMorphElChildren | ||
}); | ||
@@ -182,6 +196,12 @@ | ||
allFromNodes.forEach(function(node) { | ||
if (!node.$testOnFromNodeFlag) { | ||
throw new Error('"from" node was not reported as visited. Node: ' + node); | ||
if (node.$onNodeDiscarded && isNodeInTree(node, morphedNode)) { | ||
throw new Error('"from" node was reported as being discarded, but it still in the final DOM tree. Node: ' + serializeNode(node)); | ||
} | ||
if (node.nodeType === 1 && node.$onNodeDiscarded !== true) { | ||
if (!node.$onBeforeMorphEl) { | ||
throw new Error('"from" element was not reported as being discarded, but it was not morphed. Node: ' + serializeNode(node)); | ||
} | ||
} | ||
// if (isNodeInTree(node, morphedNode)) { | ||
@@ -188,0 +208,0 @@ // if (node.$testOnFromNodeRemovedFlag) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33357
55
626
63