mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-25 18:19:22 +03:00
92 lines
3.7 KiB
JavaScript
92 lines
3.7 KiB
JavaScript
|
|
ko.utils.domNodeDisposal = new (function () {
|
|
var domDataKey = ko.utils.domData.nextKey();
|
|
var cleanableNodeTypes = { 1: true, 8: true, 9: true }; // Element, Comment, Document
|
|
var cleanableNodeTypesWithDescendants = { 1: true, 9: true }; // Element, Document
|
|
|
|
function getDisposeCallbacksCollection(node, createIfNotFound) {
|
|
var allDisposeCallbacks = ko.utils.domData.get(node, domDataKey);
|
|
if ((allDisposeCallbacks === undefined) && createIfNotFound) {
|
|
allDisposeCallbacks = [];
|
|
ko.utils.domData.set(node, domDataKey, allDisposeCallbacks);
|
|
}
|
|
return allDisposeCallbacks;
|
|
}
|
|
function destroyCallbacksCollection(node) {
|
|
ko.utils.domData.set(node, domDataKey, undefined);
|
|
}
|
|
|
|
function cleanSingleNode(node) {
|
|
// Run all the dispose callbacks
|
|
var callbacks = getDisposeCallbacksCollection(node, false);
|
|
if (callbacks) {
|
|
callbacks = callbacks.slice(0); // Clone, as the array may be modified during iteration (typically, callbacks will remove themselves)
|
|
for (var i = 0; i < callbacks.length; i++)
|
|
callbacks[i](node);
|
|
}
|
|
|
|
// Erase the DOM data
|
|
ko.utils.domData.clear(node);
|
|
|
|
// Clear any immediate-child comment nodes, as these wouldn't have been found by
|
|
// node.getElementsByTagName("*") in cleanNode() (comment nodes aren't elements)
|
|
if (cleanableNodeTypesWithDescendants[node.nodeType]) {
|
|
cleanNodesInList(node.childNodes, true/*onlyComments*/);
|
|
}
|
|
}
|
|
|
|
function cleanNodesInList(nodeList, onlyComments) {
|
|
var cleanedNodes = [], lastCleanedNode;
|
|
for (var i = 0; i < nodeList.length; i++) {
|
|
if (!onlyComments || nodeList[i].nodeType === 8) {
|
|
cleanSingleNode(cleanedNodes[cleanedNodes.length] = lastCleanedNode = nodeList[i]);
|
|
if (nodeList[i] !== lastCleanedNode) {
|
|
while (i-- && !cleanedNodes.includes(nodeList[i]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
addDisposeCallback : (node, callback) => {
|
|
if (typeof callback != "function")
|
|
throw new Error("Callback must be a function");
|
|
getDisposeCallbacksCollection(node, true).push(callback);
|
|
},
|
|
|
|
removeDisposeCallback : (node, callback) => {
|
|
var callbacksCollection = getDisposeCallbacksCollection(node, false);
|
|
if (callbacksCollection) {
|
|
ko.utils.arrayRemoveItem(callbacksCollection, callback);
|
|
if (callbacksCollection.length == 0)
|
|
destroyCallbacksCollection(node);
|
|
}
|
|
},
|
|
|
|
cleanNode : node => {
|
|
ko.dependencyDetection.ignore(() => {
|
|
// First clean this node, where applicable
|
|
if (cleanableNodeTypes[node.nodeType]) {
|
|
cleanSingleNode(node);
|
|
|
|
// ... then its descendants, where applicable
|
|
if (cleanableNodeTypesWithDescendants[node.nodeType]) {
|
|
cleanNodesInList(node.getElementsByTagName("*"));
|
|
}
|
|
}
|
|
});
|
|
|
|
return node;
|
|
},
|
|
|
|
removeNode : node => {
|
|
ko.cleanNode(node);
|
|
if (node.parentNode)
|
|
node.parentNode.removeChild(node);
|
|
}
|
|
};
|
|
})();
|
|
ko.cleanNode = ko.utils.domNodeDisposal.cleanNode; // Shorthand name for convenience
|
|
ko.removeNode = ko.utils.domNodeDisposal.removeNode; // Shorthand name for convenience
|
|
ko.exportSymbol('utils.domNodeDisposal', ko.utils.domNodeDisposal);
|
|
ko.exportSymbol('utils.domNodeDisposal.addDisposeCallback', ko.utils.domNodeDisposal.addDisposeCallback);
|