@polymer/polymer
Version:
The Polymer library makes it easy to create your own web components. Give your element some markup and properties, and then use it on a site. Polymer provides features like dynamic templates and data binding to reduce the amount of boilerplate you need to
906 lines (810 loc) • 37.6 kB
HTML
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
<meta charset="utf-8">
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../../web-component-tester/browser.js"></script>
<link rel="import" href="../../polymer.html">
<link rel="import" href="dom-if-elements.html">
</head>
<body>
<x-nested-if-configured id="configured"></x-nested-if-configured>
<x-nested-if-individual id="individual"></x-nested-if-individual>
<dom-bind id="unconfigured">
<template>
<x-nested-if id="unconfigured1"></x-nested-if>
<x-nested-if id="unconfigured2"></x-nested-if>
</template>
</dom-bind>
<div id="inDocumentContainer">
<dom-if id="inDocumentIf">
<template>
<x-foo
prop="{{prop}}"
item-prop="{{item.prop}}">
</x-foo>
<template is="dom-if">
<x-foo
prop="{{prop}}"
item-prop="{{item.prop}}">
</x-foo>
<template is="dom-if">
<x-foo
prop="{{prop}}"
item-prop="{{item.prop}}">
</x-foo>
</template>
</template>
</template>
</dom-if>
</div>
<div id="structuredContainer">
<dom-bind id="structuredDomBind">
<template>
<template is="dom-if" id="structuredDomIf" if="{{item.show}}">
<div class="showing"></div>
</template>
</template>
</dom-bind>
</div>
<div id="outerContainer">
<dom-if id="simple">
<template>
<x-client></x-client>
<x-client></x-client>
<x-client></x-client>
</template>
</dom-if>
<div id="innerContainer">
</div>
</div>
<div id="removalContainer">
<dom-if if id="toBeRemoved">
<template><div id="shouldBeRemoved"></div></template>
</dom-if>
</div>
<script> /* force non-upgrade, to test MO-based template finding below */ </script>
<div id="nonUpgrade">
<dom-if if>
<template>stamped</template>
</dom-if>
</div>
<script>
/* global configured individual unconfigured1 unconfigured2 inDocumentContainer inDocumentIf structuredContainer structuredDomIf structuredDomBind outerContainer innerContainer shouldBeRemoved toBeRemoved removalContainer nonUpgrade*/
suite('nested pre-configured dom-if', function() {
test('parent scope binding', function() {
let stamped = configured.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(stamped[0].prop, 'outer');
assert.equal(stamped[0].itemProp, 'outerItem');
assert.equal(stamped[1].prop, 'outer');
assert.equal(stamped[1].itemProp, 'outerItem');
assert.equal(stamped[2].prop, 'outer');
assert.equal(stamped[2].itemProp, 'outerItem');
});
test('parent scope downward notification', function() {
let stamped = configured.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
configured.prop = 'yes';
assert.equal(stamped[0].prop, 'yes');
assert.equal(stamped[1].prop, 'yes');
assert.equal(stamped[2].prop, 'yes');
configured.set('item.prop', 'yay');
assert.equal(stamped[0].itemProp, 'yay');
assert.equal(stamped[1].itemProp, 'yay');
assert.equal(stamped[2].itemProp, 'yay');
});
test('parent upward upward notification', function() {
let stamped = configured.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
stamped[2].prop = 'nice';
assert.equal(configured.prop, 'nice');
assert.equal(stamped[0].prop, 'nice');
assert.equal(stamped[1].prop, 'nice');
assert.equal(stamped[2].prop, 'nice');
});
test('dom-change event composed, bubbles outside dom-if scope', function() {
let domChangeFired = 0;
let domIf = configured.$['if-1'];
configured.addEventListener('dom-change', function() {
domChangeFired++;
});
domIf.if = !domIf.if;
domIf.render();
domIf.if = !domIf.if;
domIf.render();
assert.equal(domChangeFired, 2);
});
});
suite('nested individually-controlled dom-if', function() {
test('nothing stamped', function() {
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 0, 'total stamped count incorrect');
});
test('show 1', function() {
individual.shouldStamp1 = true;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 1, 'total stamped count incorrect');
assert.equal(stamped[0].prop, 'prop1');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
});
test('show 2', function() {
individual.shouldStamp2 = true;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 2, 'total stamped count incorrect');
assert.equal(stamped[0].prop, 'prop1');
assert.equal(stamped[1].prop, 'prop2');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'inline', 'stamped 2 display wrong');
});
test('show 3', function() {
individual.shouldStamp3 = true;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(stamped[0].prop, 'prop1');
assert.equal(stamped[1].prop, 'prop2');
assert.equal(stamped[2].prop, 'prop3');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'inline', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'inline', 'stamped 3 display wrong');
});
test('hide 3', function() {
individual.shouldStamp3 = false;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'inline', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'none', 'stamped 3 display wrong');
});
test('hide 2', function() {
individual.shouldStamp2 = false;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'none', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'none', 'stamped 3 display wrong');
});
test('hide 1', function() {
individual.shouldStamp1 = false;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(getComputedStyle(stamped[0]).display, 'none', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'none', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'none', 'stamped 3 display wrong');
});
test('show 1', function() {
individual.shouldStamp1 = true;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'none', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'none', 'stamped 3 display wrong');
});
test('show 2', function() {
individual.shouldStamp2 = true;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'inline', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'none', 'stamped 3 display wrong');
});
test('show 3', function() {
individual.shouldStamp3 = true;
individual.render();
let stamped = individual.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
assert.equal(getComputedStyle(stamped[0]).display, 'inline', 'stamped 1 display wrong');
assert.equal(getComputedStyle(stamped[1]).display, 'inline', 'stamped 2 display wrong');
assert.equal(getComputedStyle(stamped[2]).display, 'inline', 'stamped 3 display wrong');
});
});
suite('nested un-configured dom-if in document', function() {
test('if=false: nothing rendered', function() {
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if)');
assert.equal(stamped.length, 0, 'total stamped count incorrect');
});
test('if=true: everything rendered and visible', function() {
// first dom-if
inDocumentIf.if = true;
inDocumentIf.render();
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 1, 'total stamped count incorrect');
// second dom-if
let xif = inDocumentContainer.querySelector('dom-if');
xif.if = true;
xif.render();
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 2, 'total stamped count incorrect');
// third dom-if
xif = inDocumentContainer.querySelector('dom-if');
xif.if = true;
xif.render();
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if)');
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'inline', 'node was hidden but should not have been');
});
});
test('if=false, restamp=false: everything hidden', function() {
inDocumentIf.if = false;
inDocumentIf.render();
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if)');
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'none', 'node was not hidden but should have been');
});
});
test('if=true, restamp=true, everything rendered and visible', function() {
inDocumentIf.restamp = true;
inDocumentIf.if = true;
inDocumentIf.render();
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if)');
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'inline', 'node was hidden but should not have been');
});
});
test('if=false, restamp=true, everything gone', function() {
inDocumentIf.restamp = true;
inDocumentIf.if = false;
inDocumentIf.render();
// 2nd one needed to force nested if to detach
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if)');
assert.equal(stamped.length, 0, 'total stamped count incorrect');
});
// repeat, just to get everything rendered again...
test('if=true: everything rendered and visible', function() {
// first dom-if
inDocumentIf.if = true;
inDocumentIf.render();
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 1, 'total stamped count incorrect');
// second dom-if
let xif = inDocumentContainer.querySelector('dom-if');
xif.if = true;
xif.render();
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 2, 'total stamped count incorrect');
// third dom-if
xif = inDocumentContainer.querySelector('dom-if');
xif.if = true;
xif.render();
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if)');
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'inline', 'node was hidden but should not have been');
});
});
test('parent scope binding', function() {
let stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-if):not(span)');
stamped[0].prop = 'outer';
assert.equal(stamped[1].prop, 'outer');
assert.equal(stamped[2].prop, 'outer');
});
});
suite('nested un-configured dom-if', function() {
test('if=false: nothing rendered', function() {
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if)');
assert.equal(stamped.length, 0, 'total stamped count incorrect');
});
test('if=true: everything rendered and visible', function() {
unconfigured1.domUpdateHandlerCount = 0;
unconfigured1.shouldStamp = true;
unconfigured2.shouldStamp = true;
unconfigured1.render();
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped[0].prop = 'outer';
assert.equal(unconfigured1.domUpdateHandlerCount, 1);
});
test('if=false, restamp=false: everything hidden', function() {
unconfigured1.domUpdateHandlerCount = 0;
unconfigured1.shouldStamp = false;
unconfigured1.render();
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if)');
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'none', 'node was not hidden but should have been');
});
assert.equal(unconfigured1.domUpdateHandlerCount, 1);
});
test('if=true, restamp=true, everything rendered and visible', function() {
unconfigured1.domUpdateHandlerCount = 0;
unconfigured1.$['if-1'].restamp = true;
unconfigured1.shouldStamp = true;
unconfigured1.$['if-1'].render();
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if)');
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'inline', 'node was hidden but should not have been');
});
assert.equal(unconfigured1.domUpdateHandlerCount, 1);
});
test('if=false, restamp=true, everything gone', function() {
unconfigured1.domUpdateHandlerCount = 0;
unconfigured1.$['if-1'].restamp = true;
unconfigured1.shouldStamp = false;
unconfigured1.$['if-1'].render();
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if)');
assert.equal(unconfigured1.domUpdateHandlerCount, 1);
assert.equal(stamped.length, 0, 'total stamped count incorrect');
assert.equal(unconfigured1.domUpdateHandlerCount, 1);
});
// repeat, just to get everything rendered again...
test('if=true: everything rendered and visible', function() {
unconfigured1.domUpdateHandlerCount = 0;
unconfigured1.shouldStamp = true;
unconfigured2.shouldStamp = true;
unconfigured1.render();
unconfigured2.render();
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped[0].prop = 'outer';
assert.equal(unconfigured1.domUpdateHandlerCount, 1);
});
test('parent scope binding', function() {
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
assert.equal(stamped[1].prop, 'outer');
assert.equal(stamped[2].prop, 'outer');
});
test('parent upward upward notification', function() {
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
stamped[2].prop = 'nice';
assert.equal(stamped[0].prop, 'nice');
assert.equal(stamped[1].prop, 'nice');
});
test('event handlers', function() {
let stamped = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
stamped[0].fire('test1');
assert.equal(unconfigured1.testHandler1Count, 1);
stamped[1].fire('test2');
assert.equal(unconfigured1.testHandler2Count, 1);
stamped[2].fire('test3');
assert.equal(unconfigured1.testHandler3Count, 1);
});
});
suite('notification between two dom-ifs', function() {
test('change to one scope doesn\'t affect other dom-if', function() {
let stamped1 = unconfigured1.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
let stamped2 = unconfigured2.shadowRoot.querySelectorAll('*:not(template):not(dom-if):not(span)');
unconfigured1.prop = 'foo';
unconfigured2.prop = 'bar';
assert.equal(stamped1[0].prop, 'foo');
assert.equal(stamped1[1].prop, 'foo');
assert.equal(stamped1[2].prop, 'foo');
assert.equal(stamped2[0].prop, 'bar');
assert.equal(stamped2[1].prop, 'bar');
assert.equal(stamped2[2].prop, 'bar');
});
});
suite('structured data controlling if', function() {
test('item changed with no if field', function() {
let showing;
showing = structuredContainer.querySelector('.showing');
assert.notOk(showing);
structuredDomBind.item = {show: true};
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.ok(showing);
assert.equal(getComputedStyle(showing).display, 'block');
structuredDomBind.item = {};
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.ok(showing);
assert.equal(getComputedStyle(showing).display, 'none');
structuredDomBind.item = {show: true};
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.ok(showing);
assert.equal(getComputedStyle(showing).display, 'block');
});
test('item changed with no if field (restamp)', function() {
let showing;
structuredDomIf.restamp = true;
structuredDomIf.if = false;
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.notOk(showing);
structuredDomBind.item = {show: true};
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.ok(showing);
structuredDomBind.item = {};
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.notOk(showing);
structuredDomBind.item = {show: true};
structuredDomIf.render();
showing = structuredContainer.querySelector('.showing');
assert.ok(showing);
});
});
suite('text node handling', function() {
test('text nodes cleared on if=false', function() {
let x = document.createElement('x-textcontent');
document.body.appendChild(x);
x.$.domIf.render();
let stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 12);
assert.equal(stamped[7].textContent.trim(), 'Stuff');
x.$.domIf.if = false;
x.$.domIf.render();
stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 12);
assert.equal(stamped[7].textContent.trim(), '');
x.$.domIf.if = true;
x.$.domIf.render();
stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 12);
assert.equal(stamped[7].textContent.trim(), 'Stuff');
document.body.removeChild(x);
});
test('binding to text nodes changed while if=false', function() {
let x = document.createElement('x-textcontent');
document.body.appendChild(x);
x.$.domIf.render();
let stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 12);
assert.equal(stamped[7].textContent.trim(), 'Stuff');
x.$.domIf.if = false;
x.$.domIf.render();
x.text = 'Hollaaaaa!';
stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 12);
assert.equal(stamped[7].textContent.trim(), '');
x.$.domIf.if = true;
x.$.domIf.render();
stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 12);
assert.equal(stamped[7].textContent.trim(), 'Hollaaaaa!');
document.body.removeChild(x);
});
});
suite('slot handling', function() {
test('slots added/removed on if=true/false', function() {
let x = document.createElement('x-slot');
let one = document.createElement('div');
one.slot = 'one';
x.appendChild(one);
let two = document.createElement('div');
two.slot = 'two';
x.appendChild(two);
let three = document.createElement('div');
three.slot = 'three';
x.appendChild(three);
document.body.appendChild(x);
x.$.domIf.render();
let stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 14);
assert.equal(stamped[4].assignedNodes()[0], one);
assert.equal(stamped[8].assignedNodes()[0], two);
assert.equal(stamped[10].assignedNodes()[0], three);
x.$.domIf.if = false;
x.$.domIf.render();
stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 14);
x.$.domIf.if = true;
x.$.domIf.render();
stamped = x.shadowRoot.childNodes;
assert.equal(stamped.length, 14);
assert.equal(stamped[4].assignedNodes()[0], one);
assert.equal(stamped[8].assignedNodes()[0], two);
assert.equal(stamped[10].assignedNodes()[0], three);
x.$.domIf.if = false;
x.$.domIf.render();
const innerIf = x.shadowRoot.querySelector('#innerIf');
innerIf.if = false;
innerIf.render();
x.$.domIf.if = true;
x.$.domIf.render();
stamped = x.shadowRoot.childNodes;
assert.equal(stamped[4].assignedNodes()[0], one);
assert.equal(stamped[7].assignedNodes()[0], two);
assert.equal(stamped[9].assignedNodes()[0], three);
document.body.removeChild(x);
});
});
suite('attach/detach tests', function() {
test('move domif (clients persist)', function(done) {
let domif = document.querySelector('#simple');
domif.if = true;
innerContainer.appendChild(domif);
setTimeout(function() {
let 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) {
let domif = document.querySelector('#simple');
domif.if = true;
innerContainer.removeChild(domif);
setTimeout(function() {
let clients = innerContainer.querySelectorAll('x-client');
assert.equal(clients.length, 0);
innerContainer.appendChild(domif);
setTimeout(function() {
let 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) {
let host = document.createElement('x-host');
outerContainer.appendChild(host);
setTimeout(function() {
let clients = host.shadowRoot.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]);
innerContainer.appendChild(host);
setTimeout(function() {
let clients = host.shadowRoot.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) {
let host = document.createElement('x-host');
outerContainer.appendChild(host);
setTimeout(function() {
let clients = host.shadowRoot.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]);
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]);
innerContainer.appendChild(host);
setTimeout(function() {
// Clients in removed host persist
let clients = host.shadowRoot.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();
});
});
});
});
test('remove, append domif', function(done) {
let domif = document.querySelector('#simple');
let parent = domif.parentNode;
domif.if = true;
parent.removeChild(domif);
setTimeout(function() {
let clients = parent.querySelectorAll('x-client');
assert.equal(clients.length, 0);
parent.appendChild(domif);
setTimeout(function() {
let clients = parent.querySelectorAll('x-client');
assert.equal(clients[0].uid, 12);
assert.equal(clients[1].uid, 13);
assert.equal(clients[2].uid, 14);
assert.equal(clients[1].previousElementSibling, clients[0]);
assert.equal(clients[2].previousElementSibling, clients[1]);
assert.equal(domif.previousElementSibling, clients[2]);
done();
});
});
});
test('move into doc fragment', function(done) {
let el = shouldBeRemoved;
assert.equal(el.parentNode, removalContainer);
let frag = document.createDocumentFragment();
frag.appendChild(toBeRemoved);
setTimeout(function() {
assert.equal(el.parentNode, null);
removalContainer.appendChild(frag);
setTimeout(function() {
assert.equal(shouldBeRemoved.parentNode, removalContainer);
done();
});
});
});
test('move into shadow root', function(done) {
if (Polymer.Settings.hasShadow) {
let el = shouldBeRemoved;
assert.equal(el.parentNode, removalContainer);
let div = document.createElement('div');
document.body.appendChild(div);
let frag = div.createShadowRoot();
frag.appendChild(toBeRemoved);
setTimeout(function() {
assert.equal(el.parentNode, frag);
done();
});
} else {
done();
}
});
});
suite('timing', function() {
test('non-upgrade case finds template', function() {
assert.equal(nonUpgrade.textContent.trim(), 'stamped');
});
});
[true, false].forEach(function(restamp) {
suite('ordering, restamp: ' + restamp, function() {
test('effects in if not run when `if` goes false via property', function() {
let el = document.createElement('x-guard-prop');
el.restamp = restamp;
document.body.appendChild(el);
el.bool = true;
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), 'true');
el.bool = false;
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), '');
document.body.removeChild(el);
});
test('effects in if not run when `if` goes false via inline function', function() {
let el = document.createElement('x-guard-inline');
el.restamp = restamp;
document.body.appendChild(el);
el.bool = true;
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), 'true');
el.bool = false;
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), '');
document.body.removeChild(el);
});
test('effects in if not run when `if` goes false via computed property', function() {
let el = document.createElement('x-guard-computed');
el.restamp = restamp;
document.body.appendChild(el);
el.bool = true;
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), 'true');
el.bool = false;
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), '');
document.body.removeChild(el);
});
test('effects in if not run when `if` goes false via object sub-property', function() {
let el = document.createElement('x-guard-object');
el.restamp = restamp;
document.body.appendChild(el);
el.obj = {bool: true};
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), 'true');
el.obj = {bool: false};
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), '');
document.body.removeChild(el);
});
test('effects in if not run when `if` goes false via computed from object sub-property', function() {
let el = document.createElement('x-guard-object-computed');
el.restamp = restamp;
document.body.appendChild(el);
el.obj = {bool: true};
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), 'true');
el.obj = {bool: false};
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), '');
document.body.removeChild(el);
});
test('effects in if not run when `if` goes false via setProperties batch', function() {
let el = document.createElement('x-guard-separate-props');
el.restamp = restamp;
document.body.appendChild(el);
el.setProperties({a: 'ok', b: true});
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), 'ok');
el.setProperties({a: 'notok', b: false});
Polymer.flush();
assert.equal(el.guarded.callCount, 1);
assert.equal(el.shadowRoot.textContent.trim(), '');
document.body.removeChild(el);
});
test('host properties in sync when changed while false', function() {
let el = document.createElement('x-guard-separate-props');
el.restamp = restamp;
document.body.appendChild(el);
el.a = 'ok';
el.b = true;
Polymer.flush();
assert.equal(el.shadowRoot.textContent.trim(), 'ok');
el.b = false;
el.a = 'notok';
Polymer.flush();
assert.equal(el.shadowRoot.textContent.trim(), '');
el.a = 'changed';
el.b = true;
Polymer.flush();
assert.equal(el.shadowRoot.textContent.trim(), 'changed');
document.body.removeChild(el);
});
test('host paths in sync when changed while false', function() {
let el = document.createElement('x-guard-separate-paths');
el.restamp = restamp;
document.body.appendChild(el);
el.obj = {a: 'ok', b: true};
Polymer.flush();
assert.equal(el.shadowRoot.textContent.trim(), 'ok');
el.set('obj.b', false);
el.set('obj.a', 'notok');
Polymer.flush();
assert.equal(el.shadowRoot.textContent.trim(), '');
el.set('obj.a', 'changed');
el.set('obj.b', true);
Polymer.flush();
assert.equal(el.shadowRoot.textContent.trim(), 'changed');
document.body.removeChild(el);
});
});
});
</script>
</body>
</html>