Skip to content

Commit

Permalink
Don’t tear down bindings for removed nodes that are still in the DOM
Browse files Browse the repository at this point in the history
When can-dom-mutate reports that a node has been removed, we first check whether the node is still in the document before tearing down its bindings.

Fixes #460
  • Loading branch information
chasenlehara committed Jun 1, 2018
1 parent d259437 commit fd8b423
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
6 changes: 5 additions & 1 deletion can-stache-bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,11 @@ var behaviors = {
teardown = dataBinding.onTeardown;

attributeDisposal = domMutate.onNodeAttributeChange(el, attributeListener);
removedDisposal = domMutate.onNodeRemoval(el, tearItAllDown);
removedDisposal = domMutate.onNodeRemoval(el, function() {
if (el.ownerDocument.contains(el) === false) {
tearItAllDown();
}
});
},
// ### bindings.behaviors.event
// The following section contains code for implementing the can-EVENT attribute.
Expand Down
27 changes: 27 additions & 0 deletions test/colon/basics-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var testHelpers = require('../helpers');

var stacheBindings = require('can-stache-bindings');

var domEvents = require('can-dom-events');
var stache = require('can-stache');

var SimpleMap = require("can-simple-map");
Expand Down Expand Up @@ -388,4 +389,30 @@ testHelpers.makeTests("can-stache-bindings - colon - basics", function(name, doc
QUnit.equal(input.value, "VALUE", "value should not have been updated");
});

QUnit.test("bindings still work for moved elements (#460)", function(assert) {
var done = assert.async();
var map = new SimpleMap({value: "first"});
var template = stache("<input value:bind='value'/>");
var frag = template(map);
var input = frag.firstChild;

this.fixture.appendChild(frag);

// Move the input to inside the div
var div = doc.createElement("div");
this.fixture.appendChild(div);
div.appendChild(input);

testHelpers.afterMutation(function() {
map.set("value", "second");
QUnit.equal(input.value, "second", "value should have been updated");

input.value = "third";
domEvents.dispatch(input, "change");
QUnit.equal(map.get("value"), "third", "map should have been updated");

done();
});
});

});

0 comments on commit fd8b423

Please sign in to comment.