diff --git a/knockout.mapping.js b/knockout.mapping.js index 2ac4a3d..ed30f75 100644 --- a/knockout.mapping.js +++ b/knockout.mapping.js @@ -28,27 +28,27 @@ observe: [] }; var defaultOptions = _defaultOptions; - + 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; } @@ -126,7 +126,7 @@ var DO = dependentObservables.pop(); if (DO) { DO(); - + // Move this magic property to the underlying dependent observable DO.__DO["throttleEvaluation"] = DO["throttleEvaluation"]; } @@ -197,11 +197,14 @@ }; exports.getType = function(x) { - if ((x) && (typeof (x) === "object")) { - if (x.constructor === Date) return "date"; - if (x.constructor === Array) return "array"; + switch (Object.prototype.toString.call(x)) { + case "[object Date]": + return "date"; + case "[object Array]": + return "array"; + default: + return typeof x; } - return typeof x; } function fillOptions(rawOptions, otherOptions) { @@ -210,12 +213,12 @@ // 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[""] = {}; + if (!(exports.getType(options[""]) === "object")) options[""] = {}; options[""][property] = options[property]; delete options[property]; } @@ -290,7 +293,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); @@ -326,13 +329,14 @@ }; var hasCreateCallback = function () { - return options[parentName] && options[parentName].create instanceof Function; + return options[parentName] && + exports.getType(options[parentName].create) === "function"; }; var createCallback = function (data) { return withProxyDependentObservable(dependentObservables, function () { - - if (ko.utils.unwrapObservable(parent) instanceof Array) { + + if (exports.getType(ko.utils.unwrapObservable(parent)) === "array") { return options[parentName].create({ data: data || callbackParams.data, parent: callbackParams.parent, @@ -343,12 +347,13 @@ data: data || callbackParams.data, parent: callbackParams.parent }); - } + } }); }; var hasUpdateCallback = function () { - return options[parentName] && options[parentName].update instanceof Function; + return options[parentName] && + exports.getType(options[parentName].update) === "function"; }; var updateCallback = function (obj, data) { @@ -401,7 +406,7 @@ } } else { var hasCreateOrUpdateCallback = hasCreateCallback() || hasUpdateCallback(); - + if (hasCreateCallback()) { mappedRootObject = createCallback(); } else { @@ -411,7 +416,7 @@ if (hasUpdateCallback()) { mappedRootObject(updateCallback(mappedRootObject)); } - + if (hasCreateOrUpdateCallback) return mappedRootObject; } } @@ -462,20 +467,20 @@ 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) { 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) { @@ -572,7 +577,7 @@ var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys); var ignoreIndexOf = {}; - + var i, j; var unwrappedRootObject = ko.utils.unwrapObservable(rootObject); @@ -580,7 +585,7 @@ var optimizedKeys = true; for (i = 0, j = unwrappedRootObject.length; i < j; i++) { var key = keyCallback(unwrappedRootObject[i]); - if (key === undefined || key instanceof Object) { + if (key === undefined || exports.getType(key) === "object") { optimizedKeys = false; break; } @@ -602,13 +607,13 @@ } var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); - + if (mappedItem === emptyReturn) { passedOver++; } else { newContents[index - passedOver] = mappedItem; } - + ignoreIndexOf[index] = true; break; case "retained": @@ -785,10 +790,10 @@ return value; }; }; - + function objectLookup() { var buckets = {}; - + var findBucket = function(key) { var bucketKey; try { @@ -805,7 +810,7 @@ } return bucket; }; - + this.save = function (key, value) { findBucket(key).save(key, value); };