can
Version:
MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.
207 lines (206 loc) • 7.59 kB
JavaScript
/*!
* CanJS - 2.3.34
* http://canjs.com/
* Copyright (c) 2018 Bitovi
* Mon, 30 Apr 2018 20:56:51 GMT
* Licensed MIT
*/
/*can@2.3.34#view/node_lists/node_lists*/
define([
'can/util/library',
'can/elements'
], function (can) {
var canExpando = true;
try {
document.createTextNode('')._ = 0;
} catch (ex) {
canExpando = false;
}
var nodeMap = {}, textNodeMap = {}, expando = 'ejs_' + Math.random(), _id = 0, id = function (node, localMap) {
var _textNodeMap = localMap || textNodeMap;
var id = readId(node, _textNodeMap);
if (id) {
return id;
} else {
if (canExpando || node.nodeType !== 3) {
++_id;
return node[expando] = (node.nodeName ? 'element_' : 'obj_') + _id;
} else {
++_id;
_textNodeMap['text_' + _id] = node;
return 'text_' + _id;
}
}
}, readId = function (node, textNodeMap) {
if (canExpando || node.nodeType !== 3) {
return node[expando];
} else {
for (var textNodeID in textNodeMap) {
if (textNodeMap[textNodeID] === node) {
return textNodeID;
}
}
}
}, splice = [].splice, push = [].push, itemsInChildListTree = function (list) {
var count = 0;
for (var i = 0, len = list.length; i < len; i++) {
var item = list[i];
if (item.nodeType) {
count++;
} else {
count += itemsInChildListTree(item);
}
}
return count;
}, replacementMap = function (replacements, idMap) {
var map = {};
for (var i = 0, len = replacements.length; i < len; i++) {
var node = nodeLists.first(replacements[i]);
map[id(node, idMap)] = replacements[i];
}
return map;
}, addUnfoundAsDeepChildren = function (list, rMap, foundIds) {
for (var repId in rMap) {
if (!foundIds[repId]) {
list.newDeepChildren.push(rMap[repId]);
}
}
};
var nodeLists = {
id: id,
update: function (nodeList, newNodes) {
var oldNodes = nodeLists.unregisterChildren(nodeList);
newNodes = can.makeArray(newNodes);
var oldListLength = nodeList.length;
splice.apply(nodeList, [
0,
oldListLength
].concat(newNodes));
if (nodeList.replacements) {
nodeLists.nestReplacements(nodeList);
nodeList.deepChildren = nodeList.newDeepChildren;
nodeList.newDeepChildren = [];
} else {
nodeLists.nestList(nodeList);
}
return oldNodes;
},
nestReplacements: function (list) {
var index = 0, idMap = {}, rMap = replacementMap(list.replacements, idMap), rCount = list.replacements.length, foundIds = {};
while (index < list.length && rCount) {
var node = list[index], nodeId = readId(node, idMap), replacement = rMap[nodeId];
if (replacement) {
list.splice(index, itemsInChildListTree(replacement), replacement);
foundIds[nodeId] = true;
rCount--;
}
index++;
}
if (rCount) {
addUnfoundAsDeepChildren(list, rMap, foundIds);
}
list.replacements = [];
},
nestList: function (list) {
var index = 0;
while (index < list.length) {
var node = list[index], childNodeList = nodeMap[id(node)];
if (childNodeList) {
if (childNodeList !== list) {
list.splice(index, itemsInChildListTree(childNodeList), childNodeList);
}
} else {
nodeMap[id(node)] = list;
}
index++;
}
},
last: function (nodeList) {
var last = nodeList[nodeList.length - 1];
if (last.nodeType) {
return last;
} else {
return nodeLists.last(last);
}
},
first: function (nodeList) {
var first = nodeList[0];
if (first.nodeType) {
return first;
} else {
return nodeLists.first(first);
}
},
flatten: function (nodeList) {
var items = [];
for (var i = 0; i < nodeList.length; i++) {
var item = nodeList[i];
if (item.nodeType) {
items.push(item);
} else {
items.push.apply(items, nodeLists.flatten(item));
}
}
return items;
},
register: function (nodeList, unregistered, parent, directlyNested) {
can.cid(nodeList);
nodeList.unregistered = unregistered;
nodeList.parentList = parent;
nodeList.nesting = parent && typeof parent.nesting !== 'undefined' ? parent.nesting + 1 : 0;
if (parent) {
nodeList.deepChildren = [];
nodeList.newDeepChildren = [];
nodeList.replacements = [];
if (parent !== true) {
if (directlyNested) {
parent.replacements.push(nodeList);
} else {
parent.newDeepChildren.push(nodeList);
}
}
} else {
nodeLists.nestList(nodeList);
}
return nodeList;
},
unregisterChildren: function (nodeList) {
var nodes = [];
can.each(nodeList, function (node) {
if (node.nodeType) {
if (!nodeList.replacements) {
delete nodeMap[id(node)];
}
nodes.push(node);
} else {
push.apply(nodes, nodeLists.unregister(node, true));
}
});
can.each(nodeList.deepChildren, function (nodeList) {
nodeLists.unregister(nodeList, true);
});
return nodes;
},
unregister: function (nodeList, isChild) {
var nodes = nodeLists.unregisterChildren(nodeList, true);
if (nodeList.unregistered) {
var unregisteredCallback = nodeList.unregistered;
nodeList.replacements = nodeList.unregistered = null;
if (!isChild) {
var deepChildren = nodeList.parentList && nodeList.parentList.deepChildren;
if (deepChildren) {
var index = deepChildren.indexOf(nodeList);
if (index !== -1) {
deepChildren.splice(index, 1);
}
}
}
unregisteredCallback();
}
return nodes;
},
nodeMap: nodeMap
};
can.view.nodeLists = nodeLists;
return nodeLists;
});