mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3160 from Polymer/3125-kschaaf-move-domif
Ensure dom-if in host does not restamp when host detaches. Fixes #3125.
This commit is contained in:
commit
bab847aaf7
@ -73,13 +73,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
detached: function() {
|
||||
// TODO(kschaaf): add logic to re-stamp in attached?
|
||||
this._teardownInstance();
|
||||
if (!this.parentNode) {
|
||||
this._teardownInstance();
|
||||
}
|
||||
},
|
||||
|
||||
attached: function() {
|
||||
if (this.if && this.ctor) {
|
||||
// TODO(sorvell): should not be async, but node can be attached
|
||||
// NOTE: ideally should not be async, but node can be attached
|
||||
// when shady dom is in the act of distributing/composing so push it out
|
||||
this.async(this._ensureInstance);
|
||||
}
|
||||
@ -116,16 +117,25 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_ensureInstance: function() {
|
||||
if (!this._instance) {
|
||||
var parentNode = Polymer.dom(this).parentNode;
|
||||
// Guard against element being detached while render was queued
|
||||
if (parentNode) {
|
||||
var parent = Polymer.dom(parentNode);
|
||||
// TODO(sorvell): pickup stamping logic from x-repeat
|
||||
var parentNode = Polymer.dom(this).parentNode;
|
||||
// Guard against element being detached while render was queued
|
||||
if (parentNode) {
|
||||
var parent = Polymer.dom(parentNode);
|
||||
if (!this._instance) {
|
||||
this._instance = this.stamp();
|
||||
var root = this._instance.root;
|
||||
// TODO(sorvell): this incantation needs to be simpler.
|
||||
parent.insertBefore(root, this);
|
||||
} else {
|
||||
var c$ = this._instance._children;
|
||||
if (c$ && c$.length) {
|
||||
// Detect case where dom-if was re-attached in new position
|
||||
var lastChild = Polymer.dom(this).previousSibling;
|
||||
if (lastChild !== c$[c$.length-1]) {
|
||||
for (var i=0, n; (i<c$.length) && (n=c$[i]); i++) {
|
||||
parent.insertBefore(n, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -133,7 +143,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
_teardownInstance: function() {
|
||||
if (this._instance) {
|
||||
var c$ = this._instance._children;
|
||||
if (c$) {
|
||||
if (c$ && c$.length) {
|
||||
// use first child parent, for case when dom-if may have been detached
|
||||
var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode);
|
||||
for (var i=0, n; (i<c$.length) && (n=c$[i]); i++) {
|
||||
|
@ -180,3 +180,27 @@
|
||||
});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<dom-module id="x-host">
|
||||
<template>
|
||||
<template id="domif" is="dom-if" if>
|
||||
<x-client></x-client>
|
||||
<x-client></x-client>
|
||||
<x-client></x-client>
|
||||
</template>
|
||||
</template>
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'x-host'
|
||||
});
|
||||
Polymer({
|
||||
is: 'x-client',
|
||||
statics: {
|
||||
uid: 0
|
||||
},
|
||||
ready: function() {
|
||||
this.uid = this.statics.uid++;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
@ -56,9 +56,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template is="dom-if" id="simple">
|
||||
<div></div>
|
||||
</template>
|
||||
<div id="outerContainer">
|
||||
<template is="dom-if" id="simple">
|
||||
<x-client></x-client>
|
||||
<x-client></x-client>
|
||||
<x-client></x-client>
|
||||
</template>
|
||||
|
||||
<div id="innerContainer">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
@ -518,19 +525,132 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
});
|
||||
|
||||
suite('queueing race conditions', function() {
|
||||
suite('attach/detach tests', function() {
|
||||
|
||||
test('domif=true, attach, detach', function(done) {
|
||||
test('remove, append domif', function(done) {
|
||||
var domif = document.querySelector('#simple');
|
||||
domif.if = true;
|
||||
document.body.appendChild(domif);
|
||||
document.body.removeChild(domif);
|
||||
outerContainer.removeChild(domif);
|
||||
setTimeout(function() {
|
||||
document.body.appendChild(domif);
|
||||
var clients = outerContainer.querySelectorAll('x-client');
|
||||
assert.equal(clients.length, 0);
|
||||
outerContainer.appendChild(domif);
|
||||
setTimeout(function() {
|
||||
var clients = outerContainer.querySelectorAll('x-client');
|
||||
assert.equal(clients[0].uid, 0);
|
||||
assert.equal(clients[1].uid, 1);
|
||||
assert.equal(clients[2].uid, 2);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(domif.previousElementSibling, clients[2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('move domif (clients persist)', function(done) {
|
||||
var domif = document.querySelector('#simple');
|
||||
domif.if = true;
|
||||
Polymer.dom(innerContainer).appendChild(domif);
|
||||
setTimeout(function() {
|
||||
var clients = innerContainer.querySelectorAll('x-client');
|
||||
// Same clients as before since move happened in one turn
|
||||
assert.equal(clients[0].uid, 0);
|
||||
assert.equal(clients[1].uid, 1);
|
||||
assert.equal(clients[2].uid, 2);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(domif.previousElementSibling, clients[2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('remove, wait, append domif (clients recreated)', function(done) {
|
||||
var domif = document.querySelector('#simple');
|
||||
domif.if = true;
|
||||
Polymer.dom(innerContainer).removeChild(domif);
|
||||
setTimeout(function() {
|
||||
var clients = innerContainer.querySelectorAll('x-client');
|
||||
assert.equal(clients.length, 0);
|
||||
Polymer.dom(innerContainer).appendChild(domif);
|
||||
setTimeout(function() {
|
||||
var clients = outerContainer.querySelectorAll('x-client');
|
||||
// New clients since removed for a turn
|
||||
assert.equal(clients[0].uid, 3);
|
||||
assert.equal(clients[1].uid, 4);
|
||||
assert.equal(clients[2].uid, 5);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(domif.previousElementSibling, clients[2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('move host with domif (clients persist)', function(done) {
|
||||
var host = document.createElement('x-host');
|
||||
Polymer.dom(outerContainer).appendChild(host);
|
||||
setTimeout(function() {
|
||||
var clients = Polymer.dom(host.root).querySelectorAll('x-client');
|
||||
// New clients created in host instance
|
||||
assert.equal(clients[0].uid, 6);
|
||||
assert.equal(clients[1].uid, 7);
|
||||
assert.equal(clients[2].uid, 8);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(host.$.domif.previousElementSibling, clients[2]);
|
||||
Polymer.dom(innerContainer).appendChild(host);
|
||||
setTimeout(function() {
|
||||
var clients = Polymer.dom(host.root).querySelectorAll('x-client');
|
||||
// Clients in removed host persist
|
||||
assert.equal(clients[0].uid, 6);
|
||||
assert.equal(clients[1].uid, 7);
|
||||
assert.equal(clients[2].uid, 8);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(host.$.domif.previousElementSibling, clients[2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('remove, wait, append host with domif (clients persist)', function(done) {
|
||||
var host = document.createElement('x-host');
|
||||
Polymer.dom(outerContainer).appendChild(host);
|
||||
setTimeout(function() {
|
||||
var clients = Polymer.dom(host.root).querySelectorAll('x-client');
|
||||
// New clients created in host instance
|
||||
assert.equal(clients[0].uid, 9);
|
||||
assert.equal(clients[1].uid, 10);
|
||||
assert.equal(clients[2].uid, 11);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(host.$.domif.previousElementSibling, clients[2]);
|
||||
Polymer.dom(outerContainer).removeChild(host);
|
||||
setTimeout(function() {
|
||||
// Clients in removed host persist
|
||||
assert.equal(clients[0].uid, 9);
|
||||
assert.equal(clients[1].uid, 10);
|
||||
assert.equal(clients[2].uid, 11);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(host.$.domif.previousElementSibling, clients[2]);
|
||||
Polymer.dom(innerContainer).appendChild(host);
|
||||
setTimeout(function() {
|
||||
// Clients in removed host persist
|
||||
var clients = Polymer.dom(host.root).querySelectorAll('x-client');
|
||||
assert.equal(clients[0].uid, 9);
|
||||
assert.equal(clients[1].uid, 10);
|
||||
assert.equal(clients[2].uid, 11);
|
||||
assert.equal(clients[1].previousElementSibling, clients[0]);
|
||||
assert.equal(clients[2].previousElementSibling, clients[1]);
|
||||
assert.equal(host.$.domif.previousElementSibling, clients[2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user