From e02bc42e74c5a00f47691aee5a81eebbeb704891 Mon Sep 17 00:00:00 2001 From: Thomas Allmer Date: Fri, 12 Jul 2019 16:23:29 +0200 Subject: [PATCH] fix(overlays): fire show/hide event on shown changed --- .../overlays/src/LocalOverlayController.js | 19 +++++++++++++++ .../test/LocalOverlayController.test.js | 24 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/packages/overlays/src/LocalOverlayController.js b/packages/overlays/src/LocalOverlayController.js index 6387685ab..64726a5ce 100644 --- a/packages/overlays/src/LocalOverlayController.js +++ b/packages/overlays/src/LocalOverlayController.js @@ -7,6 +7,8 @@ async function __preloadPopper() { } export class LocalOverlayController { constructor(params = {}) { + this.__fakeExtendsEventTarget(); + // TODO: Instead of in constructor, prefetch it or use a preloader-manager to load it during idle time this.constructor.popperModule = __preloadPopper(); this.__mergePopperConfigs(params.popperConfig || {}); @@ -165,11 +167,19 @@ export class LocalOverlayController { if (this.trapsKeyboardFocus) this._setupTrapsKeyboardFocus(); if (this.hidesOnOutsideClick) this._setupHidesOnOutsideClick(); if (this.hidesOnEsc) this._setupHidesOnEsc(); + + if (this._prevShown === false) { + this.dispatchEvent(new Event('show')); + } } else { this._updateContent(); this.invokerNode.setAttribute('aria-expanded', false); if (this.hidesOnOutsideClick) this._teardownHidesOnOutsideClick(); if (this.hidesOnEsc) this._teardownHidesOnEsc(); + + if (this._prevShown === true) { + this.dispatchEvent(new Event('hide')); + } } this._prevShown = shown; this._prevData = data; @@ -301,4 +311,13 @@ export class LocalOverlayController { ...this.popperConfig, }); } + + // TODO: this method has to be removed when EventTarget polyfill is available on IE11 + // issue: https://gitlab.ing.net/TheGuideComponents/lion-element/issues/12 + __fakeExtendsEventTarget() { + const delegate = document.createDocumentFragment(); + ['addEventListener', 'dispatchEvent', 'removeEventListener'].forEach(funcName => { + this[funcName] = (...args) => delegate[funcName](...args); + }); + } } diff --git a/packages/overlays/test/LocalOverlayController.test.js b/packages/overlays/test/LocalOverlayController.test.js index f8d777664..3f2fd8202 100644 --- a/packages/overlays/test/LocalOverlayController.test.js +++ b/packages/overlays/test/LocalOverlayController.test.js @@ -1,4 +1,5 @@ import { expect, fixture, html, aTimeout, defineCE, unsafeStatic } from '@open-wc/testing'; +import sinon from 'sinon'; import Popper from 'popper.js/dist/popper.min.js'; import { keyUpOn } from '@polymer/iron-test-helpers/mock-interactions.js'; @@ -898,4 +899,27 @@ describe('LocalOverlayController', () => { expect(ctrl.isShown).to.equal(true); }); }); + + describe('events', () => { + it('fires "show" event once overlay becomes shown', async () => { + const showSpy = sinon.spy(); + const ctrl = new LocalOverlayController(); + ctrl.addEventListener('show', showSpy); + await ctrl.show(); + expect(showSpy.callCount).to.equal(1); + await ctrl.show(); + expect(showSpy.callCount).to.equal(1); + }); + + it('fires "hide" event once overlay becomes hidden', async () => { + const hideSpy = sinon.spy(); + const ctrl = new LocalOverlayController(); + ctrl.addEventListener('hide', hideSpy); + ctrl.hide(); + expect(hideSpy.callCount).to.equal(0); + await ctrl.show(); + ctrl.hide(); + expect(hideSpy.callCount).to.equal(1); + }); + }); });