Skip to content

Commit e30852a

Browse files
crisbetotinayuangao
authored andcommitted
fix(overlay): OverlayKeyboardDispatcher not dispatching events when propagation is stopped (#9546)
Uses event capturing to ensure that we can dispatch events to the overlays even if bubbling was interrupted.
1 parent 085d805 commit e30852a

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/cdk/overlay/keyboard/overlay-keyboard-dispatcher.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,23 @@ describe('OverlayKeyboardDispatcher', () => {
6969
expect(overlayTwoSpy).toHaveBeenCalled();
7070
});
7171

72+
it('should dispatch keyboard events when propagation is stopped', () => {
73+
const overlayRef = overlay.create();
74+
const spy = jasmine.createSpy('keyboard event spy');
75+
const button = document.createElement('button');
76+
77+
document.body.appendChild(button);
78+
button.addEventListener('keydown', event => event.stopPropagation());
79+
80+
overlayRef.keydownEvents().subscribe(spy);
81+
keyboardDispatcher.add(overlayRef);
82+
dispatchKeyboardEvent(button, 'keydown', ESCAPE);
83+
84+
expect(spy).toHaveBeenCalled();
85+
86+
button.parentNode!.removeChild(button);
87+
});
88+
7289
it('should dispatch targeted keyboard events to the overlay containing that target', () => {
7390
const overlayOne = overlay.create();
7491
const overlayTwo = overlay.create();

src/cdk/overlay/keyboard/overlay-keyboard-dispatcher.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ export class OverlayKeyboardDispatcher implements OnDestroy {
6161
* events to the appropriate overlay.
6262
*/
6363
private _subscribeToKeydownEvents(): void {
64-
const bodyKeydownEvents = fromEvent<KeyboardEvent>(this._document.body, 'keydown');
64+
const bodyKeydownEvents = fromEvent<KeyboardEvent>(this._document.body, 'keydown', true);
6565

6666
this._keydownEventSubscription = bodyKeydownEvents.pipe(
6767
filter(() => !!this._attachedOverlays.length)
6868
).subscribe(event => {
69-
// Dispatch keydown event to correct overlay reference
69+
// Dispatch keydown event to the correct overlay.
7070
this._selectOverlayFromEvent(event)._keydownEvents.next(event);
7171
});
7272
}
@@ -87,7 +87,7 @@ export class OverlayKeyboardDispatcher implements OnDestroy {
8787
overlay.overlayElement.contains(event.target as HTMLElement);
8888
});
8989

90-
// Use that overlay if it exists, otherwise choose the most recently attached one
90+
// Use the overlay if it exists, otherwise choose the most recently attached one
9191
return targetedOverlay || this._attachedOverlays[this._attachedOverlays.length - 1];
9292
}
9393

0 commit comments

Comments
 (0)