Skip to content

Commit 23f9de5

Browse files
cspotcodecrissdev
authored andcommitted
Fix incorrect handling of properties with periods
Closes SteveSanderson#96
1 parent e6c5631 commit 23f9de5

File tree

5 files changed

+62
-20
lines changed

5 files changed

+62
-20
lines changed

dist/knockout.mapping.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@
474474

475475
// For non-atomic types, visit all properties and update recursively
476476
visitPropertiesOrArrayEntries(rootObject, function(indexer) {
477-
var fullPropertyName = parentPropertyName.length ? parentPropertyName + "." + indexer : indexer;
477+
var fullPropertyName = parentPropertyName.length ? parentPropertyName + "." + escapePropertyNameComponent(indexer) : escapePropertyNameComponent(indexer);
478478

479479
if (ko.utils.arrayIndexOf(options.ignore, fullPropertyName) !== -1) {
480480
return;
@@ -623,7 +623,8 @@
623623
for (i = 0, j = editScript.length; i < j; i++) {
624624
key = editScript[i];
625625
var mappedItem;
626-
var fullPropertyName = parentPropertyName + "[" + i + "]";
626+
var fullPropertyName = parentPropertyName + "[" + escapePropertyNameComponent(i) + "]";
627+
627628
switch (key.status) {
628629
case "added":
629630
item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback);
@@ -740,18 +741,28 @@
740741
var propertyName = parentName || "";
741742
if (exports.getType(parent) === "array") {
742743
if (parentName) {
743-
propertyName += "[" + indexer + "]";
744+
propertyName += "[" + escapePropertyNameComponent(indexer) + "]";
744745
}
745746
}
746747
else {
747748
if (parentName) {
748749
propertyName += ".";
749750
}
750-
propertyName += indexer;
751+
propertyName += escapePropertyNameComponent(indexer);
751752
}
752753
return propertyName;
753754
}
754755

756+
function escapePropertyNameComponent(indexer) {
757+
var escapedIndexer = (''+indexer)
758+
.replace(/~/g, '~~')
759+
.replace(/\[/g, '~[')
760+
.replace(/]/g, '~]')
761+
.replace(/\./g, '~.');
762+
return escapedIndexer;
763+
}
764+
765+
755766
exports.visitModel = function(rootObject, callback, options) {
756767
options = options || {};
757768
options.visitedObjects = options.visitedObjects || new ObjectLookup();
@@ -774,23 +785,24 @@
774785

775786
var parentName = options.parentName;
776787
visitPropertiesOrArrayEntries(unwrappedRootObject, function(indexer) {
777-
if (options.ignore && ko.utils.arrayIndexOf(options.ignore, indexer) !== -1) return;
788+
var escapedIndexer = escapePropertyNameComponent(indexer);
789+
if (options.ignore && ko.utils.arrayIndexOf(options.ignore, escapedIndexer) != -1) return;
778790

779791
var propertyValue = unwrappedRootObject[indexer];
780792
options.parentName = getPropertyName(parentName, unwrappedRootObject, indexer);
781793

782794
// If we don't want to explicitly copy the unmapped property...
783-
if (ko.utils.arrayIndexOf(options.copy, indexer) === -1) {
795+
if (ko.utils.arrayIndexOf(options.copy, escapedIndexer) === -1) {
784796
// ...find out if it's a property we want to explicitly include
785-
if (ko.utils.arrayIndexOf(options.include, indexer) === -1) {
797+
if (ko.utils.arrayIndexOf(options.include, escapedIndexer) === -1) {
786798
// The mapped properties object contains all the properties that were part of the original object.
787799
// 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.
788800
var unwrappedRootMappingProperty = unwrappedRootObject[mappingProperty];
789801
if (unwrappedRootMappingProperty) {
790802
var mappedProperties = unwrappedRootMappingProperty.mappedProperties;
791-
if (mappedProperties && !mappedProperties[indexer]) {
803+
if (mappedProperties && !mappedProperties[escapedIndexer]) {
792804
var copiedProperties = unwrappedRootMappingProperty.copiedProperties;
793-
if (copiedProperties && !copiedProperties[indexer] && (exports.getType(unwrappedRootObject) !== "array")) {
805+
if (copiedProperties && !copiedProperties[escapedIndexer] && (exports.getType(unwrappedRootObject) !== "array")) {
794806
return;
795807
}
796808
}

0 commit comments

Comments
 (0)