]> source.dussan.org Git - archiva.git/commitdiff
upgrade Knockout to v2.0.0rc3
authorOlivier Lamy <olamy@apache.org>
Wed, 21 Dec 2011 09:07:25 +0000 (09:07 +0000)
committerOlivier Lamy <olamy@apache.org>
Wed, 21 Dec 2011 09:07:25 +0000 (09:07 +0000)
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1221654 13f79535-47bb-0310-9956-ffa450edef68

archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-debug.js

index 33bf0624a3f913d23dabd96b0c219b3f6cc5233a..4114c81361a280bbca2e73c65eda11b9424c5386 100644 (file)
@@ -1,4 +1,4 @@
-// Knockout JavaScript library v1.3.0rc\r
+// Knockout JavaScript library v2.0.0rc3\r
 // (c) Steven Sanderson - http://knockoutjs.com/\r
 // License: MIT (http://www.opensource.org/licenses/mit-license.php)\r
 \r
@@ -294,17 +294,34 @@ ko.utils = new (function () {
         },\r
 \r
         outerHTML: function(node) {\r
-            // For IE and Chrome\r
-            var nativeOuterHtml = node.outerHTML;\r
-            if (typeof nativeOuterHtml == "string")\r
-                return nativeOuterHtml;\r
-            \r
+            // For Chrome on non-text nodes\r
+            // (Although IE supports outerHTML, the way it formats HTML is inconsistent - sometimes closing </li> tags are omitted, sometimes not. That caused https://github.com/SteveSanderson/knockout/issues/212.)\r
+            if (ieVersion === undefined) {\r
+                var nativeOuterHtml = node.outerHTML;\r
+                if (typeof nativeOuterHtml == "string")\r
+                    return nativeOuterHtml;\r
+            }\r
+\r
             // Other browsers\r
             var dummyContainer = window.document.createElement("div");\r
             dummyContainer.appendChild(node.cloneNode(true));\r
             return dummyContainer.innerHTML;\r
         },\r
 \r
+        setTextContent: function(element, textContent) {\r
+            var value = ko.utils.unwrapObservable(textContent);\r
+            if ((value === null) || (value === undefined))\r
+                value = "";\r
+\r
+            'innerText' in element ? element.innerText = value\r
+                                   : element.textContent = value;\r
+                                   \r
+            if (ieVersion) {\r
+                // Believe it or not, this actually fixes an IE9 rendering bug. Insane. https://github.com/SteveSanderson/knockout/issues/209\r
+                element.innerHTML = element.innerHTML;\r
+            }\r
+        },\r
+\r
         range: function (min, max) {\r
             min = ko.utils.unwrapObservable(min);\r
             max = ko.utils.unwrapObservable(max);\r
@@ -398,25 +415,29 @@ ko.utils = new (function () {
 })();\r
 \r
 ko.exportSymbol('ko.utils', ko.utils);\r
-ko.exportSymbol('ko.utils.arrayForEach', ko.utils.arrayForEach);\r
-ko.exportSymbol('ko.utils.arrayFirst', ko.utils.arrayFirst);\r
-ko.exportSymbol('ko.utils.arrayFilter', ko.utils.arrayFilter);\r
-ko.exportSymbol('ko.utils.arrayGetDistinctValues', ko.utils.arrayGetDistinctValues);\r
-ko.exportSymbol('ko.utils.arrayIndexOf', ko.utils.arrayIndexOf);\r
-ko.exportSymbol('ko.utils.arrayMap', ko.utils.arrayMap);\r
-ko.exportSymbol('ko.utils.arrayPushAll', ko.utils.arrayPushAll);\r
-ko.exportSymbol('ko.utils.arrayRemoveItem', ko.utils.arrayRemoveItem);\r
-ko.exportSymbol('ko.utils.extend', ko.utils.extend);\r
-ko.exportSymbol('ko.utils.fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost);\r
-ko.exportSymbol('ko.utils.getFormFields', ko.utils.getFormFields);\r
-ko.exportSymbol('ko.utils.postJson', ko.utils.postJson);\r
-ko.exportSymbol('ko.utils.parseJson', ko.utils.parseJson);\r
-ko.exportSymbol('ko.utils.registerEventHandler', ko.utils.registerEventHandler);\r
-ko.exportSymbol('ko.utils.stringifyJson', ko.utils.stringifyJson);\r
-ko.exportSymbol('ko.utils.range', ko.utils.range);\r
-ko.exportSymbol('ko.utils.toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass);\r
-ko.exportSymbol('ko.utils.triggerEvent', ko.utils.triggerEvent);\r
-ko.exportSymbol('ko.utils.unwrapObservable', ko.utils.unwrapObservable);\r
+ko.utils.arrayForEach([\r
+    ['arrayForEach', ko.utils.arrayForEach],\r
+    ['arrayFirst', ko.utils.arrayFirst],\r
+    ['arrayFilter', ko.utils.arrayFilter],\r
+    ['arrayGetDistinctValues', ko.utils.arrayGetDistinctValues],\r
+    ['arrayIndexOf', ko.utils.arrayIndexOf],\r
+    ['arrayMap', ko.utils.arrayMap],\r
+    ['arrayPushAll', ko.utils.arrayPushAll],\r
+    ['arrayRemoveItem', ko.utils.arrayRemoveItem],\r
+    ['extend', ko.utils.extend],\r
+    ['fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost],\r
+    ['getFormFields', ko.utils.getFormFields],\r
+    ['postJson', ko.utils.postJson],\r
+    ['parseJson', ko.utils.parseJson],\r
+    ['registerEventHandler', ko.utils.registerEventHandler],\r
+    ['stringifyJson', ko.utils.stringifyJson],\r
+    ['range', ko.utils.range],\r
+    ['toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass],\r
+    ['triggerEvent', ko.utils.triggerEvent],\r
+    ['unwrapObservable', ko.utils.unwrapObservable]\r
+], function(item) {\r
+    ko.exportSymbol('ko.utils.' + item[0], item[1]);\r
+});\r
 \r
 if (!Function.prototype['bind']) {\r
     // Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf)\r
@@ -580,9 +601,28 @@ ko.exportSymbol('ko.utils.domNodeDisposal.removeDisposeCallback', ko.utils.domNo
 \r
         return ko.utils.makeArray(div.lastChild.childNodes);\r
     }\r
+\r
+    function jQueryHtmlParse(html) {\r
+        var elems = jQuery['clean']([html]);\r
+\r
+        // As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment.\r
+        // Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time.\r
+        // Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment.\r
+        if (elems && elems[0]) {\r
+            // Find the top-most parent element that's a direct child of a document fragment\r
+            var elem = elems[0];\r
+            while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */)\r
+                elem = elem.parentNode;\r
+            // ... then detach it\r
+            if (elem.parentNode)\r
+                elem.parentNode.removeChild(elem);\r
+        }\r
+        \r
+        return elems;\r
+    }\r
     \r
     ko.utils.parseHtmlFragment = function(html) {\r
-        return typeof jQuery != 'undefined' ? jQuery['clean']([html]) // As below, benefit from jQuery's optimisations where possible\r
+        return typeof jQuery != 'undefined' ? jQueryHtmlParse(html)   // As below, benefit from jQuery's optimisations where possible\r
                                             : simpleHtmlParse(html);  // ... otherwise, this simple logic will do in most common cases.\r
     };\r
     \r
@@ -699,6 +739,13 @@ ko.extenders = {
                 }, timeout);                \r
             }\r
         });\r
+    },\r
+\r
+    'notify': function(target, notifyWhen) {\r
+        target["equalityComparer"] = notifyWhen == "always" \r
+            ? function() { return false } // Treat all values as not equal\r
+            : ko.observable["fn"]["equalityComparer"];\r
+        return target;\r
     }\r
 };\r
 \r
