UNPKG

@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

1,058 lines (994 loc) 34.1 kB
<!doctype 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-element.html"> <link rel="import" href="../../lib/utils/flattened-nodes-observer.html"> </head> <body> <dom-module id='test-self-observe'> <template> <slot id="slot"></slot> </template> <script> HTMLImports.whenReady(function() { class TestSelfObserve extends Polymer.Element { static get is() { return 'test-self-observe';} connectedCallback() { super.connectedCallback(); this._observer = new Polymer.FlattenedNodesObserver(this, (info) => { this.info = info; }); } disconnectedCallback() { super.disconnectedCallback(); this._observer.disconnect(); } } customElements.define(TestSelfObserve.is, TestSelfObserve); }); </script> </dom-module> <dom-module id='test-static'> <template> <div>static</div> </template> <script> HTMLImports.whenReady(function() { class TestStatic extends Polymer.Element { static get is() { return 'test-static'; } } customElements.define(TestStatic.is, TestStatic); }); </script> </dom-module> <dom-module id='test-slot'> <template> <span id="slotContainer">[<slot id="slot"></slot>]</span> </template> <script> HTMLImports.whenReady(function() { class TestSlot extends Polymer.Element { static get is() { return 'test-slot'; } } customElements.define(TestSlot.is, TestSlot); }); </script> </dom-module> <dom-module id='test-slot1'> <template> <test-slot id="slot"><slot></slot></test-slot> </template> <script> HTMLImports.whenReady(function() { class TestSlot1 extends Polymer.Element { static get is() { return 'test-slot1'; } } customElements.define(TestSlot1.is, TestSlot1); }); </script> </dom-module> <dom-module id='test-slot2'> <template> <test-slot1 id="slot"><slot></slot></test-slot1> </template> <script> HTMLImports.whenReady(function() { class TestSlot2 extends Polymer.Element { static get is() { return 'test-slot2'; } } customElements.define(TestSlot2.is, TestSlot2); }); </script> </dom-module> <dom-module id='test-slot3'> <template> <test-slot2 id="slot"><slot></slot></test-slot2> </template> <script> HTMLImports.whenReady(function() { class TestSlot3 extends Polymer.Element { static get is() { return 'test-slot3'; } } customElements.define(TestSlot3.is, TestSlot3); }); </script> </dom-module> <dom-module id='test-slot-raw'> <template> <div id="slot"><slot></slot></div> </template> <script> HTMLImports.whenReady(function() { class TestSlotRaw extends Polymer.Element { static get is() { return 'test-slot-raw'; } } customElements.define(TestSlotRaw.is, TestSlotRaw); }); </script> </dom-module> <dom-module id='test-slot-attr'> <template> [<slot id="slot" name="d"></slot>] </template> <script> HTMLImports.whenReady(function() { class El extends Polymer.Element { static get is() { return 'test-slot-attr'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id='test-slot-attr1'> <template> <test-slot-attr id="slot"><slot name="c" slot="d"></slot></test-slot-attr> </template> <script> HTMLImports.whenReady(function() { class El extends Polymer.Element { static get is() { return 'test-slot-attr1'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id='test-slot-attr2'> <template> <test-slot-attr1 id="slot"><slot name="b" slot="c"></slot></test-slot-attr1> </template> <script> HTMLImports.whenReady(function() { class El extends Polymer.Element { static get is() { return 'test-slot-attr2'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id='test-slot-attr3'> <template> <test-slot-attr2 id="slot"><slot name="a" slot="b"></slot></test-slot-attr2> </template> <script> HTMLImports.whenReady(function() { class El extends Polymer.Element { static get is() { return 'test-slot-attr3'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id='test-slot-attr-inside'> <template> <test-slot-attr3 id="slot"><slot name="a" slot="a"></slot></test-slot-attr3> </template> <script> HTMLImports.whenReady(function() { class El extends Polymer.Element { static get is() { return 'test-slot-attr-inside'; } } customElements.define(El.is, El); }); </script> </dom-module> <test-slot><div>A</div><div>B</div></test-slot> <test-static><div>static A</div><div>static B</div></test-static> <div id="staticDiv"></div> <script> suite('observeNodes', function() { test('observe initial state of distributing element', function() { var recordedA; var el = document.querySelector('test-slot'); var observer1 = new Polymer.FlattenedNodesObserver(el, function(info) { recordedA = info; }); observer1.flush(); assert.equal(recordedA.addedNodes.length, 2); recordedA = null; var recordedB; var observer2 = new Polymer.FlattenedNodesObserver(el, function(info) { recordedB = info; }); observer2.flush(); assert.equal(recordedA, null); assert.equal(recordedB.addedNodes.length, 2); observer1.disconnect(); observer2.disconnect(); }); test('observe initial state of non-distributing element', function() { var recordedA; var el = document.querySelector('test-static'); var observer1 = new Polymer.FlattenedNodesObserver(el, function(info) { recordedA = info; }); observer1.flush(); assert.equal(recordedA.addedNodes.length, 2); recordedA = null; var recordedB; var observer2 = new Polymer.FlattenedNodesObserver(el, function(info) { recordedB = info; }); observer2.flush(); assert.equal(recordedA, null); assert.equal(recordedB.addedNodes.length, 2); observer1.disconnect(); observer2.disconnect(); }); test('observeNodes called in observed node context', function(done) { var el = document.createElement('test-slot'); document.body.appendChild(el); var observer = new Polymer.FlattenedNodesObserver(el, function() { assert.equal(this, el); done(); }); // add var d = document.createElement('div'); el.appendChild(d); observer.flush(); }); test('observe children changes to distributing element', function() { var el = document.createElement('test-slot'); document.body.appendChild(el); var recorded; var observer = new Polymer.FlattenedNodesObserver(el, function(info) { recorded = info; }); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // reset, unobserve and remove recorded = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded, null); document.body.removeChild(el); }); test('observe children changes to distributing element that provoke additional changes', function() { var el = document.createElement('test-slot'); document.body.appendChild(el); var recordedInfo, elAddedInObserver; var observerCallCount = 0; var observer = new Polymer.FlattenedNodesObserver(el, function(info) { observerCallCount++; recordedInfo = info; if (info.target.childNodes.length < 5) { elAddedInObserver = document.createElement('div'); info.target.appendChild(elAddedInObserver); } }); // add var d = document.createElement('div'); el.appendChild(d); while (observer.flush()) { // re-flush until done } assert.equal(observerCallCount, 5); assert.equal(recordedInfo.addedNodes.length, 1); assert.equal(recordedInfo.addedNodes[0], elAddedInObserver); assert.equal(el.childNodes.length, 5); document.body.removeChild(el); observer.disconnect(); }); test('observe children changes to distributing element (async)', function(done) { var el = document.createElement('test-slot'); document.body.appendChild(el); var nodes = []; var handle = new Polymer.FlattenedNodesObserver(el, function(info) { for (var i=0, at; i < info.removedNodes.length; i++) { at = nodes.indexOf(info.removedNodes[i]); assert.isAbove(at, -1); nodes.splice(at, 1); } nodes = nodes.concat(info.addedNodes); }); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); let getFlattenedNodes = Polymer.FlattenedNodesObserver.getFlattenedNodes; setTimeout(function() { assert.sameMembers(getFlattenedNodes(el), nodes); // remove el.removeChild(d); el.removeChild(d1); setTimeout(function() { assert.sameMembers(getFlattenedNodes(el), nodes); // add el.appendChild(d); el.appendChild(d1); setTimeout(function() { assert.sameMembers(getFlattenedNodes(el), nodes); handle.disconnect(); el.removeChild(d); el.removeChild(d1); setTimeout(function() { assert.notEqual(nodes.length, getFlattenedNodes(el).length); document.body.removeChild(el); done(); }); }); }); }); }); test('observe children changes to non-distributing element', function() { var el = document.createElement('test-static'); document.body.appendChild(el); var recorded; var observer = new Polymer.FlattenedNodesObserver(el, function(info) { recorded = info; }); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // reset, unobserve and remove recorded = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded, null); document.body.removeChild(el); }); test('observe changes to inner node wrapping <slot>', function() { var el = document.createElement('test-slot'); document.body.appendChild(el); var observedInfo; var observer = new Polymer.FlattenedNodesObserver(el.$.slotContainer, function(info) { observedInfo = info; }); observer.flush(); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(observedInfo.target, el.$.slotContainer); assert.equal(observedInfo.addedNodes.length, 2); assert.equal(observedInfo.removedNodes.length, 0); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(observedInfo.addedNodes.length, 0); assert.equal(observedInfo.removedNodes.length, 2); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(observedInfo.addedNodes.length, 2); assert.equal(observedInfo.removedNodes.length, 0); // reset, unobserve and remove observedInfo = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(observedInfo, null); document.body.removeChild(el); }); test('observe changes to <slot>', function() { var el = document.createElement('test-slot'); document.body.appendChild(el); var observedInfo; var observer = new Polymer.FlattenedNodesObserver(el.$.slot, function(info) { observedInfo = info; }); observer.flush(); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(observedInfo.target, el.$.slot); assert.equal(observedInfo.addedNodes.length, 2); assert.equal(observedInfo.removedNodes.length, 0); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(observedInfo.addedNodes.length, 0); assert.equal(observedInfo.removedNodes.length, 2); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(observedInfo.addedNodes.length, 2); assert.equal(observedInfo.removedNodes.length, 0); // reset, unobserve and remove observedInfo = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(observedInfo, null); document.body.removeChild(el); }); test('observe effective children inside distributing element', function() { var el = document.createElement('test-slot1'); document.body.appendChild(el); var recorded; var observer = new Polymer.FlattenedNodesObserver(el.$.slot, function(info) { recorded = info; }); observer.flush(); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // reset, unobserve and remove recorded = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded, null); document.body.removeChild(el); }); test('observe effective children changes when adding to another host', function() { var el = document.createElement('test-slot1'); document.body.appendChild(el); var recorded; var observer = new Polymer.FlattenedNodesObserver(el.$.slot, function(info) { recorded = info; }); observer.flush(); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // add somewhere else... we should see these as removes document.body.appendChild(d); document.body.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // cleanup document.body.removeChild(d); document.body.removeChild(d1); document.body.removeChild(el); observer.disconnect(); }); test('observe effective children changes in static slot when adding to another host', function() { var el = document.createElement('staticDiv'); document.body.appendChild(el); var recorded; var observer = new Polymer.FlattenedNodesObserver(el, function(info) { recorded = info; }); observer.flush(); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // add somewhere else... we should see these as removes document.body.appendChild(d); document.body.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // cleanup document.body.removeChild(d); document.body.removeChild(d1); document.body.removeChild(el); observer.disconnect(); }); test('observe effective children inside deep distributing element', function() { var el = document.createElement('test-slot3'); document.body.appendChild(el); var recorded; var slot = el.$.slot.$.slot.$.slot; var observer = new Polymer.FlattenedNodesObserver(slot, function(info) { recorded = info; }); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // reset, unobserve and remove recorded = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded, null); document.body.removeChild(el); }); test('observe <slot> inside deep distributing element', function() { var el = document.createElement('test-slot3'); document.body.appendChild(el); var recorded; var slot = el.$.slot.$.slot.$.slot.$.slot; assert.equal(slot.localName, 'slot'); var observer = new Polymer.FlattenedNodesObserver(slot, function(info) { recorded = info; }); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // remove el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // add el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // reset, unobserve and remove recorded = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); observer.flush(); assert.equal(recorded, null); document.body.removeChild(el); }); test('observe effective children inside deep distributing element (async)', function(done) { var el = document.createElement('test-slot3'); document.body.appendChild(el); var recorded; var slot = el.$.slot.$.slot.$.slot; var observer = new Polymer.FlattenedNodesObserver(slot, function(info) { recorded = info; }); // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); setTimeout(function() { assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // remove el.removeChild(d); el.removeChild(d1); setTimeout(function() { assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 2); assert.equal(recorded.removedNodes[0], d); assert.equal(recorded.removedNodes[1], d1); // add el.appendChild(d); el.appendChild(d1); setTimeout(function() { assert.equal(recorded.addedNodes.length, 2); assert.equal(recorded.addedNodes[0], d); assert.equal(recorded.addedNodes[1], d1); // reset, unobserve and remove recorded = null; observer.disconnect(); el.removeChild(d); el.removeChild(d1); setTimeout(function() { assert.equal(recorded, null); document.body.removeChild(el); done(); }); }); }); }); }); test('observe effective children attr changes inside deep distributing element (async)', function(done) { var el = document.createElement('test-slot-attr3'); document.body.appendChild(el); var recorded; var slot = el.$.slot.$.slot.$.slot; var observer = new Polymer.FlattenedNodesObserver(slot, function(info) { recorded = info; }); observer.flush(); recorded = null; // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded, null); setTimeout(function() { assert.equal(recorded, null); d.setAttribute('slot', 'a'); setTimeout(function() { assert.equal(recorded.addedNodes.length, 1); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); d.removeAttribute('slot'); setTimeout(function() { assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 1); assert.equal(recorded.removedNodes[0], d); recorded = null; observer.disconnect(); d.setAttribute('slot', 'a'); setTimeout(function() { assert.equal(recorded, null); document.body.removeChild(el); done(); }); }); }); }); }); test('observe effective children attr changes inside deep distributing element without outer select (async)', function(done) { var el = document.createElement('test-slot-attr-inside'); document.body.appendChild(el); var recorded; var slot = el.$.slot.$.slot.$.slot.$.slot; var observer = new Polymer.FlattenedNodesObserver(slot, function(info) { recorded = info; }); observer.flush(); recorded = null; // add var d = document.createElement('div'); var d1 = document.createElement('div'); el.appendChild(d); el.appendChild(d1); observer.flush(); assert.equal(recorded, null); setTimeout(function() { assert.equal(recorded, null); d.setAttribute('slot', 'a'); setTimeout(function() { assert.equal(recorded.addedNodes.length, 1); assert.equal(recorded.removedNodes.length, 0); assert.equal(recorded.addedNodes[0], d); d.removeAttribute('slot'); setTimeout(function() { assert.equal(recorded.addedNodes.length, 0); assert.equal(recorded.removedNodes.length, 1); assert.equal(recorded.removedNodes[0], d); recorded = null; observer.disconnect(); d.setAttribute('slot', 'a'); setTimeout(function() { assert.equal(recorded, null); document.body.removeChild(el); done(); }); }); }); }); }); test('add/remove multiple observers', function() { var el = document.createElement('test-slot1'); document.body.appendChild(el); var r1 = 0; var h1 = new Polymer.FlattenedNodesObserver(el.$.slot, function() { r1++; }); var r2 = 0; var h2 = new Polymer.FlattenedNodesObserver(el.$.slot, function() { r2++; }); var r3 = 0; var h3 = new Polymer.FlattenedNodesObserver(el.$.slot, function() { r3++; }); // add var d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 1); assert.equal(r2, 1); assert.equal(r3, 1); h1.disconnect(); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 1); assert.equal(r2, 2); assert.equal(r3, 2); h2.disconnect(); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 1); assert.equal(r2, 2); assert.equal(r3, 3); h3.disconnect(); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 1); assert.equal(r2, 2); assert.equal(r3, 3); h1 = new Polymer.FlattenedNodesObserver(el.$.slot, h1.callback); h2 = new Polymer.FlattenedNodesObserver(el.$.slot, h2.callback); h3 = new Polymer.FlattenedNodesObserver(el.$.slot, h3.callback); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 2); assert.equal(r2, 3); assert.equal(r3, 4); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 3); assert.equal(r2, 4); assert.equal(r3, 5); h3.disconnect(); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 4); assert.equal(r2, 5); assert.equal(r3, 5); h2.disconnect(); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 5); assert.equal(r2, 5); assert.equal(r3, 5); h1.disconnect(); d = document.createElement('div'); el.appendChild(d); h1.flush(); h2.flush(); h3.flush(); assert.equal(r1, 5); assert.equal(r2, 5); assert.equal(r3, 5); }); test('observe changes of target with dynamically added <slot>', function() { var el = document.createElement('test-static'); document.body.appendChild(el); var container = el.shadowRoot.childNodes[1]; var recorded = null; var observer = new Polymer.FlattenedNodesObserver(container, function(info) { recorded = info; }); var slot = document.createElement('slot'); container.appendChild(slot); observer.flush(); recorded = null; var child = document.createElement('div'); el.appendChild(child); observer.flush(); assert.equal(recorded.addedNodes.length, 1); assert.equal(recorded.addedNodes[0], child); recorded = null; el.removeChild(child); observer.flush(); assert.equal(recorded.removedNodes.length, 1); assert.equal(recorded.removedNodes[0], child); recorded = null; container.removeChild(slot); observer.flush(); el.appendChild(child); assert.equal(recorded, null); observer.disconnect(); document.body.removeChild(el); }); test('observe changes of target with dynamically added <slot> (flush/async)', function(done) { var el = document.createElement('test-static'); document.body.appendChild(el); var container = el.shadowRoot.childNodes[1]; var recorded = null; var observer = new Polymer.FlattenedNodesObserver(container, function(info) { recorded = info; }); var slot = document.createElement('slot'); container.appendChild(slot); observer.flush(); recorded = null; var child = document.createElement('div'); el.appendChild(child); setTimeout(function() { assert.equal(recorded.addedNodes.length, 1); assert.equal(recorded.addedNodes[0], child); done(); }); }); test('observe changes of target with dynamically added <slot> (async)', function(done) { var el = document.createElement('test-static'); document.body.appendChild(el); var container = el.shadowRoot.childNodes[1]; var recorded = null; var observer = new Polymer.FlattenedNodesObserver(container, function(info) { recorded = info; }); var slot = document.createElement('slot'); container.appendChild(slot); observer.flush(); recorded = null; var child = document.createElement('div'); el.appendChild(child); setTimeout(function() { assert.equal(recorded.addedNodes.length, 1); assert.equal(recorded.addedNodes[0], child); recorded = null; el.removeChild(child); setTimeout(function() { assert.equal(recorded.removedNodes.length, 1); assert.equal(recorded.removedNodes[0], child); recorded = null; container.removeChild(slot); setTimeout(function() { el.appendChild(child); assert.equal(recorded, null); observer.disconnect(); document.body.removeChild(el); done(); }); }); }); }); test('element distributed to insertion point observing itself', function() { var host = document.createElement('test-slot'); var el = document.createElement('test-self-observe'); host.appendChild(el); document.body.appendChild(host); if (window.ShadyDOM) { ShadyDOM.flush(); } assert.ok(el._observer); var div = document.createElement('div'); el.appendChild(div); el._observer.flush(); assert.equal(el.info.addedNodes[0], div); document.body.removeChild(host); }); test('should not fail on node without children', function() { var recorded; var el = document; var observer = new Polymer.FlattenedNodesObserver(el, function(info) { recorded = info; }); assert.equal(recorded, null); observer.disconnect(); }); }); </script> </body> </html>