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

278 lines (244 loc) 8.19 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.html"> </head> <body> <script> window.clearTestLists = function() { window.actualAttachedList = []; window.actualReadyList = []; window.actualReadyBeforeAttachedList = []; }; window.clearTestLists(); window.readyMixin = function(base) { return class readyMixin extends base { static get properties() { return { prop: { value: true, observer: '_propChanged' } }; } _propChanged() { this.observerShadowRoot = Boolean(this.shadowRoot); } ready() { super.ready(); this._readied = true; this.readyList = window.actualReadyList.slice(); this.readyShadowRoot = Boolean(this.shadowRoot); window.actualReadyList.push(this); } connectedCallback() { this._eventList = []; this.addEventListener('e', (e) => { this._eventList.push(e.composedPath()[0]); }); super.connectedCallback(); this.dispatchEvent(new Event('e', {composed: true, bubbles: true})); this.attachedShadowRoot = Boolean(this.shadowRoot); this.attachedTime$Keys = Object.keys(this.$); this.attachedList = window.actualAttachedList.slice(); window.actualAttachedList.push(this); if (!this._readied) { window.actualReadyBeforeAttachedList.push(this); } } }; }; </script> <dom-module id="x-zot"> <template> x-zot<slot></slot> </template> <script> HTMLImports.whenReady(function() { class El extends window.readyMixin(Polymer.Element) { static get is() { return 'x-zot'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id="x-bar"> <template> <x-zot id="zot"></x-zot> </template> <script> HTMLImports.whenReady(function() { class El extends window.readyMixin(Polymer.Element) { static get is() { return 'x-bar'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id="x-foo"> <template> <x-bar id="bar1"></x-bar> <x-bar id="bar2"></x-bar> </template> <script> HTMLImports.whenReady(function() { class El extends window.readyMixin(Polymer.Element) { static get is() { return 'x-foo'; } } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id="x-ready"> <template> <x-zot id="a"> <x-zot id="b"></x-zot> <x-zot id="c"> <x-zot id="d"></x-zot> </x-zot> </x-zot> <x-foo id="foo"></x-foo> </template> <script> HTMLImports.whenReady(function() { class El extends window.readyMixin(Polymer.Element) { static get is() { return 'x-ready'; } static get properties() { return { foo: { observer: '_fooChanged' } }; } _fooChanged() {} } customElements.define(El.is, El); }); </script> </dom-module> <dom-module id="x-templatized"> <template> <template is="dom-if" if> <x-ready foo="[[foo]]"></x-ready> </template> </template> <script> HTMLImports.whenReady(function() { class El extends Polymer.Element { static get is() { return 'x-templatized'; } static get properties() { return { foo: { value: 'foo' } }; } } customElements.define(El.is, El); }); </script> </dom-module> <script> suite('ready and attached ordering', function() { let el; setup(function() { window.clearTestLists(); el = document.createElement('x-ready'); document.body.appendChild(el); }); teardown(function() { document.body.removeChild(el); }); test('element dom ready before element', function() { assert.includeMembers(el.readyList, [el.$.a, el.$.b, el.$.c, el.$.d, el.$.foo]); var foo = el.$.foo; assert.includeMembers(foo.readyList, [foo.$.bar1, foo.$.bar1.$.zot, foo.$.bar2, foo.$.bar2.$.zot]); var b1 = foo.$.bar1, b2 = foo.$.bar2; assert.includeMembers(b1.readyList, [b1.$.zot]); assert.includeMembers(b2.readyList, [b2.$.zot]); }); test('can listen to events fired by element dom in connected', function() { assert.includeMembers(el._eventList, [el.$.a, el.$.b, el.$.c, el.$.d, el.$.foo]); var foo = el.$.foo; assert.includeMembers(foo._eventList, [foo.$.bar1, foo.$.bar2]); var b1 = foo.$.bar1, b2 = foo.$.bar2; assert.includeMembers(b1._eventList, [b1.$.zot]); assert.includeMembers(b2._eventList, [b2.$.zot]); }); test('shadowRoot available in ready, connected, observer', function() { [el, el.$.a, el.$.b, el.$.c, el.$.d, el.$.foo, el.$.foo.$.bar1, el.$.foo.$.bar1.$.zot, el.$.foo.$.bar2, el.$.foo.$.bar2.$.zot].forEach((e) => { assert.isTrue(e.observerShadowRoot); assert.isTrue(e.readyShadowRoot); assert.isTrue(e.attachedShadowRoot); }); }); test('element attached called after ready', function() { assert.equal(window.actualReadyBeforeAttachedList.length, 0); }); test('element has $ references at attached time', function() { assert.sameMembers(el.attachedTime$Keys, ['a', 'b', 'c', 'd', 'foo']); assert.sameMembers(el.$.foo.attachedTime$Keys, ['bar1', 'bar2']); }); }); suite('templatized: ready and attached ordering', function() { let container, el; setup(function() { window.clearTestLists(); container = document.createElement('x-templatized'); document.body.appendChild(container); Polymer.flush(); el = container.shadowRoot.querySelector('x-ready'); }); teardown(function() { document.body.removeChild(container); }); test('element dom ready before element', function() { assert.includeMembers(el.readyList, [el.$.a, el.$.b, el.$.c, el.$.d, el.$.foo]); var foo = el.$.foo; assert.includeMembers(foo.readyList, [foo.$.bar1, foo.$.bar1.$.zot, foo.$.bar2, foo.$.bar2.$.zot]); var b1 = foo.$.bar1, b2 = foo.$.bar2; assert.includeMembers(b1.readyList, [b1.$.zot]); assert.includeMembers(b2.readyList, [b2.$.zot]); }); test('can listen to events fired by element dom in connected', function() { assert.includeMembers(el._eventList, [el.$.a, el.$.b, el.$.c, el.$.d, el.$.foo]); var foo = el.$.foo; assert.includeMembers(foo._eventList, [foo.$.bar1, foo.$.bar2]); var b1 = foo.$.bar1, b2 = foo.$.bar2; assert.includeMembers(b1._eventList, [b1.$.zot]); assert.includeMembers(b2._eventList, [b2.$.zot]); }); test('shadowRoot available in ready, connected, observer', function() { [el, el.$.a, el.$.b, el.$.c, el.$.d, el.$.foo, el.$.foo.$.bar1, el.$.foo.$.bar1.$.zot, el.$.foo.$.bar2, el.$.foo.$.bar2.$.zot].forEach((e) => { assert.isTrue(e.observerShadowRoot); assert.isTrue(e.readyShadowRoot); assert.isTrue(e.attachedShadowRoot); }); }); test('element attached called after ready', function() { assert.equal(window.actualReadyBeforeAttachedList.length, 0); }); test('element has $ references at attached time', function() { assert.sameMembers(el.attachedTime$Keys, ['a', 'b', 'c', 'd', 'foo']); assert.sameMembers(el.$.foo.attachedTime$Keys, ['bar1', 'bar2']); }); }); </script> </body> </html>