@@ -732,7 +779,6 @@ ko.subscribable = function () {
     ko.utils.extend(this, ko.subscribable['fn']);\r
     ko.exportProperty(this, 'subscribe', this.subscribe);\r
     ko.exportProperty(this, 'extend', this.extend);\r
-    ko.exportProperty(this, 'notifySubscribers', this.notifySubscribers);\r
     ko.exportProperty(this, 'getSubscriptionsCount', this.getSubscriptionsCount);\r
 }\r
 \r
@@ -753,7 +799,7 @@ ko.subscribable['fn'] = {
         return subscription;\r
     },\r
 \r
-    notifySubscribers: function (valueToNotify, event) {\r
+    "notifySubscribers": function (valueToNotify, event) {\r
         event = event || defaultEvent;\r
         if (this._subscriptions[event]) {\r
             ko.utils.arrayForEach(this._subscriptions[event].slice(0), function (subscription) {\r
@@ -779,7 +825,7 @@ ko.subscribable['fn'] = {
 \r
 \r
 ko.isSubscribable = function (instance) {\r
-    return typeof instance.subscribe == "function" && typeof instance.notifySubscribers == "function";\r
+    return typeof instance.subscribe == "function" && typeof instance["notifySubscribers"] == "function";\r
 };\r
 \r
 ko.exportSymbol('ko.subscribable', ko.subscribable);\r
@@ -833,8 +879,8 @@ ko.observable = function (initialValue) {
         }\r
     }\r
     ko.subscribable.call(observable);\r
-    observable.valueHasMutated = function () { observable.notifySubscribers(_latestValue); }\r
-    observable.valueWillMutate = function () { observable.notifySubscribers(_latestValue, "beforeChange"); }\r
+    observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); }\r
+    observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }\r
     ko.utils.extend(observable, ko.observable['fn']);\r
 \r
     ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated);\r
@@ -1066,13 +1112,13 @@ ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunction
             });\r
             var valueForThis = options["owner"] || evaluatorFunctionTarget; // If undefined, it will default to "window" by convention. This might change in the future.\r
             var newValue = options["read"].call(valueForThis);\r
