Skip to content

Commit 20037ba

Browse files
committed
feat(overlays): delegate events in DynamicOverlayController
1 parent ab0b871 commit 20037ba

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

packages/overlays/src/DynamicOverlayController.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export class DynamicOverlayController {
3434
if (!this.content) {
3535
this.content = document.createElement('div');
3636
}
37+
this.__fakeExtendsEventTarget();
38+
this.__delegateEvent = this.__delegateEvent.bind(this);
3739
}
3840

3941
add(ctrlToAdd) {
@@ -71,9 +73,13 @@ export class DynamicOverlayController {
7173
if (this.isShown === true) {
7274
throw new Error('You can not switch overlays while being shown');
7375
}
76+
const prevActive = this.active;
77+
7478
this.active.switchOut();
7579
ctrlToSwitchTo.switchIn();
7680
this.__active = ctrlToSwitchTo;
81+
82+
this._delegateEvents(this.__active, prevActive);
7783
}
7884

7985
async show() {
@@ -99,4 +105,24 @@ export class DynamicOverlayController {
99105
get invokerNode() {
100106
return this.active.invokerNode;
101107
}
108+
109+
_delegateEvents(active, prevActive) {
110+
['show', 'hide'].forEach(event => {
111+
active.addEventListener(event, this.__delegateEvent);
112+
prevActive.removeEventListener(event, this.__delegateEvent);
113+
});
114+
}
115+
116+
__delegateEvent(ev) {
117+
ev.stopPropagation();
118+
this.dispatchEvent(new Event(ev.type));
119+
}
120+
121+
// TODO: this method has to be removed when EventTarget polyfill is available on IE11
122+
__fakeExtendsEventTarget() {
123+
const delegate = document.createDocumentFragment();
124+
['addEventListener', 'dispatchEvent', 'removeEventListener'].forEach(funcName => {
125+
this[funcName] = (...args) => delegate[funcName](...args);
126+
});
127+
}
102128
}

packages/overlays/test/DynamicOverlayController.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,34 @@ describe('DynamicOverlayController', () => {
133133
expect(globalOutSpy).to.have.callCount(1);
134134
expect(localInSpy).to.have.callCount(1);
135135
});
136+
137+
describe('API abstraction for active overlay controller', () => {
138+
describe('Events', () => {
139+
it('delegates "show/hide" event', async () => {
140+
const ctrl = new DynamicOverlayController();
141+
const global = new FakeGlobalCtrl(defaultOptions);
142+
const local = new FakeLocalCtrl(defaultOptions);
143+
ctrl.add(global);
144+
ctrl.add(local);
145+
ctrl.switchTo(local);
146+
147+
const showSpy = sinon.spy();
148+
const hideSpy = sinon.spy();
149+
150+
ctrl.addEventListener('show', showSpy);
151+
ctrl.addEventListener('hide', hideSpy);
152+
153+
await ctrl.show();
154+
expect(showSpy.callCount).to.equal(1);
155+
await ctrl.hide();
156+
expect(hideSpy.callCount).to.equal(1);
157+
158+
ctrl.switchTo(global);
159+
await ctrl.show();
160+
expect(showSpy.callCount).to.equal(2);
161+
await ctrl.hide();
162+
expect(hideSpy.callCount).to.equal(2);
163+
});
164+
});
165+
});
136166
});

0 commit comments

Comments
 (0)