2 ko.memoization = (function () {
5 function randomMax8HexChars() {
6 return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1);
8 function generateRandomId() {
9 return randomMax8HexChars() + randomMax8HexChars();
11 function findMemoNodes(rootNode, appendToArray) {
14 if (rootNode.nodeType == 8) {
15 var memoId = ko.memoization.parseMemoText(rootNode.nodeValue);
17 appendToArray.push({ domNode: rootNode, memoId: memoId });
18 } else if (rootNode.nodeType == 1) {
19 for (var i = 0, childNodes = rootNode.childNodes, j = childNodes.length; i < j; i++)
20 findMemoNodes(childNodes[i], appendToArray);
25 memoize: function (callback) {
26 if (typeof callback != "function")
27 throw new Error("You can only pass a function to ko.memoization.memoize()");
28 var memoId = generateRandomId();
29 memos[memoId] = callback;
30 return "<!--[ko_memo:" + memoId + "]-->";
33 unmemoize: function (memoId, callbackParams) {
34 var callback = memos[memoId];
35 if (callback === undefined)
36 throw new Error("Couldn't find any memo with ID " + memoId + ". Perhaps it's already been unmemoized.");
38 callback.apply(null, callbackParams || []);
41 finally { delete memos[memoId]; }
44 unmemoizeDomNodeAndDescendants: function (domNode, extraCallbackParamsArray) {
46 findMemoNodes(domNode, memos);
47 for (var i = 0, j = memos.length; i < j; i++) {
48 var node = memos[i].domNode;
49 var combinedParams = [node];
50 if (extraCallbackParamsArray)
51 ko.utils.arrayPushAll(combinedParams, extraCallbackParamsArray);
52 ko.memoization.unmemoize(memos[i].memoId, combinedParams);
53 node.nodeValue = ""; // Neuter this node so we don't try to unmemoize it again
55 node.parentNode.removeChild(node); // If possible, erase it totally (not always possible - someone else might just hold a reference to it then call unmemoizeDomNodeAndDescendants again)
59 parseMemoText: function (memoText) {
60 var match = memoText.match(/^\[ko_memo\:(.*?)\]$/);
61 return match ? match[1] : null;
66 ko.exportSymbol('memoization', ko.memoization);
67 ko.exportSymbol('memoization.memoize', ko.memoization.memoize);
68 ko.exportSymbol('memoization.unmemoize', ko.memoization.unmemoize);
69 ko.exportSymbol('memoization.parseMemoText', ko.memoization.parseMemoText);
70 ko.exportSymbol('memoization.unmemoizeDomNodeAndDescendants', ko.memoization.unmemoizeDomNodeAndDescendants);