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

275 lines (254 loc) 7.61 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> <script> if (window.customElements) { customElements.forcePolyfill = true; } window.ShadyDOM = { force: true }; </script> <script src="../../../webcomponentsjs/webcomponents-lite.js"></script> <script src="../../../web-component-tester/browser.js"></script> <link rel="import" href="../../polymer.html"> </head> <body> <dom-module id="x-event-scoped"> <template> <div id="scoped" on-composed="childHandler" on-scoped="childHandler"></div> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-event-scoped', properties: { hostEvents: { type: Array, value: function() { return []; } }, childEvents: { type: Array, value: function() { return []; } } }, listeners: { 'composed': 'hostHandler', 'scoped': 'hostHandler' }, hostHandler: function(e) { this.hostEvents.push({ target: e.target, type: e.type, path: e.composedPath() }); }, childHandler: function(e) { this.childEvents.push({ target: e.target, type: e.type, path: e.composedPath() }); }, fireComposed: function() { return this.fire('composed', null, {node: this.$.scoped}); }, fireScoped: function(){ return this.fire('scoped', null, {node: this.$.scoped, composed: false}); } }); }); </script> </dom-module> <dom-module id="x-focus"> <template> <style> :host { display: block; } </style> <div id="child" on-focus="focusHandler"></div> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-focus', properties: { events: { type: Array, value: function() { return []; } } }, listeners: { focus: 'focusHandler' }, focusHandler: function(e) { this.events.push(e.target); }, fireComposed: function() { var ev = new Event('focus', {composed: true}); this.$.child.dispatchEvent(ev); }, fireScoped: function() { var ev = new Event('focus'); this.$.child.dispatchEvent(ev); } }); }); </script> </dom-module> <dom-module id="x-a"> <template> <div id="child" on-foo="childFooHandler"></div> <div id="child2"></div> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-a', listeners: { 'foo': 'fooHandler' }, fooHandler: function(e) { this.event = {target: e.target, relatedTarget: e.relatedTarget}; }, childFooHandler: function(e) { this.childEvent = {target: e.target, relatedTarget: e.relatedTarget}; } }); }); </script> </dom-module> <test-fixture id="scoped"> <template> <x-event-scoped></x-event-scoped> </template> </test-fixture> <test-fixture id="globalpatch"> <template> <div></div> </template> </test-fixture> <test-fixture id="focus"> <template> <x-focus></x-focus> </template> </test-fixture> <test-fixture id="relatedtarget"> <template> <x-a id="one"></x-a> <x-a id="two"></x-a> </template> </test-fixture> <dom-module id="x-slot-inner"> </dom-module> <test-fixture id="slot"> <template> <x-slot> <span class="target"></span> </x-slot> </template> </test-fixture> <script> suite('ShadyDOM event patching', function() { test('events retarget', function() { var el = fixture('scoped'); el.fireComposed(); assert.equal(el.hostEvents[0].target, el); assert.equal(el.childEvents[0].target, el.$.scoped); }); test('event.composedPath is consistent', function() { var el = fixture('scoped'); el.fireComposed(); assert.equal(el.hostEvents.length, el.childEvents.length); }); test('event patching works on non Polymer elements', function() { var el = fixture('globalpatch'); var path; el.addEventListener('foo', function(e) { path = e.composedPath(); }); var e = new Event('foo', {composed: true}); el.dispatchEvent(e); assert.deepEqual([el, el.parentNode, document.body, document.documentElement, document, window], path); }); test('`composed` flag controls event propagation through roots', function() { var el = fixture('scoped'); el.fireScoped(); el.fireComposed(); assert.equal(el.hostEvents.length, 1); assert.equal(el.hostEvents[0].type, 'composed'); assert.equal(el.childEvents.length, 2); assert.equal(el.childEvents[0].type, 'scoped'); assert.equal(el.childEvents[1].type, 'composed'); }); test('composed focus and blur events retarget up tree', function() { var el = fixture('focus'); el.fireComposed(); assert.equal(el.events.length, 2); assert.equal(el.events[0], el.$.child); assert.equal(el.events[1], el); }); test('scoped focus and blur events do not retarget', function() { var el = fixture('focus'); var e = new Event('focus'); if (e.isTrused !== false) { // skip browser if we cannot distinguish // native focus events from user created ones this.skip(); } el.fireScoped(); assert.equal(el.events.length, 1); assert.equal(el.events[0], el.$.child); }); test('composed relatedTarget retargets', function() { var els = fixture('relatedtarget'); var a = els[0]; var b = els[1]; var ev = new MouseEvent('foo', {bubbles: true, composed: true, relatedTarget: b.$.child}); a.$.child.dispatchEvent(ev); assert.property(a, 'childEvent'); assert.deepEqual(a.childEvent, {target: a.$.child, relatedTarget: b}); assert.property(a, 'event'); assert.deepEqual(a.event, {target: a, relatedTarget: b}); }); test('events do not fire if relatedtarget and target are the same node after retargeting', function() { var els = fixture('relatedtarget'); var a = els[0]; var ev = new MouseEvent('foo', {bubbles: true, composed: true, relatedTarget: a.$.child2}); a.$.child.dispatchEvent(ev); assert.property(a, 'childEvent'); assert.deepEqual(a.childEvent, {target: a.$.child, relatedTarget: a.$.child2}); assert.notProperty(a, 'event'); }); test('capturing event listeners fire correctly for focus and blur', function() { var el = fixture('focus'); var timeStamp; el.addEventListener('focus', function(e) { timeStamp = e.timeStamp; }, true); el.fireComposed(); assert.ok(timeStamp); assert.equal(el.events.length, 2); assert.equal(el.events[0], el.$.child); assert.equal(el.events[1], el); }); }); </script> </body> </html>