Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #424 from SteveSanderson/413-arraymapping-tolerate…

…-manual-edits

Fix #413 (tolerate certain kinds of manual DOM edits while using setDomN...
  • Loading branch information...
commit b76809810674c4558a4afd224eecd71163fdb7ad 2 parents 68c356f + b88a69a
Michael Best authored April 04, 2012
24  spec/editDetectionBehaviors.js
@@ -158,6 +158,30 @@ describe('Array to DOM node children mapping', {
158 158
         value_of(mappingInvocations).should_be([]);
159 159
     },
160 160
 
  161
+    'Should tolerate DOM nodes being removed manually, before the corresponding array entry is removed': function() {
  162
+        // Represents https://github.com/SteveSanderson/knockout/issues/413
  163
+        // 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.
  164
+        var mappingInvocations = [];
  165
+        var mapping = function (arrayItem) {
  166
+            mappingInvocations.push(arrayItem);
  167
+            var output = document.createElement("DIV");
  168
+            output.innerHTML = arrayItem;
  169
+            return [output];
  170
+        };
  171
+
  172
+        ko.utils.setDomNodeChildrenFromArrayMapping(testNode, ["A", "B", "C"], mapping);
  173
+        value_of(testNode).should_contain_text("ABC");
  174
+
  175
+        // Now kill the middle DIV manually, even though people shouldn't really do this
  176
+        var elemToRemove = testNode.childNodes[1];
  177
+        value_of(elemToRemove.innerHTML).should_be("B"); // Be sure it's the right one
  178
+        elemToRemove.parentNode.removeChild(elemToRemove);
  179
+
  180
+        // Now remove the corresponding array entry. This shouldn't cause an exception.
  181
+        ko.utils.setDomNodeChildrenFromArrayMapping(testNode, ["A", "C"], mapping);
  182
+        value_of(testNode).should_contain_text("AC");
  183
+    },
  184
+
161 185
     'Should handle sequences of mixed insertions and deletions': function () {
162 186
         var mappingInvocations = [], countCallbackInvocations = 0;
163 187
         var mapping = function (arrayItem) {
6  src/binding/editDetection/arrayToDomNodeChildren.js
@@ -152,8 +152,10 @@
152 152
         }
153 153
         if (!invokedBeforeRemoveCallback && nodesToDelete.length) {
154 154
             var commonParent = nodesToDelete[0].element.parentNode;
155  
-            for (var i = 0; i < nodesToDelete.length; i++)
156  
-                commonParent.removeChild(nodesToDelete[i].element);
  155
+            if (commonParent) {
  156
+                for (var i = 0; i < nodesToDelete.length; i++)
  157
+                    commonParent.removeChild(nodesToDelete[i].element);
  158
+            }
157 159
         }
158 160
 
159 161
         // Store a copy of the array items we just considered so we can difference it next time

0 notes on commit b768098

Please sign in to comment.
Something went wrong with that request. Please try again.