Socket
Socket
Sign inDemoInstall

morphdom

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

morphdom - npm Package Compare versions

Comparing version 1.3.1 to 1.4.0

44

CHANGELOG.md

@@ -6,4 +6,44 @@ Changelog

## 1.0.x
## 1.4.x
### 1.4.0
- Make attributes and elements namespace-aware ([@shawnbot](https://github.com/shawnbot))
## 1.3.x
### 1.3.1
- Upgraded to `lasso@^2`
- Fixed tests
### 1.3.0
- Support full page html diff ([@DylanPiercey](https://github.com/DylanPiercey))
## 1.2.x
### 1.2.0
- Improve node lifecycle options ([@callum](https://github.com/callum))
## 1.1.x
### 1.1.4
- Checking in `dist/` files into the git repo
- Deleted `.cache/` from npm package
### 1.1.3
- Added a minified UMD distribution file
### 1.1.2
- Minor internal changes
### 1.1.1
- Updated `package.json`
### 1.1.0

@@ -13,2 +53,4 @@

## 1.0.x
### 1.0.4

@@ -15,0 +57,0 @@

267

dist/morphdom-umd.js

@@ -5,14 +5,25 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.morphdom = f()}})(function(){var define,module,exports;module={exports:(exports={})};

var testEl = typeof document !== 'undefined' ? document.body || document.createElement('div') : {};
var testEl = (typeof document !== 'undefined') ?
document.body || document.createElement('div') :
{};
// Fixes https://github.com/patrick-steele-idem/morphdom/issues/32 (IE7+ support)
// <=IE7 does not support el.hasAttribute(name)
var hasAttribute;
if (testEl.hasAttribute) {
hasAttribute = function hasAttribute(el, name) {
var XHTML = 'http://www.w3.org/1999/xhtml';
var ELEMENT_NODE = Node.ELEMENT_NODE;
var TEXT_NODE = Node.TEXT_NODE;
// Fixes <https://github.com/patrick-steele-idem/morphdom/issues/32>
// (IE7+ support) <=IE7 does not support el.hasAttribute(name)
var hasAttributeNS;
if (testEl.hasAttributeNS) {
hasAttributeNS = function(el, namespaceURI, name) {
return el.hasAttributeNS(namespaceURI, name);
};
} else if (testEl.hasAttribute) {
hasAttributeNS = function(el, namespaceURI, name) {
return el.hasAttribute(name);
};
} else {
hasAttribute = function hasAttribute(el, name) {
return el.getAttributeNode(name);
hasAttributeNS = function(el, namespaceURI, name) {
return !!el.getAttributeNode(name);
};

@@ -27,5 +38,5 @@ }

}
return true;
}
function toElement(str) {

@@ -49,8 +60,8 @@ if (!range && document.createRange) {

/**
* Needed for IE. Apparently IE doesn't think
* that "selected" is an attribute when reading
* over the attributes using selectEl.attributes
* Needed for IE. Apparently IE doesn't think that "selected" is an
* attribute when reading over the attributes using selectEl.attributes
*/
OPTION: function(fromEl, toEl) {
if ((fromEl.selected = toEl.selected)) {
fromEl.selected = toEl.selected;
if (fromEl.selected) {
fromEl.setAttribute('selected', '');

@@ -62,21 +73,28 @@ } else {

/**
* The "value" attribute is special for the <input> element
* since it sets the initial value. Changing the "value"
* attribute without changing the "value" property will have
* no effect since it is only used to the set the initial value.
* Similar for the "checked" attribute.
* The "value" attribute is special for the <input> element since it sets
* the initial value. Changing the "value" attribute without changing the
* "value" property will have no effect since it is only used to the set the
* initial value. Similar for the "checked" attribute, and "disabled".
*/
INPUT: function(fromEl, toEl) {
fromEl.checked = toEl.checked;
if (fromEl.checked) {
fromEl.setAttribute('checked', '');
} else {
fromEl.removeAttribute('checked');
}
if (fromEl.value != toEl.value) {
if (fromEl.value !== toEl.value) {
fromEl.value = toEl.value;
}
if (!hasAttribute(toEl, 'checked')) {
fromEl.removeAttribute('checked');
if (!hasAttributeNS(toEl, null, 'value')) {
fromEl.removeAttribute('value');
}
if (!hasAttribute(toEl, 'value')) {
fromEl.removeAttribute('value');
fromEl.disabled = toEl.disabled;
if (fromEl.disabled) {
fromEl.setAttribute('disabled', '');
} else {
fromEl.removeAttribute('disabled');
}

@@ -87,3 +105,3 @@ },

var newValue = toEl.value;
if (fromEl.value != newValue) {
if (fromEl.value !== newValue) {
fromEl.value = newValue;

@@ -101,9 +119,36 @@ }

/**
* Loop over all of the attributes on the target node and make sure the
* original DOM node has the same attributes. If an attribute
* found on the original node is not on the new node then remove it from
* the original node
* @param {HTMLElement} fromNode
* @param {HTMLElement} toNode
* Returns true if two node's names and namespace URIs are the same.
*
* @param {Element} a
* @param {Element} b
* @return {boolean}
*/
var compareNodeNames = function(a, b) {
return a.nodeName === b.nodeName &&
a.namespaceURI === b.namespaceURI;
};
/**
* Create an element, optionally with a known namespace URI.
*
* @param {string} name the element name, e.g. 'div' or 'svg'
* @param {string} [namespaceURI] the element's namespace URI, i.e. the value of
* its `xmlns` attribute or its inferred namespace.
*
* @return {Element}
*/
function createElementNS(name, namespaceURI) {
return !namespaceURI || namespaceURI === XHTML ?
document.createElement(name) :
document.createElementNS(namespaceURI, name);
}
/**
* Loop over all of the attributes on the target node and make sure the original
* DOM node has the same attributes. If an attribute found on the original node
* is not on the new node then remove it from the original node.
*
* @param {Element} fromNode
* @param {Element} toNode
*/
function morphAttrs(fromNode, toNode) {

@@ -114,13 +159,20 @@ var attrs = toNode.attributes;

var attrName;
var attrNamespaceURI;
var attrValue;
var foundAttrs = {};
var fromValue;
for (i=attrs.length-1; i>=0; i--) {
for (i = attrs.length - 1; i >= 0; i--) {
attr = attrs[i];
if (attr.specified !== false) {
attrName = attr.name;
attrValue = attr.value;
foundAttrs[attrName] = true;
attrName = attr.name;
attrValue = attr.value;
attrNamespaceURI = attr.namespaceURI;
if (fromNode.getAttribute(attrName) !== attrValue) {
fromValue = attrNamespaceURI ?
fromNode.getAttributeNS(attrNamespaceURI, attrName) :
fromNode.getAttribute(attrName);
if (fromValue !== attrValue) {
if (attrNamespaceURI) {
fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
} else {
fromNode.setAttribute(attrName, attrValue);

@@ -131,12 +183,14 @@ }

// Delete any extra attributes found on the original DOM element that weren't
// found on the target element.
// Remove any extra attributes found on the original DOM element that
// weren't found on the target element.
attrs = fromNode.attributes;
for (i=attrs.length-1; i>=0; i--) {
for (i = attrs.length - 1; i >= 0; i--) {
attr = attrs[i];
if (attr.specified !== false) {
attrName = attr.name;
if (!foundAttrs.hasOwnProperty(attrName)) {
fromNode.removeAttribute(attrName);
attrNamespaceURI = attr.namespaceURI;
if (!hasAttributeNS(toNode, attrNamespaceURI, attrName)) {
fromNode.removeAttributeNode(attr);
}

@@ -152,3 +206,3 @@ }

var curChild = fromEl.firstChild;
while(curChild) {
while (curChild) {
var nextChild = curChild.nextSibling;

@@ -180,2 +234,9 @@ toEl.appendChild(curChild);

// XXX optimization: if the nodes are equal, don't morph them
/*
if (fromNode.isEqualNode(toNode)) {
return fromNode;
}
*/
var savedEls = {}; // Used to save off DOM elements with IDs

@@ -207,5 +268,5 @@ var unmatchedEls = {};

if (node.nodeType === 1) {
if (node.nodeType === ELEMENT_NODE) {
var curChild = node.firstChild;
while(curChild) {
while (curChild) {
removeNodeHelper(curChild, nestedInSavedEl || id);

@@ -218,5 +279,5 @@ curChild = curChild.nextSibling;

function walkDiscardedChildNodes(node) {
if (node.nodeType === 1) {
if (node.nodeType === ELEMENT_NODE) {
var curChild = node.firstChild;
while(curChild) {
while (curChild) {

@@ -276,3 +337,3 @@

if (fromEl.tagName != 'TEXTAREA') {
if (fromEl.nodeName !== 'TEXTAREA') {
var curToNodeChild = toEl.firstChild;

@@ -287,7 +348,7 @@ var curFromNodeChild = fromEl.firstChild;

outer: while(curToNodeChild) {
outer: while (curToNodeChild) {
toNextSibling = curToNodeChild.nextSibling;
curToNodeId = getNodeKey(curToNodeChild);
while(curFromNodeChild) {
while (curFromNodeChild) {
var curFromNodeId = getNodeKey(curFromNodeChild);

@@ -310,9 +371,10 @@ fromNextSibling = curFromNodeChild.nextSibling;

if (curFromNodeType === 1) { // Both nodes being compared are Element nodes
if (curFromNodeChild.tagName === curToNodeChild.tagName) {
// Both nodes being compared are Element nodes
if (curFromNodeType === ELEMENT_NODE) {
if (compareNodeNames(curFromNodeChild, curToNodeChild)) {
// We have compatible DOM elements
if (curFromNodeId || curToNodeId) {
// If either DOM element has an ID then we handle
// those differently since we want to match up
// by ID
// If either DOM element has an ID then we
// handle those differently since we want to
// match up by ID
if (curToNodeId === curFromNodeId) {

@@ -327,9 +389,12 @@ isCompatible = true;

if (isCompatible) {
// We found compatible DOM elements so transform the current "from" node
// to match the current target DOM node.
// We found compatible DOM elements so transform
// the current "from" node to match the current
// target DOM node.
morphEl(curFromNodeChild, curToNodeChild, alreadyVisited);
}
} else if (curFromNodeType === 3) { // Both nodes being compared are Text nodes
// Both nodes being compared are Text nodes
} else if (curFromNodeType === TEXT_NODE) {
isCompatible = true;
// Simply update nodeValue on the original node to change the text value
// Simply update nodeValue on the original node to
// change the text value
curFromNodeChild.nodeValue = curToNodeChild.nodeValue;

@@ -345,4 +410,4 @@ }

// No compatible match so remove the old node from the DOM and continue trying
// to find a match in the original DOM
// No compatible match so remove the old node from the DOM
// and continue trying to find a match in the original DOM
removeNode(curFromNodeChild, fromEl, alreadyVisited);

@@ -355,10 +420,12 @@ curFromNodeChild = fromNextSibling;

morphEl(savedEl, curToNodeChild, true);
curToNodeChild = savedEl; // We want to append the saved element instead
// We want to append the saved element instead
curToNodeChild = savedEl;
} else {
// The current DOM element in the target tree has an ID
// but we did not find a match in any of the corresponding
// siblings. We just put the target element in the old DOM tree
// but if we later find an element in the old DOM tree that has
// a matching ID then we will replace the target element
// with the corresponding old element and morph the old element
// but we did not find a match in any of the
// corresponding siblings. We just put the target
// element in the old DOM tree but if we later find an
// element in the old DOM tree that has a matching ID
// then we will replace the target element with the
// corresponding old element and morph the old element
unmatchedEls[curToNodeId] = curToNodeChild;

@@ -368,5 +435,6 @@ }

// If we got this far then we did not find a candidate match for our "to node"
// and we exhausted all of the children "from" nodes. Therefore, we will just
// append the current "to node" to the end
// If we got this far then we did not find a candidate match for
// our "to node" and we exhausted all of the children "from"
// nodes. Therefore, we will just append the current "to node"
// to the end
if (onBeforeNodeAdded(curToNodeChild) !== false) {

@@ -377,8 +445,10 @@ fromEl.appendChild(curToNodeChild);

if (curToNodeChild.nodeType === 1 && (curToNodeId || curToNodeChild.firstChild)) {
// The element that was just added to the original DOM may have
// some nested elements with a key/ID that needs to be matched up
// with other elements. We'll add the element to a list so that we
// can later process the nested elements if there are any unmatched
// keyed elements that were discarded
if (curToNodeChild.nodeType === ELEMENT_NODE &&
(curToNodeId || curToNodeChild.firstChild)) {
// The element that was just added to the original DOM may
// have some nested elements with a key/ID that needs to be
// matched up with other elements. We'll add the element to
// a list so that we can later process the nested elements
// if there are any unmatched keyed elements that were
// discarded
movedEls.push(curToNodeChild);

@@ -391,5 +461,6 @@ }

// We have processed all of the "to nodes". If curFromNodeChild is non-null then
// we still have some from nodes left over that need to be removed
while(curFromNodeChild) {
// We have processed all of the "to nodes". If curFromNodeChild is
// non-null then we still have some from nodes left over that need
// to be removed
while (curFromNodeChild) {
fromNextSibling = curFromNodeChild.nextSibling;

@@ -401,3 +472,3 @@ removeNode(curFromNodeChild, fromEl, alreadyVisited);

var specialElHandler = specialElHandlers[fromEl.tagName];
var specialElHandler = specialElHandlers[fromEl.nodeName];
if (specialElHandler) {

@@ -415,7 +486,7 @@ specialElHandler(fromEl, toEl);

// compatible (e.g. <div> --> <span> or <div> --> TEXT)
if (morphedNodeType === 1) {
if (toNodeType === 1) {
if (fromNode.tagName !== toNode.tagName) {
if (morphedNodeType === ELEMENT_NODE) {
if (toNodeType === ELEMENT_NODE) {
if (!compareNodeNames(fromNode, toNode)) {
onNodeDiscarded(fromNode);
morphedNode = moveChildren(fromNode, document.createElement(toNode.tagName));
morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
}

@@ -426,4 +497,4 @@ } else {

}
} else if (morphedNodeType === 3) { // Text node
if (toNodeType === 3) {
} else if (morphedNodeType === TEXT_NODE) { // Text node
if (toNodeType === TEXT_NODE) {
morphedNode.nodeValue = toNode.nodeValue;

@@ -439,4 +510,4 @@ return morphedNode;

if (morphedNode === toNode) {
// The "to node" was not compatible with the "from node"
// so we had to toss out the "from node" and use the "to node"
// The "to node" was not compatible with the "from node" so we had to
// toss out the "from node" and use the "to node"
onNodeDiscarded(fromNode);

@@ -447,12 +518,11 @@ } else {

/**
* What we will do here is walk the tree for the DOM element
* that was moved from the target DOM tree to the original
* DOM tree and we will look for keyed elements that could
* be matched to keyed elements that were earlier discarded.
* If we find a match then we will move the saved element
* into the final DOM tree
* What we will do here is walk the tree for the DOM element that was
* moved from the target DOM tree to the original DOM tree and we will
* look for keyed elements that could be matched to keyed elements that
* were earlier discarded. If we find a match then we will move the
* saved element into the final DOM tree.
*/
var handleMovedEl = function(el) {
var curChild = el.firstChild;
while(curChild) {
while (curChild) {
var nextSibling = curChild.nextSibling;

@@ -463,5 +533,6 @@

var savedEl = savedEls[key];
if (savedEl && (curChild.tagName === savedEl.tagName)) {
if (savedEl && compareNodeNames(curChild, savedEl)) {
curChild.parentNode.replaceChild(savedEl, curChild);
morphEl(savedEl, curChild, true /* already visited the saved el tree */);
// true: already visited the saved el tree
morphEl(savedEl, curChild, true);
curChild = nextSibling;

@@ -475,3 +546,3 @@ if (empty(savedEls)) {

if (curChild.nodeType === 1) {
if (curChild.nodeType === ELEMENT_NODE) {
handleMovedEl(curChild);

@@ -478,0 +549,0 @@ }

@@ -1,1 +0,1 @@

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.morphdom=f()}})(function(){var define,module,exports;module={exports:exports={}};var range;var testEl=typeof document!=="undefined"?document.body||document.createElement("div"):{};var hasAttribute;if(testEl.hasAttribute){hasAttribute=function hasAttribute(el,name){return el.hasAttribute(name)}}else{hasAttribute=function hasAttribute(el,name){return el.getAttributeNode(name)}}function empty(o){for(var k in o){if(o.hasOwnProperty(k)){return false}}return true}function toElement(str){if(!range&&document.createRange){range=document.createRange();range.selectNode(document.body)}var fragment;if(range&&range.createContextualFragment){fragment=range.createContextualFragment(str)}else{fragment=document.createElement("body");fragment.innerHTML=str}return fragment.childNodes[0]}var specialElHandlers={OPTION:function(fromEl,toEl){if(fromEl.selected=toEl.selected){fromEl.setAttribute("selected","")}else{fromEl.removeAttribute("selected","")}},INPUT:function(fromEl,toEl){fromEl.checked=toEl.checked;if(fromEl.value!=toEl.value){fromEl.value=toEl.value}if(!hasAttribute(toEl,"checked")){fromEl.removeAttribute("checked")}if(!hasAttribute(toEl,"value")){fromEl.removeAttribute("value")}},TEXTAREA:function(fromEl,toEl){var newValue=toEl.value;if(fromEl.value!=newValue){fromEl.value=newValue}if(fromEl.firstChild){fromEl.firstChild.nodeValue=newValue}}};function noop(){}function morphAttrs(fromNode,toNode){var attrs=toNode.attributes;var i;var attr;var attrName;var attrValue;var foundAttrs={};for(i=attrs.length-1;i>=0;i--){attr=attrs[i];if(attr.specified!==false){attrName=attr.name;attrValue=attr.value;foundAttrs[attrName]=true;if(fromNode.getAttribute(attrName)!==attrValue){fromNode.setAttribute(attrName,attrValue)}}}attrs=fromNode.attributes;for(i=attrs.length-1;i>=0;i--){attr=attrs[i];if(attr.specified!==false){attrName=attr.name;if(!foundAttrs.hasOwnProperty(attrName)){fromNode.removeAttribute(attrName)}}}}function moveChildren(fromEl,toEl){var curChild=fromEl.firstChild;while(curChild){var nextChild=curChild.nextSibling;toEl.appendChild(curChild);curChild=nextChild}return toEl}function defaultGetNodeKey(node){return node.id}function morphdom(fromNode,toNode,options){if(!options){options={}}if(typeof toNode==="string"){if(fromNode.nodeName==="#document"||fromNode.nodeName==="HTML"){var toNodeHtml=toNode;toNode=document.createElement("html");toNode.innerHTML=toNodeHtml}else{toNode=toElement(toNode)}}var savedEls={};var unmatchedEls={};var getNodeKey=options.getNodeKey||defaultGetNodeKey;var onBeforeNodeAdded=options.onBeforeNodeAdded||noop;var onNodeAdded=options.onNodeAdded||noop;var onBeforeElUpdated=options.onBeforeElUpdated||options.onBeforeMorphEl||noop;var onElUpdated=options.onElUpdated||noop;var onBeforeNodeDiscarded=options.onBeforeNodeDiscarded||noop;var onNodeDiscarded=options.onNodeDiscarded||noop;var onBeforeElChildrenUpdated=options.onBeforeElChildrenUpdated||options.onBeforeMorphElChildren||noop;var childrenOnly=options.childrenOnly===true;var movedEls=[];function removeNodeHelper(node,nestedInSavedEl){var id=getNodeKey(node);if(id){savedEls[id]=node}else if(!nestedInSavedEl){onNodeDiscarded(node)}if(node.nodeType===1){var curChild=node.firstChild;while(curChild){removeNodeHelper(curChild,nestedInSavedEl||id);curChild=curChild.nextSibling}}}function walkDiscardedChildNodes(node){if(node.nodeType===1){var curChild=node.firstChild;while(curChild){if(!getNodeKey(curChild)){onNodeDiscarded(curChild);walkDiscardedChildNodes(curChild)}curChild=curChild.nextSibling}}}function removeNode(node,parentNode,alreadyVisited){if(onBeforeNodeDiscarded(node)===false){return}parentNode.removeChild(node);if(alreadyVisited){if(!getNodeKey(node)){onNodeDiscarded(node);walkDiscardedChildNodes(node)}}else{removeNodeHelper(node)}}function morphEl(fromEl,toEl,alreadyVisited,childrenOnly){var toElKey=getNodeKey(toEl);if(toElKey){delete savedEls[toElKey]}if(!childrenOnly){if(onBeforeElUpdated(fromEl,toEl)===false){return}morphAttrs(fromEl,toEl);onElUpdated(fromEl);if(onBeforeElChildrenUpdated(fromEl,toEl)===false){return}}if(fromEl.tagName!="TEXTAREA"){var curToNodeChild=toEl.firstChild;var curFromNodeChild=fromEl.firstChild;var curToNodeId;var fromNextSibling;var toNextSibling;var savedEl;var unmatchedEl;outer:while(curToNodeChild){toNextSibling=curToNodeChild.nextSibling;curToNodeId=getNodeKey(curToNodeChild);while(curFromNodeChild){var curFromNodeId=getNodeKey(curFromNodeChild);fromNextSibling=curFromNodeChild.nextSibling;if(!alreadyVisited){if(curFromNodeId&&(unmatchedEl=unmatchedEls[curFromNodeId])){unmatchedEl.parentNode.replaceChild(curFromNodeChild,unmatchedEl);morphEl(curFromNodeChild,unmatchedEl,alreadyVisited);curFromNodeChild=fromNextSibling;continue}}var curFromNodeType=curFromNodeChild.nodeType;if(curFromNodeType===curToNodeChild.nodeType){var isCompatible=false;if(curFromNodeType===1){if(curFromNodeChild.tagName===curToNodeChild.tagName){if(curFromNodeId||curToNodeId){if(curToNodeId===curFromNodeId){isCompatible=true}}else{isCompatible=true}}if(isCompatible){morphEl(curFromNodeChild,curToNodeChild,alreadyVisited)}}else if(curFromNodeType===3){isCompatible=true;curFromNodeChild.nodeValue=curToNodeChild.nodeValue}if(isCompatible){curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling;continue outer}}removeNode(curFromNodeChild,fromEl,alreadyVisited);curFromNodeChild=fromNextSibling}if(curToNodeId){if(savedEl=savedEls[curToNodeId]){morphEl(savedEl,curToNodeChild,true);curToNodeChild=savedEl}else{unmatchedEls[curToNodeId]=curToNodeChild}}if(onBeforeNodeAdded(curToNodeChild)!==false){fromEl.appendChild(curToNodeChild);onNodeAdded(curToNodeChild)}if(curToNodeChild.nodeType===1&&(curToNodeId||curToNodeChild.firstChild)){movedEls.push(curToNodeChild)}curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling}while(curFromNodeChild){fromNextSibling=curFromNodeChild.nextSibling;removeNode(curFromNodeChild,fromEl,alreadyVisited);curFromNodeChild=fromNextSibling}}var specialElHandler=specialElHandlers[fromEl.tagName];if(specialElHandler){specialElHandler(fromEl,toEl)}}var morphedNode=fromNode;var morphedNodeType=morphedNode.nodeType;var toNodeType=toNode.nodeType;if(!childrenOnly){if(morphedNodeType===1){if(toNodeType===1){if(fromNode.tagName!==toNode.tagName){onNodeDiscarded(fromNode);morphedNode=moveChildren(fromNode,document.createElement(toNode.tagName))}}else{morphedNode=toNode}}else if(morphedNodeType===3){if(toNodeType===3){morphedNode.nodeValue=toNode.nodeValue;return morphedNode}else{morphedNode=toNode}}}if(morphedNode===toNode){onNodeDiscarded(fromNode)}else{morphEl(morphedNode,toNode,false,childrenOnly);var handleMovedEl=function(el){var curChild=el.firstChild;while(curChild){var nextSibling=curChild.nextSibling;var key=getNodeKey(curChild);if(key){var savedEl=savedEls[key];if(savedEl&&curChild.tagName===savedEl.tagName){curChild.parentNode.replaceChild(savedEl,curChild);morphEl(savedEl,curChild,true);curChild=nextSibling;if(empty(savedEls)){return false}continue}}if(curChild.nodeType===1){handleMovedEl(curChild)}curChild=nextSibling}};if(!empty(savedEls)){handleMovedElsLoop:while(movedEls.length){var movedElsTemp=movedEls;movedEls=[];for(var i=0;i<movedElsTemp.length;i++){if(handleMovedEl(movedElsTemp[i])===false){break handleMovedElsLoop}}}}for(var savedElId in savedEls){if(savedEls.hasOwnProperty(savedElId)){var savedEl=savedEls[savedElId];onNodeDiscarded(savedEl);walkDiscardedChildNodes(savedEl)}}}if(!childrenOnly&&morphedNode!==fromNode&&fromNode.parentNode){fromNode.parentNode.replaceChild(morphedNode,fromNode)}return morphedNode}module.exports=morphdom;return module.exports});
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.morphdom=f()}})(function(){var define,module,exports;module={exports:exports={}};var range;var testEl=typeof document!=="undefined"?document.body||document.createElement("div"):{};var XHTML="http://www.w3.org/1999/xhtml";var ELEMENT_NODE=Node.ELEMENT_NODE;var TEXT_NODE=Node.TEXT_NODE;var hasAttributeNS;if(testEl.hasAttributeNS){hasAttributeNS=function(el,namespaceURI,name){return el.hasAttributeNS(namespaceURI,name)}}else if(testEl.hasAttribute){hasAttributeNS=function(el,namespaceURI,name){return el.hasAttribute(name)}}else{hasAttributeNS=function(el,namespaceURI,name){return!!el.getAttributeNode(name)}}function empty(o){for(var k in o){if(o.hasOwnProperty(k)){return false}}return true}function toElement(str){if(!range&&document.createRange){range=document.createRange();range.selectNode(document.body)}var fragment;if(range&&range.createContextualFragment){fragment=range.createContextualFragment(str)}else{fragment=document.createElement("body");fragment.innerHTML=str}return fragment.childNodes[0]}var specialElHandlers={OPTION:function(fromEl,toEl){fromEl.selected=toEl.selected;if(fromEl.selected){fromEl.setAttribute("selected","")}else{fromEl.removeAttribute("selected","")}},INPUT:function(fromEl,toEl){fromEl.checked=toEl.checked;if(fromEl.checked){fromEl.setAttribute("checked","")}else{fromEl.removeAttribute("checked")}if(fromEl.value!==toEl.value){fromEl.value=toEl.value}if(!hasAttributeNS(toEl,null,"value")){fromEl.removeAttribute("value")}fromEl.disabled=toEl.disabled;if(fromEl.disabled){fromEl.setAttribute("disabled","")}else{fromEl.removeAttribute("disabled")}},TEXTAREA:function(fromEl,toEl){var newValue=toEl.value;if(fromEl.value!==newValue){fromEl.value=newValue}if(fromEl.firstChild){fromEl.firstChild.nodeValue=newValue}}};function noop(){}var compareNodeNames=function(a,b){return a.nodeName===b.nodeName&&a.namespaceURI===b.namespaceURI};function createElementNS(name,namespaceURI){return!namespaceURI||namespaceURI===XHTML?document.createElement(name):document.createElementNS(namespaceURI,name)}function morphAttrs(fromNode,toNode){var attrs=toNode.attributes;var i;var attr;var attrName;var attrNamespaceURI;var attrValue;var fromValue;for(i=attrs.length-1;i>=0;i--){attr=attrs[i];attrName=attr.name;attrValue=attr.value;attrNamespaceURI=attr.namespaceURI;fromValue=attrNamespaceURI?fromNode.getAttributeNS(attrNamespaceURI,attrName):fromNode.getAttribute(attrName);if(fromValue!==attrValue){if(attrNamespaceURI){fromNode.setAttributeNS(attrNamespaceURI,attrName,attrValue)}else{fromNode.setAttribute(attrName,attrValue)}}}attrs=fromNode.attributes;for(i=attrs.length-1;i>=0;i--){attr=attrs[i];if(attr.specified!==false){attrName=attr.name;attrNamespaceURI=attr.namespaceURI;if(!hasAttributeNS(toNode,attrNamespaceURI,attrName)){fromNode.removeAttributeNode(attr)}}}}function moveChildren(fromEl,toEl){var curChild=fromEl.firstChild;while(curChild){var nextChild=curChild.nextSibling;toEl.appendChild(curChild);curChild=nextChild}return toEl}function defaultGetNodeKey(node){return node.id}function morphdom(fromNode,toNode,options){if(!options){options={}}if(typeof toNode==="string"){if(fromNode.nodeName==="#document"||fromNode.nodeName==="HTML"){var toNodeHtml=toNode;toNode=document.createElement("html");toNode.innerHTML=toNodeHtml}else{toNode=toElement(toNode)}}var savedEls={};var unmatchedEls={};var getNodeKey=options.getNodeKey||defaultGetNodeKey;var onBeforeNodeAdded=options.onBeforeNodeAdded||noop;var onNodeAdded=options.onNodeAdded||noop;var onBeforeElUpdated=options.onBeforeElUpdated||options.onBeforeMorphEl||noop;var onElUpdated=options.onElUpdated||noop;var onBeforeNodeDiscarded=options.onBeforeNodeDiscarded||noop;var onNodeDiscarded=options.onNodeDiscarded||noop;var onBeforeElChildrenUpdated=options.onBeforeElChildrenUpdated||options.onBeforeMorphElChildren||noop;var childrenOnly=options.childrenOnly===true;var movedEls=[];function removeNodeHelper(node,nestedInSavedEl){var id=getNodeKey(node);if(id){savedEls[id]=node}else if(!nestedInSavedEl){onNodeDiscarded(node)}if(node.nodeType===ELEMENT_NODE){var curChild=node.firstChild;while(curChild){removeNodeHelper(curChild,nestedInSavedEl||id);curChild=curChild.nextSibling}}}function walkDiscardedChildNodes(node){if(node.nodeType===ELEMENT_NODE){var curChild=node.firstChild;while(curChild){if(!getNodeKey(curChild)){onNodeDiscarded(curChild);walkDiscardedChildNodes(curChild)}curChild=curChild.nextSibling}}}function removeNode(node,parentNode,alreadyVisited){if(onBeforeNodeDiscarded(node)===false){return}parentNode.removeChild(node);if(alreadyVisited){if(!getNodeKey(node)){onNodeDiscarded(node);walkDiscardedChildNodes(node)}}else{removeNodeHelper(node)}}function morphEl(fromEl,toEl,alreadyVisited,childrenOnly){var toElKey=getNodeKey(toEl);if(toElKey){delete savedEls[toElKey]}if(!childrenOnly){if(onBeforeElUpdated(fromEl,toEl)===false){return}morphAttrs(fromEl,toEl);onElUpdated(fromEl);if(onBeforeElChildrenUpdated(fromEl,toEl)===false){return}}if(fromEl.nodeName!=="TEXTAREA"){var curToNodeChild=toEl.firstChild;var curFromNodeChild=fromEl.firstChild;var curToNodeId;var fromNextSibling;var toNextSibling;var savedEl;var unmatchedEl;outer:while(curToNodeChild){toNextSibling=curToNodeChild.nextSibling;curToNodeId=getNodeKey(curToNodeChild);while(curFromNodeChild){var curFromNodeId=getNodeKey(curFromNodeChild);fromNextSibling=curFromNodeChild.nextSibling;if(!alreadyVisited){if(curFromNodeId&&(unmatchedEl=unmatchedEls[curFromNodeId])){unmatchedEl.parentNode.replaceChild(curFromNodeChild,unmatchedEl);morphEl(curFromNodeChild,unmatchedEl,alreadyVisited);curFromNodeChild=fromNextSibling;continue}}var curFromNodeType=curFromNodeChild.nodeType;if(curFromNodeType===curToNodeChild.nodeType){var isCompatible=false;if(curFromNodeType===ELEMENT_NODE){if(compareNodeNames(curFromNodeChild,curToNodeChild)){if(curFromNodeId||curToNodeId){if(curToNodeId===curFromNodeId){isCompatible=true}}else{isCompatible=true}}if(isCompatible){morphEl(curFromNodeChild,curToNodeChild,alreadyVisited)}}else if(curFromNodeType===TEXT_NODE){isCompatible=true;curFromNodeChild.nodeValue=curToNodeChild.nodeValue}if(isCompatible){curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling;continue outer}}removeNode(curFromNodeChild,fromEl,alreadyVisited);curFromNodeChild=fromNextSibling}if(curToNodeId){if(savedEl=savedEls[curToNodeId]){morphEl(savedEl,curToNodeChild,true);curToNodeChild=savedEl}else{unmatchedEls[curToNodeId]=curToNodeChild}}if(onBeforeNodeAdded(curToNodeChild)!==false){fromEl.appendChild(curToNodeChild);onNodeAdded(curToNodeChild)}if(curToNodeChild.nodeType===ELEMENT_NODE&&(curToNodeId||curToNodeChild.firstChild)){movedEls.push(curToNodeChild)}curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling}while(curFromNodeChild){fromNextSibling=curFromNodeChild.nextSibling;removeNode(curFromNodeChild,fromEl,alreadyVisited);curFromNodeChild=fromNextSibling}}var specialElHandler=specialElHandlers[fromEl.nodeName];if(specialElHandler){specialElHandler(fromEl,toEl)}}var morphedNode=fromNode;var morphedNodeType=morphedNode.nodeType;var toNodeType=toNode.nodeType;if(!childrenOnly){if(morphedNodeType===ELEMENT_NODE){if(toNodeType===ELEMENT_NODE){if(!compareNodeNames(fromNode,toNode)){onNodeDiscarded(fromNode);morphedNode=moveChildren(fromNode,createElementNS(toNode.nodeName,toNode.namespaceURI))}}else{morphedNode=toNode}}else if(morphedNodeType===TEXT_NODE){if(toNodeType===TEXT_NODE){morphedNode.nodeValue=toNode.nodeValue;return morphedNode}else{morphedNode=toNode}}}if(morphedNode===toNode){onNodeDiscarded(fromNode)}else{morphEl(morphedNode,toNode,false,childrenOnly);var handleMovedEl=function(el){var curChild=el.firstChild;while(curChild){var nextSibling=curChild.nextSibling;var key=getNodeKey(curChild);if(key){var savedEl=savedEls[key];if(savedEl&&compareNodeNames(curChild,savedEl)){curChild.parentNode.replaceChild(savedEl,curChild);morphEl(savedEl,curChild,true);curChild=nextSibling;if(empty(savedEls)){return false}continue}}if(curChild.nodeType===ELEMENT_NODE){handleMovedEl(curChild)}curChild=nextSibling}};if(!empty(savedEls)){handleMovedElsLoop:while(movedEls.length){var movedElsTemp=movedEls;movedEls=[];for(var i=0;i<movedElsTemp.length;i++){if(handleMovedEl(movedElsTemp[i])===false){break handleMovedElsLoop}}}}for(var savedElId in savedEls){if(savedEls.hasOwnProperty(savedElId)){var savedEl=savedEls[savedElId];onNodeDiscarded(savedEl);walkDiscardedChildNodes(savedEl)}}}if(!childrenOnly&&morphedNode!==fromNode&&fromNode.parentNode){fromNode.parentNode.replaceChild(morphedNode,fromNode)}return morphedNode}module.exports=morphdom;return module.exports});
// Create a range object for efficently rendering strings to elements.
var range;
var testEl = typeof document !== 'undefined' ? document.body || document.createElement('div') : {};
var testEl = (typeof document !== 'undefined') ?
document.body || document.createElement('div') :
{};
// Fixes https://github.com/patrick-steele-idem/morphdom/issues/32 (IE7+ support)
// <=IE7 does not support el.hasAttribute(name)
var hasAttribute;
if (testEl.hasAttribute) {
hasAttribute = function hasAttribute(el, name) {
var XHTML = 'http://www.w3.org/1999/xhtml';
var ELEMENT_NODE = Node.ELEMENT_NODE;
var TEXT_NODE = Node.TEXT_NODE;
// Fixes <https://github.com/patrick-steele-idem/morphdom/issues/32>
// (IE7+ support) <=IE7 does not support el.hasAttribute(name)
var hasAttributeNS;
if (testEl.hasAttributeNS) {
hasAttributeNS = function(el, namespaceURI, name) {
return el.hasAttributeNS(namespaceURI, name);
};
} else if (testEl.hasAttribute) {
hasAttributeNS = function(el, namespaceURI, name) {
return el.hasAttribute(name);
};
} else {
hasAttribute = function hasAttribute(el, name) {
return el.getAttributeNode(name);
hasAttributeNS = function(el, namespaceURI, name) {
return !!el.getAttributeNode(name);
};

@@ -25,5 +36,5 @@ }

}
return true;
}
function toElement(str) {

@@ -47,8 +58,8 @@ if (!range && document.createRange) {

/**
* Needed for IE. Apparently IE doesn't think
* that "selected" is an attribute when reading
* over the attributes using selectEl.attributes
* Needed for IE. Apparently IE doesn't think that "selected" is an
* attribute when reading over the attributes using selectEl.attributes
*/
OPTION: function(fromEl, toEl) {
if ((fromEl.selected = toEl.selected)) {
fromEl.selected = toEl.selected;
if (fromEl.selected) {
fromEl.setAttribute('selected', '');

@@ -60,21 +71,28 @@ } else {

/**
* The "value" attribute is special for the <input> element
* since it sets the initial value. Changing the "value"
* attribute without changing the "value" property will have
* no effect since it is only used to the set the initial value.
* Similar for the "checked" attribute.
* The "value" attribute is special for the <input> element since it sets
* the initial value. Changing the "value" attribute without changing the
* "value" property will have no effect since it is only used to the set the
* initial value. Similar for the "checked" attribute, and "disabled".
*/
INPUT: function(fromEl, toEl) {
fromEl.checked = toEl.checked;
if (fromEl.checked) {
fromEl.setAttribute('checked', '');
} else {
fromEl.removeAttribute('checked');
}
if (fromEl.value != toEl.value) {
if (fromEl.value !== toEl.value) {
fromEl.value = toEl.value;
}
if (!hasAttribute(toEl, 'checked')) {
fromEl.removeAttribute('checked');
if (!hasAttributeNS(toEl, null, 'value')) {
fromEl.removeAttribute('value');
}
if (!hasAttribute(toEl, 'value')) {
fromEl.removeAttribute('value');
fromEl.disabled = toEl.disabled;
if (fromEl.disabled) {
fromEl.setAttribute('disabled', '');
} else {
fromEl.removeAttribute('disabled');
}

@@ -85,3 +103,3 @@ },

var newValue = toEl.value;
if (fromEl.value != newValue) {
if (fromEl.value !== newValue) {
fromEl.value = newValue;

@@ -99,9 +117,36 @@ }

/**
* Loop over all of the attributes on the target node and make sure the
* original DOM node has the same attributes. If an attribute
* found on the original node is not on the new node then remove it from
* the original node
* @param {HTMLElement} fromNode
* @param {HTMLElement} toNode
* Returns true if two node's names and namespace URIs are the same.
*
* @param {Element} a
* @param {Element} b
* @return {boolean}
*/
var compareNodeNames = function(a, b) {
return a.nodeName === b.nodeName &&
a.namespaceURI === b.namespaceURI;
};
/**
* Create an element, optionally with a known namespace URI.
*
* @param {string} name the element name, e.g. 'div' or 'svg'
* @param {string} [namespaceURI] the element's namespace URI, i.e. the value of
* its `xmlns` attribute or its inferred namespace.
*
* @return {Element}
*/
function createElementNS(name, namespaceURI) {
return !namespaceURI || namespaceURI === XHTML ?
document.createElement(name) :
document.createElementNS(namespaceURI, name);
}
/**
* Loop over all of the attributes on the target node and make sure the original
* DOM node has the same attributes. If an attribute found on the original node
* is not on the new node then remove it from the original node.
*
* @param {Element} fromNode
* @param {Element} toNode
*/
function morphAttrs(fromNode, toNode) {

@@ -112,13 +157,20 @@ var attrs = toNode.attributes;

var attrName;
var attrNamespaceURI;
var attrValue;
var foundAttrs = {};
var fromValue;
for (i=attrs.length-1; i>=0; i--) {
for (i = attrs.length - 1; i >= 0; i--) {
attr = attrs[i];
if (attr.specified !== false) {
attrName = attr.name;
attrValue = attr.value;
foundAttrs[attrName] = true;
attrName = attr.name;
attrValue = attr.value;
attrNamespaceURI = attr.namespaceURI;
if (fromNode.getAttribute(attrName) !== attrValue) {
fromValue = attrNamespaceURI ?
fromNode.getAttributeNS(attrNamespaceURI, attrName) :
fromNode.getAttribute(attrName);
if (fromValue !== attrValue) {
if (attrNamespaceURI) {
fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
} else {
fromNode.setAttribute(attrName, attrValue);

@@ -129,12 +181,14 @@ }

// Delete any extra attributes found on the original DOM element that weren't
// found on the target element.
// Remove any extra attributes found on the original DOM element that
// weren't found on the target element.
attrs = fromNode.attributes;
for (i=attrs.length-1; i>=0; i--) {
for (i = attrs.length - 1; i >= 0; i--) {
attr = attrs[i];
if (attr.specified !== false) {
attrName = attr.name;
if (!foundAttrs.hasOwnProperty(attrName)) {
fromNode.removeAttribute(attrName);
attrNamespaceURI = attr.namespaceURI;
if (!hasAttributeNS(toNode, attrNamespaceURI, attrName)) {
fromNode.removeAttributeNode(attr);
}

@@ -150,3 +204,3 @@ }

var curChild = fromEl.firstChild;
while(curChild) {
while (curChild) {
var nextChild = curChild.nextSibling;

@@ -178,2 +232,9 @@ toEl.appendChild(curChild);

// XXX optimization: if the nodes are equal, don't morph them
/*
if (fromNode.isEqualNode(toNode)) {
return fromNode;
}
*/
var savedEls = {}; // Used to save off DOM elements with IDs

@@ -205,5 +266,5 @@ var unmatchedEls = {};

if (node.nodeType === 1) {
if (node.nodeType === ELEMENT_NODE) {
var curChild = node.firstChild;
while(curChild) {
while (curChild) {
removeNodeHelper(curChild, nestedInSavedEl || id);

@@ -216,5 +277,5 @@ curChild = curChild.nextSibling;

function walkDiscardedChildNodes(node) {
if (node.nodeType === 1) {
if (node.nodeType === ELEMENT_NODE) {
var curChild = node.firstChild;
while(curChild) {
while (curChild) {

@@ -274,3 +335,3 @@

if (fromEl.tagName != 'TEXTAREA') {
if (fromEl.nodeName !== 'TEXTAREA') {
var curToNodeChild = toEl.firstChild;

@@ -285,7 +346,7 @@ var curFromNodeChild = fromEl.firstChild;

outer: while(curToNodeChild) {
outer: while (curToNodeChild) {
toNextSibling = curToNodeChild.nextSibling;
curToNodeId = getNodeKey(curToNodeChild);
while(curFromNodeChild) {
while (curFromNodeChild) {
var curFromNodeId = getNodeKey(curFromNodeChild);

@@ -308,9 +369,10 @@ fromNextSibling = curFromNodeChild.nextSibling;

if (curFromNodeType === 1) { // Both nodes being compared are Element nodes
if (curFromNodeChild.tagName === curToNodeChild.tagName) {
// Both nodes being compared are Element nodes
if (curFromNodeType === ELEMENT_NODE) {
if (compareNodeNames(curFromNodeChild, curToNodeChild)) {
// We have compatible DOM elements
if (curFromNodeId || curToNodeId) {
// If either DOM element has an ID then we handle
// those differently since we want to match up
// by ID
// If either DOM element has an ID then we
// handle those differently since we want to
// match up by ID
if (curToNodeId === curFromNodeId) {

@@ -325,9 +387,12 @@ isCompatible = true;

if (isCompatible) {
// We found compatible DOM elements so transform the current "from" node
// to match the current target DOM node.
// We found compatible DOM elements so transform
// the current "from" node to match the current
// target DOM node.
morphEl(curFromNodeChild, curToNodeChild, alreadyVisited);
}
} else if (curFromNodeType === 3) { // Both nodes being compared are Text nodes
// Both nodes being compared are Text nodes
} else if (curFromNodeType === TEXT_NODE) {
isCompatible = true;
// Simply update nodeValue on the original node to change the text value
// Simply update nodeValue on the original node to
// change the text value
curFromNodeChild.nodeValue = curToNodeChild.nodeValue;

@@ -343,4 +408,4 @@ }

// No compatible match so remove the old node from the DOM and continue trying
// to find a match in the original DOM
// No compatible match so remove the old node from the DOM
// and continue trying to find a match in the original DOM
removeNode(curFromNodeChild, fromEl, alreadyVisited);

@@ -353,10 +418,12 @@ curFromNodeChild = fromNextSibling;

morphEl(savedEl, curToNodeChild, true);
curToNodeChild = savedEl; // We want to append the saved element instead
// We want to append the saved element instead
curToNodeChild = savedEl;
} else {
// The current DOM element in the target tree has an ID
// but we did not find a match in any of the corresponding
// siblings. We just put the target element in the old DOM tree
// but if we later find an element in the old DOM tree that has
// a matching ID then we will replace the target element
// with the corresponding old element and morph the old element
// but we did not find a match in any of the
// corresponding siblings. We just put the target
// element in the old DOM tree but if we later find an
// element in the old DOM tree that has a matching ID
// then we will replace the target element with the
// corresponding old element and morph the old element
unmatchedEls[curToNodeId] = curToNodeChild;

@@ -366,5 +433,6 @@ }

// If we got this far then we did not find a candidate match for our "to node"
// and we exhausted all of the children "from" nodes. Therefore, we will just
// append the current "to node" to the end
// If we got this far then we did not find a candidate match for
// our "to node" and we exhausted all of the children "from"
// nodes. Therefore, we will just append the current "to node"
// to the end
if (onBeforeNodeAdded(curToNodeChild) !== false) {

@@ -375,8 +443,10 @@ fromEl.appendChild(curToNodeChild);

if (curToNodeChild.nodeType === 1 && (curToNodeId || curToNodeChild.firstChild)) {
// The element that was just added to the original DOM may have
// some nested elements with a key/ID that needs to be matched up
// with other elements. We'll add the element to a list so that we
// can later process the nested elements if there are any unmatched
// keyed elements that were discarded
if (curToNodeChild.nodeType === ELEMENT_NODE &&
(curToNodeId || curToNodeChild.firstChild)) {
// The element that was just added to the original DOM may
// have some nested elements with a key/ID that needs to be
// matched up with other elements. We'll add the element to
// a list so that we can later process the nested elements
// if there are any unmatched keyed elements that were
// discarded
movedEls.push(curToNodeChild);

@@ -389,5 +459,6 @@ }

// We have processed all of the "to nodes". If curFromNodeChild is non-null then
// we still have some from nodes left over that need to be removed
while(curFromNodeChild) {
// We have processed all of the "to nodes". If curFromNodeChild is
// non-null then we still have some from nodes left over that need
// to be removed
while (curFromNodeChild) {
fromNextSibling = curFromNodeChild.nextSibling;

@@ -399,3 +470,3 @@ removeNode(curFromNodeChild, fromEl, alreadyVisited);

var specialElHandler = specialElHandlers[fromEl.tagName];
var specialElHandler = specialElHandlers[fromEl.nodeName];
if (specialElHandler) {

@@ -413,7 +484,7 @@ specialElHandler(fromEl, toEl);

// compatible (e.g. <div> --> <span> or <div> --> TEXT)
if (morphedNodeType === 1) {
if (toNodeType === 1) {
if (fromNode.tagName !== toNode.tagName) {
if (morphedNodeType === ELEMENT_NODE) {
if (toNodeType === ELEMENT_NODE) {
if (!compareNodeNames(fromNode, toNode)) {
onNodeDiscarded(fromNode);
morphedNode = moveChildren(fromNode, document.createElement(toNode.tagName));
morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
}

@@ -424,4 +495,4 @@ } else {

}
} else if (morphedNodeType === 3) { // Text node
if (toNodeType === 3) {
} else if (morphedNodeType === TEXT_NODE) { // Text node
if (toNodeType === TEXT_NODE) {
morphedNode.nodeValue = toNode.nodeValue;

@@ -437,4 +508,4 @@ return morphedNode;

if (morphedNode === toNode) {
// The "to node" was not compatible with the "from node"
// so we had to toss out the "from node" and use the "to node"
// The "to node" was not compatible with the "from node" so we had to
// toss out the "from node" and use the "to node"
onNodeDiscarded(fromNode);

@@ -445,12 +516,11 @@ } else {

/**
* What we will do here is walk the tree for the DOM element
* that was moved from the target DOM tree to the original
* DOM tree and we will look for keyed elements that could
* be matched to keyed elements that were earlier discarded.
* If we find a match then we will move the saved element
* into the final DOM tree
* What we will do here is walk the tree for the DOM element that was
* moved from the target DOM tree to the original DOM tree and we will
* look for keyed elements that could be matched to keyed elements that
* were earlier discarded. If we find a match then we will move the
* saved element into the final DOM tree.
*/
var handleMovedEl = function(el) {
var curChild = el.firstChild;
while(curChild) {
while (curChild) {
var nextSibling = curChild.nextSibling;

@@ -461,5 +531,6 @@

var savedEl = savedEls[key];
if (savedEl && (curChild.tagName === savedEl.tagName)) {
if (savedEl && compareNodeNames(curChild, savedEl)) {
curChild.parentNode.replaceChild(savedEl, curChild);
morphEl(savedEl, curChild, true /* already visited the saved el tree */);
// true: already visited the saved el tree
morphEl(savedEl, curChild, true);
curChild = nextSibling;

@@ -473,3 +544,3 @@ if (empty(savedEls)) {

if (curChild.nodeType === 1) {
if (curChild.nodeType === ELEMENT_NODE) {
handleMovedEl(curChild);

@@ -476,0 +547,0 @@ }

@@ -39,3 +39,3 @@ {

"dependencies": {},
"version": "1.3.1",
"version": "1.4.0",
"keywords": [

@@ -42,0 +42,0 @@ "dom",

@@ -58,2 +58,7 @@ morphdom

# Browser Support
- IE7+ and any modern browser
- Proper namespace support added in `v1.4.0`
# API

@@ -527,3 +532,3 @@

_NOTE: Safari 9.0.2 (11601.3.9)
_NOTE: Safari 9.0.2 (11601.3.9)_

@@ -530,0 +535,0 @@ # Maintainers

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc