From 9ec06cd3e5ebad2bad80ad8233b06a04f8fdc352 Mon Sep 17 00:00:00 2001 From: Andre Gregori Date: Wed, 17 Feb 2016 10:05:17 -0600 Subject: [PATCH] Pull request 201: See https://github.com/SteveSanderson/knockout.mapping/pull/201 --- .gitignore | 3 +- HISTORY.md | 0 LICENSE | 0 Package.nuspec | 0 README.md | 2 +- build/build-linux | 0 build/output/knockout.mapping-latest.debug.js | 274 ++++++++++-------- build/output/knockout.mapping-latest.js | 20 +- build/tools/curl.exe | Bin build/tools/searchReplace.js | 0 build/version-header.js | 0 knockout.mapping.js | 59 +++- spec/issues.js | 0 spec/lib/json2.js | 0 spec/lib/qunit-1.10.0.css | 0 spec/lib/qunit-1.10.0.js | 0 spec/mappingBehaviors.js | 0 spec/proxyDependentObservableBehaviors.js | 0 spec/runner.html | 0 19 files changed, 201 insertions(+), 157 deletions(-) mode change 100644 => 100755 HISTORY.md mode change 100644 => 100755 LICENSE mode change 100644 => 100755 Package.nuspec mode change 100644 => 100755 README.md mode change 100644 => 100755 build/build-linux mode change 100644 => 100755 build/output/knockout.mapping-latest.debug.js mode change 100644 => 100755 build/output/knockout.mapping-latest.js mode change 100644 => 100755 build/tools/curl.exe mode change 100644 => 100755 build/tools/searchReplace.js mode change 100644 => 100755 build/version-header.js mode change 100644 => 100755 knockout.mapping.js mode change 100644 => 100755 spec/issues.js mode change 100644 => 100755 spec/lib/json2.js mode change 100644 => 100755 spec/lib/qunit-1.10.0.css mode change 100644 => 100755 spec/lib/qunit-1.10.0.js mode change 100644 => 100755 spec/mappingBehaviors.js mode change 100644 => 100755 spec/proxyDependentObservableBehaviors.js mode change 100644 => 100755 spec/runner.html diff --git a/.gitignore b/.gitignore index 0d2e3f3..b2de40b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ _ReSharper* *.ReSharper.user *.ReSharper desktop.ini -.eprj \ No newline at end of file +.eprj +.DS_Store diff --git a/HISTORY.md b/HISTORY.md old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Package.nuspec b/Package.nuspec old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 153f239..314fc92 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ Object mapping plugin for [Knockout](http://knockoutjs.com/) - Find the documentation [here](http://knockoutjs.com/documentation/plugins-mapping.html). READ THIS --- -Due to lack of time this project is currently not actively maintained. Feel free to be a hero-- step up and [fork this repo](https://github.com/SteveSanderson/knockout.mapping/fork)! +Due to lack of time this project was no longer actively maintained by the original author. I've forked it to keep it up to date. diff --git a/build/build-linux b/build/build-linux old mode 100644 new mode 100755 diff --git a/build/output/knockout.mapping-latest.debug.js b/build/output/knockout.mapping-latest.debug.js old mode 100644 new mode 100755 index 00c3691..caff37f --- a/build/output/knockout.mapping-latest.debug.js +++ b/build/output/knockout.mapping-latest.debug.js @@ -1,6 +1,3 @@ -/// Knockout Mapping plugin v2.4.1 -/// (c) 2013 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/ -/// License: MIT (http://www.opensource.org/licenses/mit-license.php) (function (factory) { // Module systems magic dance. @@ -32,16 +29,25 @@ }; var defaultOptions = _defaultOptions; - // Author: KennyTM @ StackOverflow - function unionArrays (x, y) { - var obj = {}; - for (var i = x.length - 1; i >= 0; -- i) obj[x[i]] = x[i]; - for (var i = y.length - 1; i >= 0; -- i) obj[y[i]] = y[i]; - var res = []; - - for (var k in obj) { - res.push(obj[k]); - }; + function unionArrays() { + var args = arguments, + l = args.length, + obj = {}, + res = [], + i, j, k; + + while (l--) { + k = args[l]; + i = k.length; + + while (i--) { + j = k[i]; + if (!obj[j]) { + obj[j] = 1; + res.push(j); + } + } + } return res; } @@ -120,7 +126,7 @@ var DO = dependentObservables.pop(); if (DO) { DO(); - + // Move this magic property to the underlying dependent observable DO.__DO["throttleEvaluation"] = DO["throttleEvaluation"]; } @@ -185,7 +191,8 @@ defaultOptions = { include: _defaultOptions.include.slice(0), ignore: _defaultOptions.ignore.slice(0), - copy: _defaultOptions.copy.slice(0) + copy: _defaultOptions.copy.slice(0), + observe: _defaultOptions.observe.slice(0) }; }; @@ -203,10 +210,10 @@ // Move recognized root-level properties into a root namespace for (var i = recognizedRootProperties.length - 1; i >= 0; i--) { var property = recognizedRootProperties[i]; - + // Carry on, unless this property is present if (!options[property]) continue; - + // Move the property into the root namespace if (!(options[""] instanceof Object)) options[""] = {}; options[""][property] = options[property]; @@ -283,7 +290,7 @@ wrapped.__DO = DO; return wrapped; }; - + options.deferEvaluation = true; // will either set for just options, or both read/options. var realDependentObservable = new realKoDependentObservable(read, owner, options); @@ -324,7 +331,7 @@ var createCallback = function (data) { return withProxyDependentObservable(dependentObservables, function () { - + if (ko.utils.unwrapObservable(parent) instanceof Array) { return options[parentName].create({ data: data || callbackParams.data, @@ -336,7 +343,7 @@ data: data || callbackParams.data, parent: callbackParams.parent }); - } + } }); }; @@ -369,44 +376,44 @@ // For atomic types, do a direct update on the observable if (!canHaveProperties(rootObject)) { switch (exports.getType(rootObject)) { - case "function": - if (hasUpdateCallback()) { - if (ko.isWriteableObservable(rootObject)) { - rootObject(updateCallback(rootObject)); - mappedRootObject = rootObject; - } else { - mappedRootObject = updateCallback(rootObject); - } - } else { - mappedRootObject = rootObject; - } - break; - default: - if (ko.isWriteableObservable(mappedRootObject)) { + case "function": if (hasUpdateCallback()) { - var valueToWrite = updateCallback(mappedRootObject); - mappedRootObject(valueToWrite); - return valueToWrite; + if (ko.isWriteableObservable(rootObject)) { + rootObject(updateCallback(rootObject)); + mappedRootObject = rootObject; + } else { + mappedRootObject = updateCallback(rootObject); + } } else { - var valueToWrite = ko.utils.unwrapObservable(rootObject); - mappedRootObject(valueToWrite); - return valueToWrite; + mappedRootObject = rootObject; } - } else { - var hasCreateOrUpdateCallback = hasCreateCallback() || hasUpdateCallback(); - - if (hasCreateCallback()) { - mappedRootObject = createCallback(); + break; + default: + if (ko.isWriteableObservable(mappedRootObject)) { + if (hasUpdateCallback()) { + var valueToWrite = updateCallback(mappedRootObject); + mappedRootObject(valueToWrite); + return valueToWrite; + } else { + var valueToWrite = ko.utils.unwrapObservable(rootObject); + mappedRootObject(valueToWrite); + return valueToWrite; + } } else { - mappedRootObject = ko.observable(ko.utils.unwrapObservable(rootObject)); - } + var hasCreateOrUpdateCallback = hasCreateCallback() || hasUpdateCallback(); - if (hasUpdateCallback()) { - mappedRootObject(updateCallback(mappedRootObject)); + if (hasCreateCallback()) { + mappedRootObject = createCallback(); + } else { + mappedRootObject = ko.observable(ko.utils.unwrapObservable(rootObject)); + } + + if (hasUpdateCallback()) { + mappedRootObject(updateCallback(mappedRootObject)); + } + + if (hasCreateOrUpdateCallback) return mappedRootObject; } - - if (hasCreateOrUpdateCallback) return mappedRootObject; - } } } else { @@ -440,35 +447,59 @@ visitPropertiesOrArrayEntries(rootObject, function (indexer) { var fullPropertyName = parentPropertyName.length ? parentPropertyName + "." + indexer : indexer; - if (ko.utils.arrayIndexOf(options.ignore, fullPropertyName) != -1) { + if (ko.utils.arrayFirst(options.ignore, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { return; } - if (ko.utils.arrayIndexOf(options.copy, fullPropertyName) != -1) { + if (ko.utils.arrayFirst(options.copy, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { mappedRootObject[indexer] = rootObject[indexer]; return; } - if(typeof rootObject[indexer] != "object" && typeof rootObject[indexer] != "array" && options.observe.length > 0 && ko.utils.arrayIndexOf(options.observe, fullPropertyName) == -1) + if (typeof rootObject[indexer] != "object" && typeof rootObject[indexer] != "array" && options.observe.length > 0) { - mappedRootObject[indexer] = rootObject[indexer]; - options.copiedProperties[fullPropertyName] = true; - return; + if (!ko.utils.arrayFirst(options.observe, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { + mappedRootObject[indexer] = rootObject[indexer]; + options.copiedProperties[fullPropertyName] = true; + return; + } } - + // In case we are adding an already mapped property, fill it with the previously mapped property value to prevent recursion. // If this is a property that was generated by fromJS, we should use the options specified there var prevMappedProperty = visitedObjects.get(rootObject[indexer]); var retval = updateViewModel(mappedRootObject[indexer], rootObject[indexer], options, indexer, mappedRootObject, fullPropertyName, mappedRootObject); var value = prevMappedProperty || retval; - - if(options.observe.length > 0 && ko.utils.arrayIndexOf(options.observe, fullPropertyName) == -1) + + if (options.observe.length > 0) { - mappedRootObject[indexer] = value(); - options.copiedProperties[fullPropertyName] = true; - return; + if (!ko.utils.arrayFirst(options.observe, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { + mappedRootObject[indexer] = ko.utils.unwrapObservable(value); + options.copiedProperties[fullPropertyName] = true; + return; + } } - + if (ko.isWriteableObservable(mappedRootObject[indexer])) { value = ko.utils.unwrapObservable(value); if (mappedRootObject[indexer]() !== value) { @@ -500,8 +531,8 @@ mappedRootObject.mappedRemove = function (valueOrPredicate) { var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { - return value === keyCallback(valueOrPredicate); - }; + return value === keyCallback(valueOrPredicate); + }; return mappedRootObject.remove(function (item) { return predicate(keyCallback(item)); }); @@ -516,8 +547,8 @@ mappedRootObject.mappedDestroy = function (valueOrPredicate) { var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { - return value === keyCallback(valueOrPredicate); - }; + return value === keyCallback(valueOrPredicate); + }; return mappedRootObject.destroy(function (item) { return predicate(keyCallback(item)); }); @@ -560,12 +591,10 @@ } var currentArrayKeys = filterArrayByKey(ko.utils.unwrapObservable(mappedRootObject), keyCallback).sort(); - var newArrayKeys = filterArrayByKey(rootObject, keyCallback); - if (hasKeyCallback) newArrayKeys.sort(); - var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys); + var newArrayKeys = [];//filterArrayByKey(rootObject, keyCallback); var ignoreIndexOf = {}; - + var i, j; var unwrappedRootObject = ko.utils.unwrapObservable(rootObject); @@ -573,12 +602,17 @@ var optimizedKeys = true; for (i = 0, j = unwrappedRootObject.length; i < j; i++) { var key = keyCallback(unwrappedRootObject[i]); + newArrayKeys.push(key); if (key === undefined || key instanceof Object) { optimizedKeys = false; break; } itemsByKey[key] = unwrappedRootObject[i]; } + if (hasKeyCallback) { + newArrayKeys.sort(); + } + var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys); var newContents = []; var passedOver = 0; @@ -587,35 +621,35 @@ var mappedItem; var fullPropertyName = parentPropertyName + "[" + i + "]"; switch (key.status) { - case "added": - var item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback); - mappedItem = updateViewModel(undefined, item, options, parentName, mappedRootObject, fullPropertyName, parent); - if(!hasCreateCallback()) { - mappedItem = ko.utils.unwrapObservable(mappedItem); - } + case "added": + var item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback); + mappedItem = updateViewModel(undefined, item, options, parentName, mappedRootObject, fullPropertyName, parent); + if (!hasCreateCallback()) { + mappedItem = ko.utils.unwrapObservable(mappedItem); + } - var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); - - if (mappedItem === emptyReturn) { - passedOver++; - } else { - newContents[index - passedOver] = mappedItem; - } - - ignoreIndexOf[index] = true; - break; - case "retained": - var item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback); - mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback); - updateViewModel(mappedItem, item, options, parentName, mappedRootObject, fullPropertyName, parent); - - var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); - newContents[index] = mappedItem; - ignoreIndexOf[index] = true; - break; - case "deleted": - mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback); - break; + var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); + + if (mappedItem === emptyReturn) { + passedOver++; + } else { + newContents[index - passedOver] = mappedItem; + } + + ignoreIndexOf[index] = true; + break; + case "retained": + var item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback); + mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback); + updateViewModel(mappedItem, item, options, parentName, mappedRootObject, fullPropertyName, parent); + + var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); + newContents[index] = mappedItem; + ignoreIndexOf[index] = true; + break; + case "deleted": + mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback); + break; } changes.push({ @@ -675,10 +709,10 @@ function visitPropertiesOrArrayEntries(rootObject, visitorCallback) { if (exports.getType(rootObject) === "array") { for (var i = 0; i < rootObject.length; i++) - visitorCallback(i); + visitorCallback(i); } else { for (var propertyName in rootObject) - visitorCallback(propertyName); + visitorCallback(propertyName); } }; @@ -736,10 +770,10 @@ if (ko.utils.arrayIndexOf(options.include, indexer) === -1) { // The mapped properties object contains all the properties that were part of the original object. // If a property does not exist, and it is not because it is part of an array (e.g. "myProp[3]"), then it should not be unmapped. - if (unwrappedRootObject[mappingProperty] - && unwrappedRootObject[mappingProperty].mappedProperties && !unwrappedRootObject[mappingProperty].mappedProperties[indexer] - && unwrappedRootObject[mappingProperty].copiedProperties && !unwrappedRootObject[mappingProperty].copiedProperties[indexer] - && !(exports.getType(unwrappedRootObject) === "array")) { + if (unwrappedRootObject[mappingProperty] + && unwrappedRootObject[mappingProperty].mappedProperties && !unwrappedRootObject[mappingProperty].mappedProperties[indexer] + && unwrappedRootObject[mappingProperty].copiedProperties && !unwrappedRootObject[mappingProperty].copiedProperties[indexer] + && !(exports.getType(unwrappedRootObject) === "array")) { return; } } @@ -747,14 +781,14 @@ var outputProperty; switch (exports.getType(ko.utils.unwrapObservable(propertyValue))) { - case "object": - case "array": - case "undefined": - var previouslyMappedValue = options.visitedObjects.get(propertyValue); - mappedRootObject[indexer] = (exports.getType(previouslyMappedValue) !== "undefined") ? previouslyMappedValue : exports.visitModel(propertyValue, callback, options); - break; - default: - mappedRootObject[indexer] = callback(propertyValue, options.parentName); + case "object": + case "array": + case "undefined": + var previouslyMappedValue = options.visitedObjects.get(propertyValue); + mappedRootObject[indexer] = (exports.getType(previouslyMappedValue) !== "undefined") ? previouslyMappedValue : exports.visitModel(propertyValue, callback, options); + break; + default: + mappedRootObject[indexer] = callback(propertyValue, options.parentName); } }); @@ -778,17 +812,17 @@ return value; }; }; - + function objectLookup() { var buckets = {}; - + var findBucket = function(key) { var bucketKey; try { - bucketKey = key;//JSON.stringify(key); + bucketKey = { __ko_mapping_key__: key };//JSON.stringify(key); } catch (e) { - bucketKey = "$$$"; + bucketKey = { __ko_mapping_key__: "$$$" }; } var bucket = buckets[bucketKey]; @@ -798,7 +832,7 @@ } return bucket; }; - + this.save = function (key, value) { findBucket(key).save(key, value); }; diff --git a/build/output/knockout.mapping-latest.js b/build/output/knockout.mapping-latest.js old mode 100644 new mode 100755 index 8d1d512..fae590b --- a/build/output/knockout.mapping-latest.js +++ b/build/output/knockout.mapping-latest.js @@ -1,22 +1,4 @@ /// Knockout Mapping plugin v2.4.1 /// (c) 2013 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/ /// License: MIT (http://www.opensource.org/licenses/mit-license.php) -(function(e){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?e(require("knockout"),exports):"function"===typeof define&&define.amd?define(["knockout","exports"],e):e(ko,ko.mapping={})})(function(e,f){function y(b,c){var a,d;for(d in c)if(c.hasOwnProperty(d)&&c[d])if(a=f.getType(b[d]),d&&b[d]&&"array"!==a&&"string"!==a)y(b[d],c[d]);else if("array"===f.getType(b[d])&&"array"===f.getType(c[d])){a=b;for(var e=d,l=b[d],n=c[d],t={},g=l.length-1;0<=g;--g)t[l[g]]=l[g];for(g= -n.length-1;0<=g;--g)t[n[g]]=n[g];l=[];n=void 0;for(n in t)l.push(t[n]);a[e]=l}else b[d]=c[d]}function E(b,c){var a={};y(a,b);y(a,c);return a}function z(b,c){for(var a=E({},b),e=L.length-1;0<=e;e--){var f=L[e];a[f]&&(a[""]instanceof Object||(a[""]={}),a[""][f]=a[f],delete a[f])}c&&(a.ignore=h(c.ignore,a.ignore),a.include=h(c.include,a.include),a.copy=h(c.copy,a.copy),a.observe=h(c.observe,a.observe));a.ignore=h(a.ignore,j.ignore);a.include=h(a.include,j.include);a.copy=h(a.copy,j.copy);a.observe=h(a.observe, -j.observe);a.mappedProperties=a.mappedProperties||{};a.copiedProperties=a.copiedProperties||{};return a}function h(b,c){"array"!==f.getType(b)&&(b="undefined"===f.getType(b)?[]:[b]);"array"!==f.getType(c)&&(c="undefined"===f.getType(c)?[]:[c]);return e.utils.arrayGetDistinctValues(b.concat(c))}function F(b,c,a,d,k,l,n){var t="array"===f.getType(e.utils.unwrapObservable(c));l=l||"";if(f.isMapped(b)){var g=e.utils.unwrapObservable(b)[p];a=E(g,a)}var j=n||k,h=function(){return a[d]&&a[d].create instanceof -Function},x=function(b){var f=G,g=e.dependentObservable;e.dependentObservable=function(a,b,c){c=c||{};a&&"object"==typeof a&&(c=a);var d=c.deferEvaluation,M=!1;c.deferEvaluation=!0;a=new H(a,b,c);if(!d){var g=a,d=e.dependentObservable;e.dependentObservable=H;a=e.isWriteableObservable(g);e.dependentObservable=d;d=H({read:function(){M||(e.utils.arrayRemoveItem(f,g),M=!0);return g.apply(g,arguments)},write:a&&function(a){return g(a)},deferEvaluation:!0});d.__DO=g;a=d;f.push(a)}return a};e.dependentObservable.fn= -H.fn;e.computed=e.dependentObservable;b=e.utils.unwrapObservable(k)instanceof Array?a[d].create({data:b||c,parent:j,skip:N}):a[d].create({data:b||c,parent:j});e.dependentObservable=g;e.computed=e.dependentObservable;return b},u=function(){return a[d]&&a[d].update instanceof Function},v=function(b,f){var g={data:f||c,parent:j,target:e.utils.unwrapObservable(b)};e.isWriteableObservable(b)&&(g.observable=b);return a[d].update(g)};if(n=I.get(c))return n;d=d||"";if(t){var t=[],s=!1,m=function(a){return a}; -a[d]&&a[d].key&&(m=a[d].key,s=!0);e.isObservable(b)||(b=e.observableArray([]),b.mappedRemove=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.remove(function(a){return c(m(a))})},b.mappedRemoveAll=function(a){var c=C(a,m);return b.remove(function(a){return-1!=e.utils.arrayIndexOf(c,m(a))})},b.mappedDestroy=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.destroy(function(a){return c(m(a))})},b.mappedDestroyAll=function(a){var c=C(a,m);return b.destroy(function(a){return-1!= -e.utils.arrayIndexOf(c,m(a))})},b.mappedIndexOf=function(a){var c=C(b(),m);a=m(a);return e.utils.arrayIndexOf(c,a)},b.mappedGet=function(a){return b()[b.mappedIndexOf(a)]},b.mappedCreate=function(a){if(-1!==b.mappedIndexOf(a))throw Error("There already is an object with the key that you specified.");var c=h()?x(a):a;u()&&(a=v(c,a),e.isWriteableObservable(c)?c(a):c=a);b.push(c);return c});n=C(e.utils.unwrapObservable(b),m).sort();g=C(c,m);s&&g.sort();s=e.utils.compareArrays(n,g);n={};var J,A=e.utils.unwrapObservable(c), -y={},z=!0,g=0;for(J=A.length;g=0;e--)(f=w[e],i[f])&&(i[""]instanceof Object||(i[""]={}),i[""][f]=i[f],delete i[f]);return t&&(i.ignore=u(t.ignore,i.ignore),i.include=u(t.include,i.include),i.copy=u(t.copy,i.copy),i.observe=u(t.observe,i.observe)),i.ignore=u(i.ignore,r.ignore),i.include=u(i.include,r.include),i.copy=u(i.copy,r.copy),i.observe=u(i.observe,r.observe),i.mappedProperties=i.mappedProperties||{},i.copiedProperties=i.copiedProperties||{},i}function u(i,r){return t.getType(i)!=="array"&&(i=t.getType(i)==="undefined"?[]:[i]),t.getType(r)!=="array"&&(r=t.getType(r)==="undefined"?[]:[r]),n.utils.arrayGetDistinctValues(i.concat(r))}function ut(t,i){var u=n.dependentObservable,r;return n.dependentObservable=function(i,r,u){var f;u=u||{};i&&typeof i=="object"&&(u=i);var s=u.deferEvaluation,o=!1,h=function(i){var f=n.dependentObservable,u,r;return n.dependentObservable=e,u=n.isWriteableObservable(i),n.dependentObservable=f,r=e({read:function(){return o||(n.utils.arrayRemoveItem(t,i),o=!0),i.apply(i,arguments)},write:u&&function(n){return i(n)},deferEvaluation:!0}),it&&(r._wrapper=!0),r.__DO=i,r};return u.deferEvaluation=!0,f=new e(i,r,u),s||(f=h(f),t.push(f)),f},n.dependentObservable.fn=e.fn,n.computed=n.dependentObservable,r=i(),n.dependentObservable=u,n.computed=n.dependentObservable,r}function c(r,u,f,e,v,y,p){var oi=t.getType(n.utils.unwrapObservable(u))==="array",ni,ot,ii,lt,d,it,gt,st,ht;y=y||"";t.isMapped(r)&&(ni=n.utils.unwrapObservable(r)[i],f=h(ni,f));var et={data:u,parent:p||v},ct=function(){return f[e]&&f[e].create instanceof Function},yt=function(t){return ut(o,function(){return n.utils.unwrapObservable(v)instanceof Array?f[e].create({data:t||et.data,parent:et.parent,skip:b}):f[e].create({data:t||et.data,parent:et.parent})})},rt=function(){return f[e]&&f[e].update instanceof Function},ft=function(t,i){var r={data:i||et.data,parent:et.parent,target:n.utils.unwrapObservable(t)};return n.isWriteableObservable(t)&&(r.observable=t),f[e].update(r)},ti=s.get(u);if(ti)return ti;if(e=e||"",oi){var ri=[],ui=!1,w=function(n){return n};f[e]&&f[e].key&&(w=f[e].key,ui=!0);n.isObservable(r)||(r=n.observableArray([]),r.mappedRemove=function(n){var t=typeof n=="function"?n:function(t){return t===w(n)};return r.remove(function(n){return t(w(n))})},r.mappedRemoveAll=function(t){var i=a(t,w);return r.remove(function(t){return n.utils.arrayIndexOf(i,w(t))!=-1})},r.mappedDestroy=function(n){var t=typeof n=="function"?n:function(t){return t===w(n)};return r.destroy(function(n){return t(w(n))})},r.mappedDestroyAll=function(t){var i=a(t,w);return r.destroy(function(t){return n.utils.arrayIndexOf(i,w(t))!=-1})},r.mappedIndexOf=function(t){var i=a(r(),w),u=w(t);return n.utils.arrayIndexOf(i,u)},r.mappedGet=function(n){return r()[r.mappedIndexOf(n)]},r.mappedCreate=function(t){var i,u;if(r.mappedIndexOf(t)!==-1)throw new Error("There already is an object with the key that you specified.");return i=ct()?yt(t):t,rt()&&(u=ft(i,t),n.isWriteableObservable(i)?i(u):i=u),r.push(i),i});for(var si=a(n.utils.unwrapObservable(r),w).sort(),pt=[],at={},wt=n.utils.unwrapObservable(u),bt={},kt=!0,tt=0,vt=wt.length;tt0&&!n.utils.arrayFirst(f.observe,function(n){return n.test instanceof Function?n.test(i):i===n})){r[t]=u[t];f.copiedProperties[i]=!0;return}var o=s.get(u[t]),h=c(r[t],u[t],f,t,r,i,r),e=o||h;if(f.observe.length>0&&!n.utils.arrayFirst(f.observe,function(n){return n.test instanceof Function?n.test(i):i===n})){r[t]=n.utils.unwrapObservable(e);f.copiedProperties[i]=!0;return}n.isWriteableObservable(r[t])?(e=n.utils.unwrapObservable(e),r[t]()!==e&&r[t](e)):(e=r[t]===undefined?e:n.utils.unwrapObservable(e),r[t]=e);f.mappedProperties[i]=!0}})}else switch(t.getType(u)){case"function":rt()?n.isWriteableObservable(u)?(u(ft(u)),r=u):r=ft(u):r=u;break;default:if(n.isWriteableObservable(r))return rt()?(ot=ft(r),r(ot),ot):(ot=n.utils.unwrapObservable(u),r(ot),ot);if(ii=ct()||rt(),r=ct()?yt():n.observable(n.utils.unwrapObservable(u)),rt()&&r(ft(r)),ii)return r}return r}function k(n,t,i){for(var r=0,u=n.length;r=0?i[f]=u:(t.push(r),i.push(u))};this.get=function(r){var u=n.utils.arrayIndexOf(t,r);return u>=0?i[u]:undefined}}function tt(){var n={},t=function(t){var r,i;try{r={__ko_mapping_key__:t}}catch(u){r={__ko_mapping_key__:"$$$"}}return i=n[r],i===undefined&&(i=new et,n[r]=i),i};this.save=function(n,i){t(n).save(n,i)};this.get=function(n){return t(n).get(n)}}var it=!0,i="__ko_mapping__",e=n.dependentObservable,v=0,o,s,w=["create","update","key","arrayChanged"],b={},f={include:["_destroy"],ignore:[],copy:[],observe:[]},r=f;t.isMapped=function(t){var r=n.utils.unwrapObservable(t);return r&&r[i]};t.fromJS=function(n){var t,r,u,f;if(arguments.length==0)throw new Error("When calling ko.fromJS, pass the object you want to convert.");try{if(v++||(o=[],s=new tt),arguments.length==2&&(arguments[1][i]?r=arguments[1]:t=arguments[1]),arguments.length==3&&(t=arguments[1],r=arguments[2]),r&&(t=h(t,r[i])),t=p(t),u=c(r,n,t),r&&(u=r),!--v)while(o.length)f=o.pop(),f&&(f(),f.__DO.throttleEvaluation=f.throttleEvaluation);return u[i]=h(u[i],t),u}catch(e){v=0;throw e;}};t.fromJSON=function(i){var r=n.utils.parseJson(i);return arguments[0]=r,t.fromJS.apply(this,arguments)};t.updateFromJS=function(){throw new Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");};t.updateFromJSON=function(){throw new Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");};t.toJS=function(u,f){if(r||t.resetDefaultOptions(),arguments.length==0)throw new Error("When calling ko.mapping.toJS, pass the object you want to convert.");if(t.getType(r.ignore)!=="array")throw new Error("ko.mapping.defaultOptions().ignore should be an array.");if(t.getType(r.include)!=="array")throw new Error("ko.mapping.defaultOptions().include should be an array.");if(t.getType(r.copy)!=="array")throw new Error("ko.mapping.defaultOptions().copy should be an array.");return f=p(f,u[i]),t.visitModel(u,function(t){return n.utils.unwrapObservable(t)},f)};t.toJSON=function(i,r){var u=t.toJS(i,r);return n.utils.stringifyJson(u)};t.defaultOptions=function(){if(arguments.length>0)r=arguments[0];else return r};t.resetDefaultOptions=function(){r={include:f.include.slice(0),ignore:f.ignore.slice(0),copy:f.copy.slice(0),observe:f.observe.slice(0)}};t.getType=function(n){if(n&&typeof n=="object"){if(n.constructor===Date)return"date";if(n.constructor===Array)return"array"}return typeof n};t.visitModel=function(r,u,f){var o,e,s;if(f=f||{},f.visitedObjects=f.visitedObjects||new tt,e=n.utils.unwrapObservable(r),nt(e))f=p(f,e[i]),u(r,f.parentName),o=t.getType(e)==="array"?[]:{};else return u(r,f.parentName);return f.visitedObjects.save(r,o),s=f.parentName,g(e,function(r){var h,c;if((!f.ignore||n.utils.arrayIndexOf(f.ignore,r)==-1)&&(h=e[r],f.parentName=ft(s,e,r),n.utils.arrayIndexOf(f.copy,r)!==-1||n.utils.arrayIndexOf(f.include,r)!==-1||!e[i]||!e[i].mappedProperties||e[i].mappedProperties[r]||!e[i].copiedProperties||e[i].copiedProperties[r]||t.getType(e)==="array"))switch(t.getType(n.utils.unwrapObservable(h))){case"object":case"array":case"undefined":c=f.visitedObjects.get(h);o[r]=t.getType(c)!=="undefined"?c:t.visitModel(h,u,f);break;default:o[r]=u(h,f.parentName)}}),o}}); diff --git a/build/tools/curl.exe b/build/tools/curl.exe old mode 100644 new mode 100755 diff --git a/build/tools/searchReplace.js b/build/tools/searchReplace.js old mode 100644 new mode 100755 diff --git a/build/version-header.js b/build/version-header.js old mode 100644 new mode 100755 diff --git a/knockout.mapping.js b/knockout.mapping.js old mode 100644 new mode 100755 index 2ac4a3d..40e07f1 --- a/knockout.mapping.js +++ b/knockout.mapping.js @@ -447,20 +447,37 @@ visitPropertiesOrArrayEntries(rootObject, function (indexer) { var fullPropertyName = parentPropertyName.length ? parentPropertyName + "." + indexer : indexer; - if (ko.utils.arrayIndexOf(options.ignore, fullPropertyName) != -1) { + if (ko.utils.arrayFirst(options.ignore, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { return; } - if (ko.utils.arrayIndexOf(options.copy, fullPropertyName) != -1) { + if (ko.utils.arrayFirst(options.copy, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { mappedRootObject[indexer] = rootObject[indexer]; return; } - if(typeof rootObject[indexer] != "object" && typeof rootObject[indexer] != "array" && options.observe.length > 0 && ko.utils.arrayIndexOf(options.observe, fullPropertyName) == -1) + if (typeof rootObject[indexer] != "object" && typeof rootObject[indexer] != "array" && options.observe.length > 0) { - mappedRootObject[indexer] = rootObject[indexer]; - options.copiedProperties[fullPropertyName] = true; - return; + if (!ko.utils.arrayFirst(options.observe, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { + mappedRootObject[indexer] = rootObject[indexer]; + options.copiedProperties[fullPropertyName] = true; + return; + } } // In case we are adding an already mapped property, fill it with the previously mapped property value to prevent recursion. @@ -468,12 +485,19 @@ var prevMappedProperty = visitedObjects.get(rootObject[indexer]); var retval = updateViewModel(mappedRootObject[indexer], rootObject[indexer], options, indexer, mappedRootObject, fullPropertyName, mappedRootObject); var value = prevMappedProperty || retval; - - if(options.observe.length > 0 && ko.utils.arrayIndexOf(options.observe, fullPropertyName) == -1) + + if (options.observe.length > 0) { - mappedRootObject[indexer] = ko.utils.unwrapObservable(value); - options.copiedProperties[fullPropertyName] = true; - return; + if (!ko.utils.arrayFirst(options.observe, function (item) { + if (item.test instanceof Function) { + return item.test(fullPropertyName); + } + return fullPropertyName === item; + })) { + mappedRootObject[indexer] = ko.utils.unwrapObservable(value); + options.copiedProperties[fullPropertyName] = true; + return; + } } if (ko.isWriteableObservable(mappedRootObject[indexer])) { @@ -567,9 +591,7 @@ } var currentArrayKeys = filterArrayByKey(ko.utils.unwrapObservable(mappedRootObject), keyCallback).sort(); - var newArrayKeys = filterArrayByKey(rootObject, keyCallback); - if (hasKeyCallback) newArrayKeys.sort(); - var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys); + var newArrayKeys = [];//filterArrayByKey(rootObject, keyCallback); var ignoreIndexOf = {}; @@ -580,12 +602,17 @@ var optimizedKeys = true; for (i = 0, j = unwrappedRootObject.length; i < j; i++) { var key = keyCallback(unwrappedRootObject[i]); + newArrayKeys.push(key); if (key === undefined || key instanceof Object) { optimizedKeys = false; break; } itemsByKey[key] = unwrappedRootObject[i]; } + if (hasKeyCallback) { + newArrayKeys.sort(); + } + var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys); var newContents = []; var passedOver = 0; @@ -792,10 +819,10 @@ var findBucket = function(key) { var bucketKey; try { - bucketKey = key;//JSON.stringify(key); + bucketKey = { __ko_mapping_key__: key };//JSON.stringify(key); } catch (e) { - bucketKey = "$$$"; + bucketKey = { __ko_mapping_key__: "$$$" }; } var bucket = buckets[bucketKey]; diff --git a/spec/issues.js b/spec/issues.js old mode 100644 new mode 100755 diff --git a/spec/lib/json2.js b/spec/lib/json2.js old mode 100644 new mode 100755 diff --git a/spec/lib/qunit-1.10.0.css b/spec/lib/qunit-1.10.0.css old mode 100644 new mode 100755 diff --git a/spec/lib/qunit-1.10.0.js b/spec/lib/qunit-1.10.0.js old mode 100644 new mode 100755 diff --git a/spec/mappingBehaviors.js b/spec/mappingBehaviors.js old mode 100644 new mode 100755 diff --git a/spec/proxyDependentObservableBehaviors.js b/spec/proxyDependentObservableBehaviors.js old mode 100644 new mode 100755 diff --git a/spec/runner.html b/spec/runner.html old mode 100644 new mode 100755