Skip to content

Commit

Permalink
Merge pull request knockout#424 from SteveSanderson/413-arraymapping-…
Browse files Browse the repository at this point in the history
…tolerate-manual-edits

Fix knockout#413 (tolerate certain kinds of manual DOM edits while using setDomN...
  • Loading branch information
mbest committed Apr 4, 2012
2 parents 68c356f + b88a69a commit b768098
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
24 changes: 24 additions & 0 deletions spec/editDetectionBehaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,30 @@ describe('Array to DOM node children mapping', {
value_of(mappingInvocations).should_be([]);
},

'Should tolerate DOM nodes being removed manually, before the corresponding array entry is removed': function() {
// Represents https://github.com/SteveSanderson/knockout/issues/413
// Ideally, people wouldn't be mutating the generated DOM manually. But this didn't error in v2.0, so we should try to avoid introducing a break.
var mappingInvocations = [];
var mapping = function (arrayItem) {
mappingInvocations.push(arrayItem);
var output = document.createElement("DIV");
output.innerHTML = arrayItem;
return [output];
};

ko.utils.setDomNodeChildrenFromArrayMapping(testNode, ["A", "B", "C"], mapping);
value_of(testNode).should_contain_text("ABC");

// Now kill the middle DIV manually, even though people shouldn't really do this
var elemToRemove = testNode.childNodes[1];
value_of(elemToRemove.innerHTML).should_be("B"); // Be sure it's the right one
elemToRemove.parentNode.removeChild(elemToRemove);

// Now remove the corresponding array entry. This shouldn't cause an exception.
ko.utils.setDomNodeChildrenFromArrayMapping(testNode, ["A", "C"], mapping);
value_of(testNode).should_contain_text("AC");
},

'Should handle sequences of mixed insertions and deletions': function () {
var mappingInvocations = [], countCallbackInvocations = 0;
var mapping = function (arrayItem) {
Expand Down
6 changes: 4 additions & 2 deletions src/binding/editDetection/arrayToDomNodeChildren.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@
}
if (!invokedBeforeRemoveCallback && nodesToDelete.length) {
var commonParent = nodesToDelete[0].element.parentNode;
for (var i = 0; i < nodesToDelete.length; i++)
commonParent.removeChild(nodesToDelete[i].element);
if (commonParent) {
for (var i = 0; i < nodesToDelete.length; i++)
commonParent.removeChild(nodesToDelete[i].element);
}
}

// Store a copy of the array items we just considered so we can difference it next time
Expand Down

0 comments on commit b768098

Please sign in to comment.