Comparing version 2.3.3 to 2.4.0
@@ -113,3 +113,3 @@ 'use strict'; | ||
} else { | ||
fromEl.removeAttribute(name, ''); | ||
fromEl.removeAttribute(name); | ||
} | ||
@@ -167,3 +167,2 @@ } | ||
if (!hasAttributeNS(toEl, null, 'multiple')) { | ||
var selectedIndex = -1; | ||
var i = 0; | ||
@@ -175,3 +174,2 @@ var curChild = toEl.firstChild; | ||
if (hasAttributeNS(curChild, null, 'selected')) { | ||
selectedIndex = i; | ||
break; | ||
@@ -178,0 +176,0 @@ } |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.morphdom = factory()); | ||
}(this, (function () { 'use strict'; | ||
(global = global || self, global.morphdom = factory()); | ||
}(this, function () { 'use strict'; | ||
var range; // Create a range object for efficently rendering strings to elements. | ||
var NS_XHTML = 'http://www.w3.org/1999/xhtml'; | ||
var range; // Create a range object for efficently rendering strings to elements. | ||
var NS_XHTML = 'http://www.w3.org/1999/xhtml'; | ||
var doc = typeof document === 'undefined' ? undefined : document; | ||
var doc = typeof document === 'undefined' ? undefined : document; | ||
var testEl = doc ? | ||
doc.body || doc.createElement('div') : | ||
{}; | ||
var testEl = doc ? | ||
doc.body || doc.createElement('div') : | ||
{}; | ||
// Fixes <https://github.com/patrick-steele-idem/morphdom/issues/32> | ||
// (IE7+ support) <=IE7 does not support el.hasAttribute(name) | ||
var actualHasAttributeNS; | ||
// Fixes <https://github.com/patrick-steele-idem/morphdom/issues/32> | ||
// (IE7+ support) <=IE7 does not support el.hasAttribute(name) | ||
var actualHasAttributeNS; | ||
if (testEl.hasAttributeNS) { | ||
actualHasAttributeNS = function(el, namespaceURI, name) { | ||
return el.hasAttributeNS(namespaceURI, name); | ||
}; | ||
} else if (testEl.hasAttribute) { | ||
actualHasAttributeNS = function(el, namespaceURI, name) { | ||
return el.hasAttribute(name); | ||
}; | ||
} else { | ||
actualHasAttributeNS = function(el, namespaceURI, name) { | ||
return el.getAttributeNode(namespaceURI, name) != null; | ||
}; | ||
} | ||
if (testEl.hasAttributeNS) { | ||
actualHasAttributeNS = function(el, namespaceURI, name) { | ||
return el.hasAttributeNS(namespaceURI, name); | ||
}; | ||
} else if (testEl.hasAttribute) { | ||
actualHasAttributeNS = function(el, namespaceURI, name) { | ||
return el.hasAttribute(name); | ||
}; | ||
} else { | ||
actualHasAttributeNS = function(el, namespaceURI, name) { | ||
return el.getAttributeNode(namespaceURI, name) != null; | ||
}; | ||
} | ||
var hasAttributeNS = actualHasAttributeNS; | ||
var hasAttributeNS = actualHasAttributeNS; | ||
function toElement(str) { | ||
if (!range && doc.createRange) { | ||
range = doc.createRange(); | ||
range.selectNode(doc.body); | ||
} | ||
function toElement(str) { | ||
if (!range && doc.createRange) { | ||
range = doc.createRange(); | ||
range.selectNode(doc.body); | ||
} | ||
var fragment; | ||
if (range && range.createContextualFragment) { | ||
fragment = range.createContextualFragment(str); | ||
} else { | ||
fragment = doc.createElement('body'); | ||
fragment.innerHTML = str; | ||
var fragment; | ||
if (range && range.createContextualFragment) { | ||
fragment = range.createContextualFragment(str); | ||
} else { | ||
fragment = doc.createElement('body'); | ||
fragment.innerHTML = str; | ||
} | ||
return fragment.childNodes[0]; | ||
} | ||
return fragment.childNodes[0]; | ||
} | ||
/** | ||
* Returns true if two node's names are the same. | ||
* | ||
* NOTE: We don't bother checking `namespaceURI` because you will never find two HTML elements with the same | ||
* nodeName and different namespace URIs. | ||
* | ||
* @param {Element} a | ||
* @param {Element} b The target element | ||
* @return {boolean} | ||
*/ | ||
function compareNodeNames(fromEl, toEl) { | ||
var fromNodeName = fromEl.nodeName; | ||
var toNodeName = toEl.nodeName; | ||
/** | ||
* Returns true if two node's names are the same. | ||
* | ||
* NOTE: We don't bother checking `namespaceURI` because you will never find two HTML elements with the same | ||
* nodeName and different namespace URIs. | ||
* | ||
* @param {Element} a | ||
* @param {Element} b The target element | ||
* @return {boolean} | ||
*/ | ||
function compareNodeNames(fromEl, toEl) { | ||
var fromNodeName = fromEl.nodeName; | ||
var toNodeName = toEl.nodeName; | ||
if (fromNodeName === toNodeName) { | ||
return true; | ||
} | ||
if (fromNodeName === toNodeName) { | ||
return true; | ||
} | ||
if (toEl.actualize && | ||
fromNodeName.charCodeAt(0) < 91 && /* from tag name is upper case */ | ||
toNodeName.charCodeAt(0) > 90 /* target tag name is lower case */) { | ||
// If the target element is a virtual DOM node then we may need to normalize the tag name | ||
// before comparing. Normal HTML elements that are in the "http://www.w3.org/1999/xhtml" | ||
// are converted to upper case | ||
return fromNodeName === toNodeName.toUpperCase(); | ||
} else { | ||
return false; | ||
if (toEl.actualize && | ||
fromNodeName.charCodeAt(0) < 91 && /* from tag name is upper case */ | ||
toNodeName.charCodeAt(0) > 90 /* target tag name is lower case */) { | ||
// If the target element is a virtual DOM node then we may need to normalize the tag name | ||
// before comparing. Normal HTML elements that are in the "http://www.w3.org/1999/xhtml" | ||
// are converted to upper case | ||
return fromNodeName === toNodeName.toUpperCase(); | ||
} else { | ||
return false; | ||
} | ||
} | ||
} | ||
/** | ||
* 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 === NS_XHTML ? | ||
doc.createElement(name) : | ||
doc.createElementNS(namespaceURI, name); | ||
} | ||
/** | ||
* Copies the children of one DOM element to another DOM element | ||
*/ | ||
function moveChildren(fromEl, toEl) { | ||
var curChild = fromEl.firstChild; | ||
while (curChild) { | ||
var nextChild = curChild.nextSibling; | ||
toEl.appendChild(curChild); | ||
curChild = nextChild; | ||
/** | ||
* 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 === NS_XHTML ? | ||
doc.createElement(name) : | ||
doc.createElementNS(namespaceURI, name); | ||
} | ||
return toEl; | ||
} | ||
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; | ||
attrNamespaceURI = attr.namespaceURI; | ||
attrValue = attr.value; | ||
if (attrNamespaceURI) { | ||
attrName = attr.localName || attrName; | ||
fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName); | ||
if (fromValue !== attrValue) { | ||
fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue); | ||
} | ||
} else { | ||
fromValue = fromNode.getAttribute(attrName); | ||
if (fromValue !== attrValue) { | ||
fromNode.setAttribute(attrName, attrValue); | ||
} | ||
/** | ||
* Copies the children of one DOM element to another DOM element | ||
*/ | ||
function moveChildren(fromEl, toEl) { | ||
var curChild = fromEl.firstChild; | ||
while (curChild) { | ||
var nextChild = curChild.nextSibling; | ||
toEl.appendChild(curChild); | ||
curChild = nextChild; | ||
} | ||
return toEl; | ||
} | ||
// Remove any extra attributes found on the original DOM element that | ||
// weren't found on the target element. | ||
attrs = fromNode.attributes; | ||
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]; | ||
if (attr.specified !== false) { | ||
for (i = attrs.length - 1; i >= 0; --i) { | ||
attr = attrs[i]; | ||
attrName = attr.name; | ||
attrNamespaceURI = attr.namespaceURI; | ||
attrValue = attr.value; | ||
if (attrNamespaceURI) { | ||
attrName = attr.localName || attrName; | ||
fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName); | ||
if (!hasAttributeNS(toNode, attrNamespaceURI, attrName)) { | ||
fromNode.removeAttributeNS(attrNamespaceURI, attrName); | ||
if (fromValue !== attrValue) { | ||
fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue); | ||
} | ||
} else { | ||
if (!hasAttributeNS(toNode, null, attrName)) { | ||
fromNode.removeAttribute(attrName); | ||
fromValue = fromNode.getAttribute(attrName); | ||
if (fromValue !== attrValue) { | ||
fromNode.setAttribute(attrName, attrValue); | ||
} | ||
} | ||
} | ||
// 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) { | ||
attr = attrs[i]; | ||
if (attr.specified !== false) { | ||
attrName = attr.name; | ||
attrNamespaceURI = attr.namespaceURI; | ||
if (attrNamespaceURI) { | ||
attrName = attr.localName || attrName; | ||
if (!hasAttributeNS(toNode, attrNamespaceURI, attrName)) { | ||
fromNode.removeAttributeNS(attrNamespaceURI, attrName); | ||
} | ||
} else { | ||
if (!hasAttributeNS(toNode, null, attrName)) { | ||
fromNode.removeAttribute(attrName); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
function syncBooleanAttrProp(fromEl, toEl, name) { | ||
if (fromEl[name] !== toEl[name]) { | ||
fromEl[name] = toEl[name]; | ||
if (fromEl[name]) { | ||
fromEl.setAttribute(name, ''); | ||
} else { | ||
fromEl.removeAttribute(name, ''); | ||
function syncBooleanAttrProp(fromEl, toEl, name) { | ||
if (fromEl[name] !== toEl[name]) { | ||
fromEl[name] = toEl[name]; | ||
if (fromEl[name]) { | ||
fromEl.setAttribute(name, ''); | ||
} else { | ||
fromEl.removeAttribute(name); | ||
} | ||
} | ||
} | ||
} | ||
var specialElHandlers = { | ||
/** | ||
* 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) { | ||
syncBooleanAttrProp(fromEl, toEl, 'selected'); | ||
}, | ||
/** | ||
* 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) { | ||
syncBooleanAttrProp(fromEl, toEl, 'checked'); | ||
syncBooleanAttrProp(fromEl, toEl, 'disabled'); | ||
var specialElHandlers = { | ||
/** | ||
* 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) { | ||
syncBooleanAttrProp(fromEl, toEl, 'selected'); | ||
}, | ||
/** | ||
* 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) { | ||
syncBooleanAttrProp(fromEl, toEl, 'checked'); | ||
syncBooleanAttrProp(fromEl, toEl, 'disabled'); | ||
if (fromEl.value !== toEl.value) { | ||
fromEl.value = toEl.value; | ||
} | ||
if (fromEl.value !== toEl.value) { | ||
fromEl.value = toEl.value; | ||
} | ||
if (!hasAttributeNS(toEl, null, 'value')) { | ||
fromEl.removeAttribute('value'); | ||
} | ||
}, | ||
if (!hasAttributeNS(toEl, null, 'value')) { | ||
fromEl.removeAttribute('value'); | ||
} | ||
}, | ||
TEXTAREA: function(fromEl, toEl) { | ||
var newValue = toEl.value; | ||
if (fromEl.value !== newValue) { | ||
fromEl.value = newValue; | ||
} | ||
TEXTAREA: function(fromEl, toEl) { | ||
var newValue = toEl.value; | ||
if (fromEl.value !== newValue) { | ||
fromEl.value = newValue; | ||
} | ||
var firstChild = fromEl.firstChild; | ||
if (firstChild) { | ||
// Needed for IE. Apparently IE sets the placeholder as the | ||
// node value and vise versa. This ignores an empty update. | ||
var oldValue = firstChild.nodeValue; | ||
var firstChild = fromEl.firstChild; | ||
if (firstChild) { | ||
// Needed for IE. Apparently IE sets the placeholder as the | ||
// node value and vise versa. This ignores an empty update. | ||
var oldValue = firstChild.nodeValue; | ||
if (oldValue == newValue || (!newValue && oldValue == fromEl.placeholder)) { | ||
return; | ||
if (oldValue == newValue || (!newValue && oldValue == fromEl.placeholder)) { | ||
return; | ||
} | ||
firstChild.nodeValue = newValue; | ||
} | ||
firstChild.nodeValue = newValue; | ||
} | ||
}, | ||
SELECT: function(fromEl, toEl) { | ||
if (!hasAttributeNS(toEl, null, 'multiple')) { | ||
var selectedIndex = -1; | ||
var i = 0; | ||
var curChild = toEl.firstChild; | ||
while(curChild) { | ||
var nodeName = curChild.nodeName; | ||
if (nodeName && nodeName.toUpperCase() === 'OPTION') { | ||
if (hasAttributeNS(curChild, null, 'selected')) { | ||
selectedIndex = i; | ||
break; | ||
}, | ||
SELECT: function(fromEl, toEl) { | ||
if (!hasAttributeNS(toEl, null, 'multiple')) { | ||
var i = 0; | ||
var curChild = toEl.firstChild; | ||
while(curChild) { | ||
var nodeName = curChild.nodeName; | ||
if (nodeName && nodeName.toUpperCase() === 'OPTION') { | ||
if (hasAttributeNS(curChild, null, 'selected')) { | ||
break; | ||
} | ||
i++; | ||
} | ||
i++; | ||
curChild = curChild.nextSibling; | ||
} | ||
curChild = curChild.nextSibling; | ||
fromEl.selectedIndex = i; | ||
} | ||
fromEl.selectedIndex = i; | ||
} | ||
} | ||
}; | ||
}; | ||
var ELEMENT_NODE = 1; | ||
var TEXT_NODE = 3; | ||
var COMMENT_NODE = 8; | ||
var ELEMENT_NODE = 1; | ||
var TEXT_NODE = 3; | ||
var COMMENT_NODE = 8; | ||
function noop() {} | ||
function noop() {} | ||
function defaultGetNodeKey(node) { | ||
return node.id; | ||
} | ||
function defaultGetNodeKey(node) { | ||
return node.id; | ||
} | ||
function morphdomFactory(morphAttrs) { | ||
function morphdomFactory(morphAttrs) { | ||
return function morphdom(fromNode, toNode, options) { | ||
if (!options) { | ||
options = {}; | ||
} | ||
return function morphdom(fromNode, toNode, options) { | ||
if (!options) { | ||
options = {}; | ||
} | ||
if (typeof toNode === 'string') { | ||
if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML') { | ||
var toNodeHtml = toNode; | ||
toNode = doc.createElement('html'); | ||
toNode.innerHTML = toNodeHtml; | ||
} else { | ||
toNode = toElement(toNode); | ||
if (typeof toNode === 'string') { | ||
if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML') { | ||
var toNodeHtml = toNode; | ||
toNode = doc.createElement('html'); | ||
toNode.innerHTML = toNodeHtml; | ||
} else { | ||
toNode = toElement(toNode); | ||
} | ||
} | ||
} | ||
var getNodeKey = options.getNodeKey || defaultGetNodeKey; | ||
var onBeforeNodeAdded = options.onBeforeNodeAdded || noop; | ||
var onNodeAdded = options.onNodeAdded || noop; | ||
var onBeforeElUpdated = options.onBeforeElUpdated || noop; | ||
var onElUpdated = options.onElUpdated || noop; | ||
var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop; | ||
var onNodeDiscarded = options.onNodeDiscarded || noop; | ||
var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop; | ||
var childrenOnly = options.childrenOnly === true; | ||
var getNodeKey = options.getNodeKey || defaultGetNodeKey; | ||
var onBeforeNodeAdded = options.onBeforeNodeAdded || noop; | ||
var onNodeAdded = options.onNodeAdded || noop; | ||
var onBeforeElUpdated = options.onBeforeElUpdated || noop; | ||
var onElUpdated = options.onElUpdated || noop; | ||
var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop; | ||
var onNodeDiscarded = options.onNodeDiscarded || noop; | ||
var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop; | ||
var childrenOnly = options.childrenOnly === true; | ||
// This object is used as a lookup to quickly find all keyed elements in the original DOM tree. | ||
var fromNodesLookup = {}; | ||
var keyedRemovalList; | ||
// This object is used as a lookup to quickly find all keyed elements in the original DOM tree. | ||
var fromNodesLookup = {}; | ||
var keyedRemovalList; | ||
function addKeyedRemoval(key) { | ||
if (keyedRemovalList) { | ||
keyedRemovalList.push(key); | ||
} else { | ||
keyedRemovalList = [key]; | ||
function addKeyedRemoval(key) { | ||
if (keyedRemovalList) { | ||
keyedRemovalList.push(key); | ||
} else { | ||
keyedRemovalList = [key]; | ||
} | ||
} | ||
} | ||
function walkDiscardedChildNodes(node, skipKeyedNodes) { | ||
if (node.nodeType === ELEMENT_NODE) { | ||
var curChild = node.firstChild; | ||
while (curChild) { | ||
function walkDiscardedChildNodes(node, skipKeyedNodes) { | ||
if (node.nodeType === ELEMENT_NODE) { | ||
var curChild = node.firstChild; | ||
while (curChild) { | ||
var key = undefined; | ||
var key = undefined; | ||
if (skipKeyedNodes && (key = getNodeKey(curChild))) { | ||
// If we are skipping keyed nodes then we add the key | ||
// to a list so that it can be handled at the very end. | ||
addKeyedRemoval(key); | ||
} else { | ||
// Only report the node as discarded if it is not keyed. We do this because | ||
// at the end we loop through all keyed elements that were unmatched | ||
// and then discard them in one final pass. | ||
onNodeDiscarded(curChild); | ||
if (curChild.firstChild) { | ||
walkDiscardedChildNodes(curChild, skipKeyedNodes); | ||
if (skipKeyedNodes && (key = getNodeKey(curChild))) { | ||
// If we are skipping keyed nodes then we add the key | ||
// to a list so that it can be handled at the very end. | ||
addKeyedRemoval(key); | ||
} else { | ||
// Only report the node as discarded if it is not keyed. We do this because | ||
// at the end we loop through all keyed elements that were unmatched | ||
// and then discard them in one final pass. | ||
onNodeDiscarded(curChild); | ||
if (curChild.firstChild) { | ||
walkDiscardedChildNodes(curChild, skipKeyedNodes); | ||
} | ||
} | ||
curChild = curChild.nextSibling; | ||
} | ||
curChild = curChild.nextSibling; | ||
} | ||
} | ||
} | ||
/** | ||
* Removes a DOM node out of the original DOM | ||
* | ||
* @param {Node} node The node to remove | ||
* @param {Node} parentNode The nodes parent | ||
* @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded. | ||
* @return {undefined} | ||
*/ | ||
function removeNode(node, parentNode, skipKeyedNodes) { | ||
if (onBeforeNodeDiscarded(node) === false) { | ||
return; | ||
} | ||
/** | ||
* Removes a DOM node out of the original DOM | ||
* | ||
* @param {Node} node The node to remove | ||
* @param {Node} parentNode The nodes parent | ||
* @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded. | ||
* @return {undefined} | ||
*/ | ||
function removeNode(node, parentNode, skipKeyedNodes) { | ||
if (onBeforeNodeDiscarded(node) === false) { | ||
return; | ||
} | ||
if (parentNode) { | ||
parentNode.removeChild(node); | ||
if (parentNode) { | ||
parentNode.removeChild(node); | ||
} | ||
onNodeDiscarded(node); | ||
walkDiscardedChildNodes(node, skipKeyedNodes); | ||
} | ||
onNodeDiscarded(node); | ||
walkDiscardedChildNodes(node, skipKeyedNodes); | ||
} | ||
// // TreeWalker implementation is no faster, but keeping this around in case this changes in the future | ||
// function indexTree(root) { | ||
// var treeWalker = document.createTreeWalker( | ||
// root, | ||
// NodeFilter.SHOW_ELEMENT); | ||
// | ||
// var el; | ||
// while((el = treeWalker.nextNode())) { | ||
// var key = getNodeKey(el); | ||
// if (key) { | ||
// fromNodesLookup[key] = el; | ||
// } | ||
// } | ||
// } | ||
// // TreeWalker implementation is no faster, but keeping this around in case this changes in the future | ||
// function indexTree(root) { | ||
// var treeWalker = document.createTreeWalker( | ||
// root, | ||
// NodeFilter.SHOW_ELEMENT); | ||
// | ||
// var el; | ||
// while((el = treeWalker.nextNode())) { | ||
// var key = getNodeKey(el); | ||
// if (key) { | ||
// fromNodesLookup[key] = el; | ||
// } | ||
// } | ||
// } | ||
// // NodeIterator implementation is no faster, but keeping this around in case this changes in the future | ||
// | ||
// function indexTree(node) { | ||
// var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT); | ||
// var el; | ||
// while((el = nodeIterator.nextNode())) { | ||
// var key = getNodeKey(el); | ||
// if (key) { | ||
// fromNodesLookup[key] = el; | ||
// } | ||
// } | ||
// } | ||
// // NodeIterator implementation is no faster, but keeping this around in case this changes in the future | ||
// | ||
// function indexTree(node) { | ||
// var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT); | ||
// var el; | ||
// while((el = nodeIterator.nextNode())) { | ||
// var key = getNodeKey(el); | ||
// if (key) { | ||
// fromNodesLookup[key] = el; | ||
// } | ||
// } | ||
// } | ||
function indexTree(node) { | ||
if (node.nodeType === ELEMENT_NODE) { | ||
var curChild = node.firstChild; | ||
while (curChild) { | ||
var key = getNodeKey(curChild); | ||
if (key) { | ||
fromNodesLookup[key] = curChild; | ||
} | ||
function indexTree(node) { | ||
if (node.nodeType === ELEMENT_NODE) { | ||
var curChild = node.firstChild; | ||
while (curChild) { | ||
var key = getNodeKey(curChild); | ||
if (key) { | ||
fromNodesLookup[key] = curChild; | ||
// Walk recursively | ||
indexTree(curChild); | ||
curChild = curChild.nextSibling; | ||
} | ||
// Walk recursively | ||
indexTree(curChild); | ||
curChild = curChild.nextSibling; | ||
} | ||
} | ||
} | ||
indexTree(fromNode); | ||
indexTree(fromNode); | ||
function handleNodeAdded(el) { | ||
onNodeAdded(el); | ||
function handleNodeAdded(el) { | ||
onNodeAdded(el); | ||
var curChild = el.firstChild; | ||
while (curChild) { | ||
var nextSibling = curChild.nextSibling; | ||
var curChild = el.firstChild; | ||
while (curChild) { | ||
var nextSibling = curChild.nextSibling; | ||
var key = getNodeKey(curChild); | ||
if (key) { | ||
var unmatchedFromEl = fromNodesLookup[key]; | ||
if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) { | ||
curChild.parentNode.replaceChild(unmatchedFromEl, curChild); | ||
morphEl(unmatchedFromEl, curChild); | ||
var key = getNodeKey(curChild); | ||
if (key) { | ||
var unmatchedFromEl = fromNodesLookup[key]; | ||
if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) { | ||
curChild.parentNode.replaceChild(unmatchedFromEl, curChild); | ||
morphEl(unmatchedFromEl, curChild); | ||
} | ||
} | ||
handleNodeAdded(curChild); | ||
curChild = nextSibling; | ||
} | ||
handleNodeAdded(curChild); | ||
curChild = nextSibling; | ||
} | ||
} | ||
function morphEl(fromEl, toEl, childrenOnly) { | ||
var toElKey = getNodeKey(toEl); | ||
var curFromNodeKey; | ||
function morphEl(fromEl, toEl, childrenOnly) { | ||
var toElKey = getNodeKey(toEl); | ||
var curFromNodeKey; | ||
if (toElKey) { | ||
// If an element with an ID is being morphed then it is will be in the final | ||
// DOM so clear it out of the saved elements collection | ||
delete fromNodesLookup[toElKey]; | ||
} | ||
if (toElKey) { | ||
// If an element with an ID is being morphed then it is will be in the final | ||
// DOM so clear it out of the saved elements collection | ||
delete fromNodesLookup[toElKey]; | ||
} | ||
if (toNode.isSameNode && toNode.isSameNode(fromNode)) { | ||
return; | ||
} | ||
if (!childrenOnly) { | ||
if (onBeforeElUpdated(fromEl, toEl) === false) { | ||
if (toNode.isSameNode && toNode.isSameNode(fromNode)) { | ||
return; | ||
} | ||
morphAttrs(fromEl, toEl); | ||
onElUpdated(fromEl); | ||
if (!childrenOnly) { | ||
if (onBeforeElUpdated(fromEl, toEl) === false) { | ||
return; | ||
} | ||
if (onBeforeElChildrenUpdated(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 curToNodeKey; | ||
if (fromEl.nodeName !== 'TEXTAREA') { | ||
var curToNodeChild = toEl.firstChild; | ||
var curFromNodeChild = fromEl.firstChild; | ||
var curToNodeKey; | ||
var fromNextSibling; | ||
var toNextSibling; | ||
var matchingFromEl; | ||
var fromNextSibling; | ||
var toNextSibling; | ||
var matchingFromEl; | ||
outer: while (curToNodeChild) { | ||
toNextSibling = curToNodeChild.nextSibling; | ||
curToNodeKey = getNodeKey(curToNodeChild); | ||
outer: while (curToNodeChild) { | ||
toNextSibling = curToNodeChild.nextSibling; | ||
curToNodeKey = getNodeKey(curToNodeChild); | ||
while (curFromNodeChild) { | ||
fromNextSibling = curFromNodeChild.nextSibling; | ||
while (curFromNodeChild) { | ||
fromNextSibling = curFromNodeChild.nextSibling; | ||
if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) { | ||
curToNodeChild = toNextSibling; | ||
curFromNodeChild = fromNextSibling; | ||
continue outer; | ||
} | ||
if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) { | ||
curToNodeChild = toNextSibling; | ||
curFromNodeChild = fromNextSibling; | ||
continue outer; | ||
} | ||
curFromNodeKey = getNodeKey(curFromNodeChild); | ||
curFromNodeKey = getNodeKey(curFromNodeChild); | ||
var curFromNodeType = curFromNodeChild.nodeType; | ||
var curFromNodeType = curFromNodeChild.nodeType; | ||
var isCompatible = undefined; | ||
var isCompatible = undefined; | ||
if (curFromNodeType === curToNodeChild.nodeType) { | ||
if (curFromNodeType === ELEMENT_NODE) { | ||
// Both nodes being compared are Element nodes | ||
if (curFromNodeType === curToNodeChild.nodeType) { | ||
if (curFromNodeType === ELEMENT_NODE) { | ||
// Both nodes being compared are Element nodes | ||
if (curToNodeKey) { | ||
// The target node has a key so we want to match it up with the correct element | ||
// in the original DOM tree | ||
if (curToNodeKey !== curFromNodeKey) { | ||
// The current element in the original DOM tree does not have a matching key so | ||
// let's check our lookup to see if there is a matching element in the original | ||
// DOM tree | ||
if ((matchingFromEl = fromNodesLookup[curToNodeKey])) { | ||
if (curFromNodeChild.nextSibling === matchingFromEl) { | ||
// Special case for single element removals. To avoid removing the original | ||
// DOM node out of the tree (since that can break CSS transitions, etc.), | ||
// we will instead discard the current node and wait until the next | ||
// iteration to properly match up the keyed target element with its matching | ||
// element in the original tree | ||
isCompatible = false; | ||
} else { | ||
// We found a matching keyed element somewhere in the original DOM tree. | ||
// Let's moving the original DOM node into the current position and morph | ||
// it. | ||
if (curToNodeKey) { | ||
// The target node has a key so we want to match it up with the correct element | ||
// in the original DOM tree | ||
if (curToNodeKey !== curFromNodeKey) { | ||
// The current element in the original DOM tree does not have a matching key so | ||
// let's check our lookup to see if there is a matching element in the original | ||
// DOM tree | ||
if ((matchingFromEl = fromNodesLookup[curToNodeKey])) { | ||
if (curFromNodeChild.nextSibling === matchingFromEl) { | ||
// Special case for single element removals. To avoid removing the original | ||
// DOM node out of the tree (since that can break CSS transitions, etc.), | ||
// we will instead discard the current node and wait until the next | ||
// iteration to properly match up the keyed target element with its matching | ||
// element in the original tree | ||
isCompatible = false; | ||
} else { | ||
// We found a matching keyed element somewhere in the original DOM tree. | ||
// Let's moving the original DOM node into the current position and morph | ||
// it. | ||
// NOTE: We use insertBefore instead of replaceChild because we want to go through | ||
// the `removeNode()` function for the node that is being discarded so that | ||
// all lifecycle hooks are correctly invoked | ||
fromEl.insertBefore(matchingFromEl, curFromNodeChild); | ||
// NOTE: We use insertBefore instead of replaceChild because we want to go through | ||
// the `removeNode()` function for the node that is being discarded so that | ||
// all lifecycle hooks are correctly invoked | ||
fromEl.insertBefore(matchingFromEl, curFromNodeChild); | ||
fromNextSibling = curFromNodeChild.nextSibling; | ||
fromNextSibling = curFromNodeChild.nextSibling; | ||
if (curFromNodeKey) { | ||
// Since the node is keyed it might be matched up later so we defer | ||
// the actual removal to later | ||
addKeyedRemoval(curFromNodeKey); | ||
} else { | ||
// NOTE: we skip nested keyed nodes from being removed since there is | ||
// still a chance they will be matched up later | ||
removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); | ||
if (curFromNodeKey) { | ||
// Since the node is keyed it might be matched up later so we defer | ||
// the actual removal to later | ||
addKeyedRemoval(curFromNodeKey); | ||
} else { | ||
// NOTE: we skip nested keyed nodes from being removed since there is | ||
// still a chance they will be matched up later | ||
removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); | ||
} | ||
curFromNodeChild = matchingFromEl; | ||
} | ||
curFromNodeChild = matchingFromEl; | ||
} else { | ||
// The nodes are not compatible since the "to" node has a key and there | ||
// is no matching keyed node in the source tree | ||
isCompatible = false; | ||
} | ||
} else { | ||
// The nodes are not compatible since the "to" node has a key and there | ||
// is no matching keyed node in the source tree | ||
isCompatible = false; | ||
} | ||
} else if (curFromNodeKey) { | ||
// The original has a key | ||
isCompatible = false; | ||
} | ||
} else if (curFromNodeKey) { | ||
// The original has a key | ||
isCompatible = false; | ||
} | ||
isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild); | ||
if (isCompatible) { | ||
// We found compatible DOM elements so transform | ||
// the current "from" node to match the current | ||
// target DOM node. | ||
morphEl(curFromNodeChild, curToNodeChild); | ||
} | ||
isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild); | ||
if (isCompatible) { | ||
// We found compatible DOM elements so transform | ||
// the current "from" node to match the current | ||
// target DOM node. | ||
morphEl(curFromNodeChild, curToNodeChild); | ||
} | ||
} else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) { | ||
// Both nodes being compared are Text or Comment nodes | ||
isCompatible = true; | ||
// Simply update nodeValue on the original node to | ||
// change the text value | ||
if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) { | ||
curFromNodeChild.nodeValue = curToNodeChild.nodeValue; | ||
} else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) { | ||
// Both nodes being compared are Text or Comment nodes | ||
isCompatible = true; | ||
// Simply update nodeValue on the original node to | ||
// change the text value | ||
if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) { | ||
curFromNodeChild.nodeValue = curToNodeChild.nodeValue; | ||
} | ||
} | ||
} | ||
if (isCompatible) { | ||
// Advance both the "to" child and the "from" child since we found a match | ||
curToNodeChild = toNextSibling; | ||
curFromNodeChild = fromNextSibling; | ||
continue outer; | ||
} | ||
} | ||
if (isCompatible) { | ||
// Advance both the "to" child and the "from" child since we found a match | ||
curToNodeChild = toNextSibling; | ||
// No compatible match so remove the old node from the DOM and continue trying to find a | ||
// match in the original DOM. However, we only do this if the from node is not keyed | ||
// since it is possible that a keyed node might match up with a node somewhere else in the | ||
// target tree and we don't want to discard it just yet since it still might find a | ||
// home in the final DOM tree. After everything is done we will remove any keyed nodes | ||
// that didn't find a home | ||
if (curFromNodeKey) { | ||
// Since the node is keyed it might be matched up later so we defer | ||
// the actual removal to later | ||
addKeyedRemoval(curFromNodeKey); | ||
} else { | ||
// NOTE: we skip nested keyed nodes from being removed since there is | ||
// still a chance they will be matched up later | ||
removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); | ||
} | ||
curFromNodeChild = fromNextSibling; | ||
continue outer; | ||
} | ||
// No compatible match so remove the old node from the DOM and continue trying to find a | ||
// match in the original DOM. However, we only do this if the from node is not keyed | ||
// since it is possible that a keyed node might match up with a node somewhere else in the | ||
// target tree and we don't want to discard it just yet since it still might find a | ||
// home in the final DOM tree. After everything is done we will remove any keyed nodes | ||
// that didn't find a home | ||
if (curFromNodeKey) { | ||
// 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 (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) { | ||
fromEl.appendChild(matchingFromEl); | ||
morphEl(matchingFromEl, curToNodeChild); | ||
} else { | ||
var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild); | ||
if (onBeforeNodeAddedResult !== false) { | ||
if (onBeforeNodeAddedResult) { | ||
curToNodeChild = onBeforeNodeAddedResult; | ||
} | ||
if (curToNodeChild.actualize) { | ||
curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc); | ||
} | ||
fromEl.appendChild(curToNodeChild); | ||
handleNodeAdded(curToNodeChild); | ||
} | ||
} | ||
curToNodeChild = toNextSibling; | ||
curFromNodeChild = fromNextSibling; | ||
} | ||
// 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; | ||
if ((curFromNodeKey = getNodeKey(curFromNodeChild))) { | ||
// Since the node is keyed it might be matched up later so we defer | ||
@@ -561,129 +603,85 @@ // the actual removal to later | ||
} | ||
curFromNodeChild = fromNextSibling; | ||
} | ||
} | ||
// 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 (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) { | ||
fromEl.appendChild(matchingFromEl); | ||
morphEl(matchingFromEl, curToNodeChild); | ||
} else { | ||
var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild); | ||
if (onBeforeNodeAddedResult !== false) { | ||
if (onBeforeNodeAddedResult) { | ||
curToNodeChild = onBeforeNodeAddedResult; | ||
} | ||
var specialElHandler = specialElHandlers[fromEl.nodeName]; | ||
if (specialElHandler) { | ||
specialElHandler(fromEl, toEl); | ||
} | ||
} // END: morphEl(...) | ||
if (curToNodeChild.actualize) { | ||
curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc); | ||
} | ||
fromEl.appendChild(curToNodeChild); | ||
handleNodeAdded(curToNodeChild); | ||
var morphedNode = fromNode; | ||
var morphedNodeType = morphedNode.nodeType; | ||
var toNodeType = toNode.nodeType; | ||
if (!childrenOnly) { | ||
// Handle the case where we are given two DOM nodes that are not | ||
// compatible (e.g. <div> --> <span> or <div> --> TEXT) | ||
if (morphedNodeType === ELEMENT_NODE) { | ||
if (toNodeType === ELEMENT_NODE) { | ||
if (!compareNodeNames(fromNode, toNode)) { | ||
onNodeDiscarded(fromNode); | ||
morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI)); | ||
} | ||
} else { | ||
// Going from an element node to a text node | ||
morphedNode = toNode; | ||
} | ||
} else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { // Text or comment node | ||
if (toNodeType === morphedNodeType) { | ||
if (morphedNode.nodeValue !== toNode.nodeValue) { | ||
morphedNode.nodeValue = toNode.nodeValue; | ||
} | ||
curToNodeChild = toNextSibling; | ||
curFromNodeChild = fromNextSibling; | ||
} | ||
// 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; | ||
if ((curFromNodeKey = getNodeKey(curFromNodeChild))) { | ||
// Since the node is keyed it might be matched up later so we defer | ||
// the actual removal to later | ||
addKeyedRemoval(curFromNodeKey); | ||
return morphedNode; | ||
} else { | ||
// NOTE: we skip nested keyed nodes from being removed since there is | ||
// still a chance they will be matched up later | ||
removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */); | ||
// Text node to something else | ||
morphedNode = toNode; | ||
} | ||
curFromNodeChild = fromNextSibling; | ||
} | ||
} | ||
var specialElHandler = specialElHandlers[fromEl.nodeName]; | ||
if (specialElHandler) { | ||
specialElHandler(fromEl, toEl); | ||
} | ||
} // END: morphEl(...) | ||
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" | ||
onNodeDiscarded(fromNode); | ||
} else { | ||
morphEl(morphedNode, toNode, childrenOnly); | ||
var morphedNode = fromNode; | ||
var morphedNodeType = morphedNode.nodeType; | ||
var toNodeType = toNode.nodeType; | ||
if (!childrenOnly) { | ||
// Handle the case where we are given two DOM nodes that are not | ||
// compatible (e.g. <div> --> <span> or <div> --> TEXT) | ||
if (morphedNodeType === ELEMENT_NODE) { | ||
if (toNodeType === ELEMENT_NODE) { | ||
if (!compareNodeNames(fromNode, toNode)) { | ||
onNodeDiscarded(fromNode); | ||
morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI)); | ||
// We now need to loop over any keyed nodes that might need to be | ||
// removed. We only do the removal if we know that the keyed node | ||
// never found a match. When a keyed node is matched up we remove | ||
// it out of fromNodesLookup and we use fromNodesLookup to determine | ||
// if a keyed node has been matched up or not | ||
if (keyedRemovalList) { | ||
for (var i=0, len=keyedRemovalList.length; i<len; i++) { | ||
var elToRemove = fromNodesLookup[keyedRemovalList[i]]; | ||
if (elToRemove) { | ||
removeNode(elToRemove, elToRemove.parentNode, false); | ||
} | ||
} | ||
} else { | ||
// Going from an element node to a text node | ||
morphedNode = toNode; | ||
} | ||
} else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { // Text or comment node | ||
if (toNodeType === morphedNodeType) { | ||
if (morphedNode.nodeValue !== toNode.nodeValue) { | ||
morphedNode.nodeValue = toNode.nodeValue; | ||
} | ||
return morphedNode; | ||
} else { | ||
// Text node to something else | ||
morphedNode = toNode; | ||
} | ||
} | ||
} | ||
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" | ||
onNodeDiscarded(fromNode); | ||
} else { | ||
morphEl(morphedNode, toNode, childrenOnly); | ||
// We now need to loop over any keyed nodes that might need to be | ||
// removed. We only do the removal if we know that the keyed node | ||
// never found a match. When a keyed node is matched up we remove | ||
// it out of fromNodesLookup and we use fromNodesLookup to determine | ||
// if a keyed node has been matched up or not | ||
if (keyedRemovalList) { | ||
for (var i=0, len=keyedRemovalList.length; i<len; i++) { | ||
var elToRemove = fromNodesLookup[keyedRemovalList[i]]; | ||
if (elToRemove) { | ||
removeNode(elToRemove, elToRemove.parentNode, false); | ||
} | ||
if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) { | ||
if (morphedNode.actualize) { | ||
morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc); | ||
} | ||
// If we had to swap out the from node with a new node because the old | ||
// node was not compatible with the target node then we need to | ||
// replace the old DOM node in the original DOM tree. This is only | ||
// possible if the original DOM node was part of a DOM tree which | ||
// we know is the case if it has a parent node. | ||
fromNode.parentNode.replaceChild(morphedNode, fromNode); | ||
} | ||
} | ||
if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) { | ||
if (morphedNode.actualize) { | ||
morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc); | ||
} | ||
// If we had to swap out the from node with a new node because the old | ||
// node was not compatible with the target node then we need to | ||
// replace the old DOM node in the original DOM tree. This is only | ||
// possible if the original DOM node was part of a DOM tree which | ||
// we know is the case if it has a parent node. | ||
fromNode.parentNode.replaceChild(morphedNode, fromNode); | ||
} | ||
return morphedNode; | ||
}; | ||
} | ||
return morphedNode; | ||
}; | ||
} | ||
var morphdom = morphdomFactory(morphAttrs); | ||
var morphdom = morphdomFactory(morphAttrs); | ||
return morphdom; | ||
return morphdom; | ||
}))); | ||
})); |
@@ -1,1 +0,1 @@ | ||
(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):global.morphdom=factory()})(this,function(){"use strict";var range;var NS_XHTML="http://www.w3.org/1999/xhtml";var doc=typeof document==="undefined"?undefined:document;var testEl=doc?doc.body||doc.createElement("div"):{};var actualHasAttributeNS;if(testEl.hasAttributeNS){actualHasAttributeNS=function(el,namespaceURI,name){return el.hasAttributeNS(namespaceURI,name)}}else if(testEl.hasAttribute){actualHasAttributeNS=function(el,namespaceURI,name){return el.hasAttribute(name)}}else{actualHasAttributeNS=function(el,namespaceURI,name){return el.getAttributeNode(namespaceURI,name)!=null}}var hasAttributeNS=actualHasAttributeNS;function toElement(str){if(!range&&doc.createRange){range=doc.createRange();range.selectNode(doc.body)}var fragment;if(range&&range.createContextualFragment){fragment=range.createContextualFragment(str)}else{fragment=doc.createElement("body");fragment.innerHTML=str}return fragment.childNodes[0]}function compareNodeNames(fromEl,toEl){var fromNodeName=fromEl.nodeName;var toNodeName=toEl.nodeName;if(fromNodeName===toNodeName){return true}if(toEl.actualize&&fromNodeName.charCodeAt(0)<91&&toNodeName.charCodeAt(0)>90){return fromNodeName===toNodeName.toUpperCase()}else{return false}}function createElementNS(name,namespaceURI){return!namespaceURI||namespaceURI===NS_XHTML?doc.createElement(name):doc.createElementNS(namespaceURI,name)}function moveChildren(fromEl,toEl){var curChild=fromEl.firstChild;while(curChild){var nextChild=curChild.nextSibling;toEl.appendChild(curChild);curChild=nextChild}return toEl}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;attrNamespaceURI=attr.namespaceURI;attrValue=attr.value;if(attrNamespaceURI){attrName=attr.localName||attrName;fromValue=fromNode.getAttributeNS(attrNamespaceURI,attrName);if(fromValue!==attrValue){fromNode.setAttributeNS(attrNamespaceURI,attrName,attrValue)}}else{fromValue=fromNode.getAttribute(attrName);if(fromValue!==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;attrNamespaceURI=attr.namespaceURI;if(attrNamespaceURI){attrName=attr.localName||attrName;if(!hasAttributeNS(toNode,attrNamespaceURI,attrName)){fromNode.removeAttributeNS(attrNamespaceURI,attrName)}}else{if(!hasAttributeNS(toNode,null,attrName)){fromNode.removeAttribute(attrName)}}}}}function syncBooleanAttrProp(fromEl,toEl,name){if(fromEl[name]!==toEl[name]){fromEl[name]=toEl[name];if(fromEl[name]){fromEl.setAttribute(name,"")}else{fromEl.removeAttribute(name,"")}}}var specialElHandlers={OPTION:function(fromEl,toEl){syncBooleanAttrProp(fromEl,toEl,"selected")},INPUT:function(fromEl,toEl){syncBooleanAttrProp(fromEl,toEl,"checked");syncBooleanAttrProp(fromEl,toEl,"disabled");if(fromEl.value!==toEl.value){fromEl.value=toEl.value}if(!hasAttributeNS(toEl,null,"value")){fromEl.removeAttribute("value")}},TEXTAREA:function(fromEl,toEl){var newValue=toEl.value;if(fromEl.value!==newValue){fromEl.value=newValue}var firstChild=fromEl.firstChild;if(firstChild){var oldValue=firstChild.nodeValue;if(oldValue==newValue||!newValue&&oldValue==fromEl.placeholder){return}firstChild.nodeValue=newValue}},SELECT:function(fromEl,toEl){if(!hasAttributeNS(toEl,null,"multiple")){var selectedIndex=-1;var i=0;var curChild=toEl.firstChild;while(curChild){var nodeName=curChild.nodeName;if(nodeName&&nodeName.toUpperCase()==="OPTION"){if(hasAttributeNS(curChild,null,"selected")){selectedIndex=i;break}i++}curChild=curChild.nextSibling}fromEl.selectedIndex=i}}};var ELEMENT_NODE=1;var TEXT_NODE=3;var COMMENT_NODE=8;function noop(){}function defaultGetNodeKey(node){return node.id}function morphdomFactory(morphAttrs){return function morphdom(fromNode,toNode,options){if(!options){options={}}if(typeof toNode==="string"){if(fromNode.nodeName==="#document"||fromNode.nodeName==="HTML"){var toNodeHtml=toNode;toNode=doc.createElement("html");toNode.innerHTML=toNodeHtml}else{toNode=toElement(toNode)}}var getNodeKey=options.getNodeKey||defaultGetNodeKey;var onBeforeNodeAdded=options.onBeforeNodeAdded||noop;var onNodeAdded=options.onNodeAdded||noop;var onBeforeElUpdated=options.onBeforeElUpdated||noop;var onElUpdated=options.onElUpdated||noop;var onBeforeNodeDiscarded=options.onBeforeNodeDiscarded||noop;var onNodeDiscarded=options.onNodeDiscarded||noop;var onBeforeElChildrenUpdated=options.onBeforeElChildrenUpdated||noop;var childrenOnly=options.childrenOnly===true;var fromNodesLookup={};var keyedRemovalList;function addKeyedRemoval(key){if(keyedRemovalList){keyedRemovalList.push(key)}else{keyedRemovalList=[key]}}function walkDiscardedChildNodes(node,skipKeyedNodes){if(node.nodeType===ELEMENT_NODE){var curChild=node.firstChild;while(curChild){var key=undefined;if(skipKeyedNodes&&(key=getNodeKey(curChild))){addKeyedRemoval(key)}else{onNodeDiscarded(curChild);if(curChild.firstChild){walkDiscardedChildNodes(curChild,skipKeyedNodes)}}curChild=curChild.nextSibling}}}function removeNode(node,parentNode,skipKeyedNodes){if(onBeforeNodeDiscarded(node)===false){return}if(parentNode){parentNode.removeChild(node)}onNodeDiscarded(node);walkDiscardedChildNodes(node,skipKeyedNodes)}function indexTree(node){if(node.nodeType===ELEMENT_NODE){var curChild=node.firstChild;while(curChild){var key=getNodeKey(curChild);if(key){fromNodesLookup[key]=curChild}indexTree(curChild);curChild=curChild.nextSibling}}}indexTree(fromNode);function handleNodeAdded(el){onNodeAdded(el);var curChild=el.firstChild;while(curChild){var nextSibling=curChild.nextSibling;var key=getNodeKey(curChild);if(key){var unmatchedFromEl=fromNodesLookup[key];if(unmatchedFromEl&&compareNodeNames(curChild,unmatchedFromEl)){curChild.parentNode.replaceChild(unmatchedFromEl,curChild);morphEl(unmatchedFromEl,curChild)}}handleNodeAdded(curChild);curChild=nextSibling}}function morphEl(fromEl,toEl,childrenOnly){var toElKey=getNodeKey(toEl);var curFromNodeKey;if(toElKey){delete fromNodesLookup[toElKey]}if(toNode.isSameNode&&toNode.isSameNode(fromNode)){return}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 curToNodeKey;var fromNextSibling;var toNextSibling;var matchingFromEl;outer:while(curToNodeChild){toNextSibling=curToNodeChild.nextSibling;curToNodeKey=getNodeKey(curToNodeChild);while(curFromNodeChild){fromNextSibling=curFromNodeChild.nextSibling;if(curToNodeChild.isSameNode&&curToNodeChild.isSameNode(curFromNodeChild)){curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling;continue outer}curFromNodeKey=getNodeKey(curFromNodeChild);var curFromNodeType=curFromNodeChild.nodeType;var isCompatible=undefined;if(curFromNodeType===curToNodeChild.nodeType){if(curFromNodeType===ELEMENT_NODE){if(curToNodeKey){if(curToNodeKey!==curFromNodeKey){if(matchingFromEl=fromNodesLookup[curToNodeKey]){if(curFromNodeChild.nextSibling===matchingFromEl){isCompatible=false}else{fromEl.insertBefore(matchingFromEl,curFromNodeChild);fromNextSibling=curFromNodeChild.nextSibling;if(curFromNodeKey){addKeyedRemoval(curFromNodeKey)}else{removeNode(curFromNodeChild,fromEl,true)}curFromNodeChild=matchingFromEl}}else{isCompatible=false}}}else if(curFromNodeKey){isCompatible=false}isCompatible=isCompatible!==false&&compareNodeNames(curFromNodeChild,curToNodeChild);if(isCompatible){morphEl(curFromNodeChild,curToNodeChild)}}else if(curFromNodeType===TEXT_NODE||curFromNodeType==COMMENT_NODE){isCompatible=true;if(curFromNodeChild.nodeValue!==curToNodeChild.nodeValue){curFromNodeChild.nodeValue=curToNodeChild.nodeValue}}}if(isCompatible){curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling;continue outer}if(curFromNodeKey){addKeyedRemoval(curFromNodeKey)}else{removeNode(curFromNodeChild,fromEl,true)}curFromNodeChild=fromNextSibling}if(curToNodeKey&&(matchingFromEl=fromNodesLookup[curToNodeKey])&&compareNodeNames(matchingFromEl,curToNodeChild)){fromEl.appendChild(matchingFromEl);morphEl(matchingFromEl,curToNodeChild)}else{var onBeforeNodeAddedResult=onBeforeNodeAdded(curToNodeChild);if(onBeforeNodeAddedResult!==false){if(onBeforeNodeAddedResult){curToNodeChild=onBeforeNodeAddedResult}if(curToNodeChild.actualize){curToNodeChild=curToNodeChild.actualize(fromEl.ownerDocument||doc)}fromEl.appendChild(curToNodeChild);handleNodeAdded(curToNodeChild)}}curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling}while(curFromNodeChild){fromNextSibling=curFromNodeChild.nextSibling;if(curFromNodeKey=getNodeKey(curFromNodeChild)){addKeyedRemoval(curFromNodeKey)}else{removeNode(curFromNodeChild,fromEl,true)}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||morphedNodeType===COMMENT_NODE){if(toNodeType===morphedNodeType){if(morphedNode.nodeValue!==toNode.nodeValue){morphedNode.nodeValue=toNode.nodeValue}return morphedNode}else{morphedNode=toNode}}}if(morphedNode===toNode){onNodeDiscarded(fromNode)}else{morphEl(morphedNode,toNode,childrenOnly);if(keyedRemovalList){for(var i=0,len=keyedRemovalList.length;i<len;i++){var elToRemove=fromNodesLookup[keyedRemovalList[i]];if(elToRemove){removeNode(elToRemove,elToRemove.parentNode,false)}}}}if(!childrenOnly&&morphedNode!==fromNode&&fromNode.parentNode){if(morphedNode.actualize){morphedNode=morphedNode.actualize(fromNode.ownerDocument||doc)}fromNode.parentNode.replaceChild(morphedNode,fromNode)}return morphedNode}}var morphdom=morphdomFactory(morphAttrs);return morphdom}); | ||
(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):(global=global||self,global.morphdom=factory())})(this,function(){"use strict";var range;var NS_XHTML="http://www.w3.org/1999/xhtml";var doc=typeof document==="undefined"?undefined:document;var testEl=doc?doc.body||doc.createElement("div"):{};var actualHasAttributeNS;if(testEl.hasAttributeNS){actualHasAttributeNS=function(el,namespaceURI,name){return el.hasAttributeNS(namespaceURI,name)}}else if(testEl.hasAttribute){actualHasAttributeNS=function(el,namespaceURI,name){return el.hasAttribute(name)}}else{actualHasAttributeNS=function(el,namespaceURI,name){return el.getAttributeNode(namespaceURI,name)!=null}}var hasAttributeNS=actualHasAttributeNS;function toElement(str){if(!range&&doc.createRange){range=doc.createRange();range.selectNode(doc.body)}var fragment;if(range&&range.createContextualFragment){fragment=range.createContextualFragment(str)}else{fragment=doc.createElement("body");fragment.innerHTML=str}return fragment.childNodes[0]}function compareNodeNames(fromEl,toEl){var fromNodeName=fromEl.nodeName;var toNodeName=toEl.nodeName;if(fromNodeName===toNodeName){return true}if(toEl.actualize&&fromNodeName.charCodeAt(0)<91&&toNodeName.charCodeAt(0)>90){return fromNodeName===toNodeName.toUpperCase()}else{return false}}function createElementNS(name,namespaceURI){return!namespaceURI||namespaceURI===NS_XHTML?doc.createElement(name):doc.createElementNS(namespaceURI,name)}function moveChildren(fromEl,toEl){var curChild=fromEl.firstChild;while(curChild){var nextChild=curChild.nextSibling;toEl.appendChild(curChild);curChild=nextChild}return toEl}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;attrNamespaceURI=attr.namespaceURI;attrValue=attr.value;if(attrNamespaceURI){attrName=attr.localName||attrName;fromValue=fromNode.getAttributeNS(attrNamespaceURI,attrName);if(fromValue!==attrValue){fromNode.setAttributeNS(attrNamespaceURI,attrName,attrValue)}}else{fromValue=fromNode.getAttribute(attrName);if(fromValue!==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;attrNamespaceURI=attr.namespaceURI;if(attrNamespaceURI){attrName=attr.localName||attrName;if(!hasAttributeNS(toNode,attrNamespaceURI,attrName)){fromNode.removeAttributeNS(attrNamespaceURI,attrName)}}else{if(!hasAttributeNS(toNode,null,attrName)){fromNode.removeAttribute(attrName)}}}}}function syncBooleanAttrProp(fromEl,toEl,name){if(fromEl[name]!==toEl[name]){fromEl[name]=toEl[name];if(fromEl[name]){fromEl.setAttribute(name,"")}else{fromEl.removeAttribute(name)}}}var specialElHandlers={OPTION:function(fromEl,toEl){syncBooleanAttrProp(fromEl,toEl,"selected")},INPUT:function(fromEl,toEl){syncBooleanAttrProp(fromEl,toEl,"checked");syncBooleanAttrProp(fromEl,toEl,"disabled");if(fromEl.value!==toEl.value){fromEl.value=toEl.value}if(!hasAttributeNS(toEl,null,"value")){fromEl.removeAttribute("value")}},TEXTAREA:function(fromEl,toEl){var newValue=toEl.value;if(fromEl.value!==newValue){fromEl.value=newValue}var firstChild=fromEl.firstChild;if(firstChild){var oldValue=firstChild.nodeValue;if(oldValue==newValue||!newValue&&oldValue==fromEl.placeholder){return}firstChild.nodeValue=newValue}},SELECT:function(fromEl,toEl){if(!hasAttributeNS(toEl,null,"multiple")){var i=0;var curChild=toEl.firstChild;while(curChild){var nodeName=curChild.nodeName;if(nodeName&&nodeName.toUpperCase()==="OPTION"){if(hasAttributeNS(curChild,null,"selected")){break}i++}curChild=curChild.nextSibling}fromEl.selectedIndex=i}}};var ELEMENT_NODE=1;var TEXT_NODE=3;var COMMENT_NODE=8;function noop(){}function defaultGetNodeKey(node){return node.id}function morphdomFactory(morphAttrs){return function morphdom(fromNode,toNode,options){if(!options){options={}}if(typeof toNode==="string"){if(fromNode.nodeName==="#document"||fromNode.nodeName==="HTML"){var toNodeHtml=toNode;toNode=doc.createElement("html");toNode.innerHTML=toNodeHtml}else{toNode=toElement(toNode)}}var getNodeKey=options.getNodeKey||defaultGetNodeKey;var onBeforeNodeAdded=options.onBeforeNodeAdded||noop;var onNodeAdded=options.onNodeAdded||noop;var onBeforeElUpdated=options.onBeforeElUpdated||noop;var onElUpdated=options.onElUpdated||noop;var onBeforeNodeDiscarded=options.onBeforeNodeDiscarded||noop;var onNodeDiscarded=options.onNodeDiscarded||noop;var onBeforeElChildrenUpdated=options.onBeforeElChildrenUpdated||noop;var childrenOnly=options.childrenOnly===true;var fromNodesLookup={};var keyedRemovalList;function addKeyedRemoval(key){if(keyedRemovalList){keyedRemovalList.push(key)}else{keyedRemovalList=[key]}}function walkDiscardedChildNodes(node,skipKeyedNodes){if(node.nodeType===ELEMENT_NODE){var curChild=node.firstChild;while(curChild){var key=undefined;if(skipKeyedNodes&&(key=getNodeKey(curChild))){addKeyedRemoval(key)}else{onNodeDiscarded(curChild);if(curChild.firstChild){walkDiscardedChildNodes(curChild,skipKeyedNodes)}}curChild=curChild.nextSibling}}}function removeNode(node,parentNode,skipKeyedNodes){if(onBeforeNodeDiscarded(node)===false){return}if(parentNode){parentNode.removeChild(node)}onNodeDiscarded(node);walkDiscardedChildNodes(node,skipKeyedNodes)}function indexTree(node){if(node.nodeType===ELEMENT_NODE){var curChild=node.firstChild;while(curChild){var key=getNodeKey(curChild);if(key){fromNodesLookup[key]=curChild}indexTree(curChild);curChild=curChild.nextSibling}}}indexTree(fromNode);function handleNodeAdded(el){onNodeAdded(el);var curChild=el.firstChild;while(curChild){var nextSibling=curChild.nextSibling;var key=getNodeKey(curChild);if(key){var unmatchedFromEl=fromNodesLookup[key];if(unmatchedFromEl&&compareNodeNames(curChild,unmatchedFromEl)){curChild.parentNode.replaceChild(unmatchedFromEl,curChild);morphEl(unmatchedFromEl,curChild)}}handleNodeAdded(curChild);curChild=nextSibling}}function morphEl(fromEl,toEl,childrenOnly){var toElKey=getNodeKey(toEl);var curFromNodeKey;if(toElKey){delete fromNodesLookup[toElKey]}if(toNode.isSameNode&&toNode.isSameNode(fromNode)){return}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 curToNodeKey;var fromNextSibling;var toNextSibling;var matchingFromEl;outer:while(curToNodeChild){toNextSibling=curToNodeChild.nextSibling;curToNodeKey=getNodeKey(curToNodeChild);while(curFromNodeChild){fromNextSibling=curFromNodeChild.nextSibling;if(curToNodeChild.isSameNode&&curToNodeChild.isSameNode(curFromNodeChild)){curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling;continue outer}curFromNodeKey=getNodeKey(curFromNodeChild);var curFromNodeType=curFromNodeChild.nodeType;var isCompatible=undefined;if(curFromNodeType===curToNodeChild.nodeType){if(curFromNodeType===ELEMENT_NODE){if(curToNodeKey){if(curToNodeKey!==curFromNodeKey){if(matchingFromEl=fromNodesLookup[curToNodeKey]){if(curFromNodeChild.nextSibling===matchingFromEl){isCompatible=false}else{fromEl.insertBefore(matchingFromEl,curFromNodeChild);fromNextSibling=curFromNodeChild.nextSibling;if(curFromNodeKey){addKeyedRemoval(curFromNodeKey)}else{removeNode(curFromNodeChild,fromEl,true)}curFromNodeChild=matchingFromEl}}else{isCompatible=false}}}else if(curFromNodeKey){isCompatible=false}isCompatible=isCompatible!==false&&compareNodeNames(curFromNodeChild,curToNodeChild);if(isCompatible){morphEl(curFromNodeChild,curToNodeChild)}}else if(curFromNodeType===TEXT_NODE||curFromNodeType==COMMENT_NODE){isCompatible=true;if(curFromNodeChild.nodeValue!==curToNodeChild.nodeValue){curFromNodeChild.nodeValue=curToNodeChild.nodeValue}}}if(isCompatible){curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling;continue outer}if(curFromNodeKey){addKeyedRemoval(curFromNodeKey)}else{removeNode(curFromNodeChild,fromEl,true)}curFromNodeChild=fromNextSibling}if(curToNodeKey&&(matchingFromEl=fromNodesLookup[curToNodeKey])&&compareNodeNames(matchingFromEl,curToNodeChild)){fromEl.appendChild(matchingFromEl);morphEl(matchingFromEl,curToNodeChild)}else{var onBeforeNodeAddedResult=onBeforeNodeAdded(curToNodeChild);if(onBeforeNodeAddedResult!==false){if(onBeforeNodeAddedResult){curToNodeChild=onBeforeNodeAddedResult}if(curToNodeChild.actualize){curToNodeChild=curToNodeChild.actualize(fromEl.ownerDocument||doc)}fromEl.appendChild(curToNodeChild);handleNodeAdded(curToNodeChild)}}curToNodeChild=toNextSibling;curFromNodeChild=fromNextSibling}while(curFromNodeChild){fromNextSibling=curFromNodeChild.nextSibling;if(curFromNodeKey=getNodeKey(curFromNodeChild)){addKeyedRemoval(curFromNodeKey)}else{removeNode(curFromNodeChild,fromEl,true)}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||morphedNodeType===COMMENT_NODE){if(toNodeType===morphedNodeType){if(morphedNode.nodeValue!==toNode.nodeValue){morphedNode.nodeValue=toNode.nodeValue}return morphedNode}else{morphedNode=toNode}}}if(morphedNode===toNode){onNodeDiscarded(fromNode)}else{morphEl(morphedNode,toNode,childrenOnly);if(keyedRemovalList){for(var i=0,len=keyedRemovalList.length;i<len;i++){var elToRemove=fromNodesLookup[keyedRemovalList[i]];if(elToRemove){removeNode(elToRemove,elToRemove.parentNode,false)}}}}if(!childrenOnly&&morphedNode!==fromNode&&fromNode.parentNode){if(morphedNode.actualize){morphedNode=morphedNode.actualize(fromNode.ownerDocument||doc)}fromNode.parentNode.replaceChild(morphedNode,fromNode)}return morphedNode}}var morphdom=morphdomFactory(morphAttrs);return morphdom}); |
@@ -169,3 +169,3 @@ 'use strict'; | ||
} else { | ||
fromEl.removeAttribute(name, ''); | ||
fromEl.removeAttribute(name); | ||
} | ||
@@ -223,3 +223,2 @@ } | ||
if (!hasAttributeNS(toEl, null, 'multiple')) { | ||
var selectedIndex = -1; | ||
var i = 0; | ||
@@ -231,3 +230,2 @@ var curChild = toEl.firstChild; | ||
if (hasAttributeNS(curChild, null, 'selected')) { | ||
selectedIndex = i; | ||
break; | ||
@@ -234,0 +232,0 @@ } |
@@ -5,2 +5,3 @@ { | ||
"main": "dist/morphdom.js", | ||
"types": "./index.d.ts", | ||
"scripts": { | ||
@@ -45,3 +46,3 @@ "build": "npm run rollup && npm run minify", | ||
"phantomjs-prebuilt": "^2.1.13", | ||
"rollup": "^0.39.2", | ||
"rollup": "^1.4.1", | ||
"uglify-js": "^2.6.2", | ||
@@ -53,3 +54,3 @@ "umd": "^3.0.1", | ||
"dependencies": {}, | ||
"version": "2.3.3", | ||
"version": "2.4.0", | ||
"keywords": [ | ||
@@ -56,0 +57,0 @@ "dom", |
@@ -9,3 +9,3 @@ import { hasAttributeNS } from './util'; | ||
} else { | ||
fromEl.removeAttribute(name, ''); | ||
fromEl.removeAttribute(name); | ||
} | ||
@@ -12,0 +12,0 @@ } |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
155773
17
2337
1