-            dependentObservable.notifySubscribers(_latestValue, "beforeChange");\r
+            dependentObservable["notifySubscribers"](_latestValue, "beforeChange");\r
             _latestValue = newValue;\r
         } finally {\r
             ko.dependencyDetection.end();\r
         }\r
 \r
-        dependentObservable.notifySubscribers(_latestValue);\r
+        dependentObservable["notifySubscribers"](_latestValue);\r
         _hasBeenEvaluated = true;\r
     }\r
 \r
@@ -1207,13 +1253,15 @@ ko.exportSymbol('ko.computed', ko.dependentObservable); // Make "ko.computed" an
 \r
 ko.exportSymbol('ko.toJS', ko.toJS);\r
 ko.exportSymbol('ko.toJSON', ko.toJSON);(function () {\r
+    var hasDomDataExpandoProperty = '__ko__hasDomDataOptionValue__';\r
+\r
     // Normally, SELECT elements and their OPTIONs can only take value of type 'string' (because the values\r
     // are stored on DOM attributes). ko.selectExtensions provides a way for SELECTs/OPTIONs to have values\r
     // that are arbitrary objects. This is very convenient when implementing things like cascading dropdowns.\r
     ko.selectExtensions = {\r
         readValue : function(element) {\r
             if (element.tagName == 'OPTION') {\r
-                if (element['__ko__hasDomDataOptionValue__'] === true)\r
+                if (element[hasDomDataExpandoProperty] === true)\r
                     return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey);\r
                 return element.getAttribute("value");\r
             } else if (element.tagName == 'SELECT')\r
@@ -1226,18 +1274,19 @@ ko.exportSymbol('ko.toJSON', ko.toJSON);(function () {
             if (element.tagName == 'OPTION') {\r
                 switch(typeof value) {\r
                     case "string":\r
-                    case "number":\r
                         ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined);\r
-                        if ('__ko__hasDomDataOptionValue__' in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node\r
-                            delete element['__ko__hasDomDataOptionValue__'];\r
+                        if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node\r
+                            delete element[hasDomDataExpandoProperty];\r
                         }\r
                         element.value = value;                                   \r
                         break;\r
                     default:\r
                         // Store arbitrary object using DomData\r
                         ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value);\r
-                        element['__ko__hasDomDataOptionValue__'] = true;\r
-                        element.value = "";\r
+                        element[hasDomDataExpandoProperty] = true;\r
+\r
+                        // Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value.\r
+                        element.value = typeof value === "number" ? value : "";\r
                         break;\r
                 }                      \r
             } else if (element.tagName == 'SELECT') {\r
@@ -1894,7 +1943,10 @@ ko.bindingHandlers['event'] = {
                         var allBindings = allBindingsAccessor();\r
                         \r
                         try { \r
-                            handlerReturnValue = handlerFunction.apply(viewModel, arguments);                          \r
+                            // Take all the event args, and prefix with the viewmodel\r
+                            var argsForHandler = ko.utils.makeArray(arguments);\r
+                            argsForHandler.unshift(viewModel);\r
+                            handlerReturnValue = handlerFunction.apply(viewModel, argsForHandler);\r
                         } finally {\r
                             if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.\r
                                 if (event.preventDefault)\r
@@ -1920,7 +1972,7 @@ ko.bindingHandlers['event'] = {
 ko.bindingHandlers['submit'] = {\r
     'init': function (element, valueAccessor, allBindingsAccessor, viewModel) {\r
         if (typeof valueAccessor() != "function")\r
-            throw new Error("The value for a submit binding must be a function to invoke on submit");\r
+            throw new Error("The value for a submit binding must be a function");\r
         ko.utils.registerEventHandler(element, "submit", function (event) {\r
             var handlerReturnValue;\r
             var value = valueAccessor();\r
@@ -2057,6 +2109,7 @@ ko.bindingHandlers['options'] = {
             return ko.selectExtensions.readValue(node) || node.innerText || node.textContent;\r
         });\r
         var previousScrollTop = element.scrollTop;\r
+        element.scrollTop = 0; // Workaround for a Chrome rendering bug. Note that we restore the scroll position later. (https://github.com/SteveSanderson/knockout/issues/215)\r
 \r
         var value = ko.utils.unwrapObservable(valueAccessor());\r
         var selectedValue = element.value;\r
@@ -2097,9 +2150,8 @@ ko.bindingHandlers['options'] = {
                     optionText = optionValue;                           // Given no optionsText arg; use the data value itself\r
                 if ((optionText === null) || (optionText === undefined))\r
                     optionText = "";                                    \r
-                optionText = ko.utils.unwrapObservable(optionText).toString();\r
-                typeof option.innerText == "string" ? option.innerText = optionText\r
-                                                    : option.textContent = optionText;\r
+\r
+                ko.utils.setTextContent(option, optionText);\r
 \r
                 element.appendChild(option);\r
             }\r
@@ -2127,7 +2179,7 @@ ko.bindingHandlers['options'] = {
         }\r
     }\r
 };\r
-ko.bindingHandlers['options'].optionValueDomDataKey = '__ko.bindingHandlers.options.optionValueDomData__';\r
+ko.bindingHandlers['options'].optionValueDomDataKey = '__ko.optionValueDomData__';\r
 \r
 ko.bindingHandlers['selectedOptions'] = {\r
     getSelectedValuesFromSelectNode: function (selectNode) {\r
@@ -2170,11 +2222,7 @@ ko.bindingHandlers['selectedOptions'] = {
 \r
 ko.bindingHandlers['text'] = {\r
     'update': function (element, valueAccessor) {\r
-        var value = ko.utils.unwrapObservable(valueAccessor());\r
-        if ((value === null) || (value === undefined))\r
-            value = "";\r
-        typeof element.innerText == "string" ? element.innerText = value\r
-                                             : element.textContent = value;\r
+        ko.utils.setTextContent(element, valueAccessor());\r
     }\r
 };\r
 \r
@@ -2435,11 +2483,11 @@ ko.exportSymbol('ko.allowedVirtualElementBindings', ko.virtualElements.allowedBi
 ko.templateEngine = function () { };\r
 \r
 ko.templateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) {\r
-    throw "Override renderTemplateSource in your ko.templateEngine subclass";\r
+    throw "Override renderTemplateSource";\r
 };\r
 \r
 ko.templateEngine.prototype['createJavaScriptEvaluatorBlock'] = function (script) {\r
-    throw "Override createJavaScriptEvaluatorBlock in your ko.templateEngine subclass";    \r
+    throw "Override createJavaScriptEvaluatorBlock";\r
 };\r
 \r
 ko.templateEngine.prototype['makeTemplateSource'] = function(template) {\r
@@ -2453,7 +2501,7 @@ ko.templateEngine.prototype['makeTemplateSource'] = function(template) {
         // Anonymous template\r
         return new ko.templateSources.anonymousTemplate(template);\r
     } else\r
-        throw new Error("Unrecognised template type: " + template);\r
+        throw new Error("Unknown template type: " + template);\r
 };\r
 \r
 ko.templateEngine.prototype['renderTemplate'] = function (template, bindingContext, options) {\r
@@ -2805,12 +2853,11 @@ ko.exportSymbol('ko.templateRewriting.applyMemoizedBindingsToNextSibling', ko.te
             \r
             var templateSubscription = null;\r
             \r
-            if (typeof bindingValue['foreach'] != "undefined") {\r
+            if ((typeof bindingValue === 'object') && ('foreach' in bindingValue)) { // Note: can't use 'in' operator on strings\r
                 // Render once for each data point (treating data set as empty if shouldDisplay==false)\r
                 var dataArray = (shouldDisplay && bindingValue['foreach']) || [];\r
                 templateSubscription = ko.renderTemplateForEach(templateName || element, dataArray, /* options: */ bindingValue, element, bindingContext);\r
-            }\r
-            else {\r
+            } else {\r
                 if (shouldDisplay) {\r
                     // Render once for this single data point (or use the viewModel if no data was provided)\r
                     var innerBindingContext = (typeof bindingValue == 'object') && ('data' in bindingValue)\r