diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts index a3350ba97dc2..1611aefefc94 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts @@ -277,6 +277,23 @@ describe('FocusMonitor', () => { // After 2 ticks, the timeout has cleared the origin. Default is 'program'. expect(changeHandler).toHaveBeenCalledWith('program'); })); + + it('should check children if monitor was called with different checkChildren', fakeAsync(() => { + const parent = fixture.nativeElement.querySelector('.parent'); + + focusMonitor.monitor(parent, true); + focusMonitor.monitor(parent, false); + + // Simulate focus via mouse. + dispatchMouseEvent(buttonElement, 'mousedown'); + buttonElement.focus(); + fixture.detectChanges(); + flush(); + + expect(parent.classList).toContain('cdk-focused'); + expect(parent.classList).toContain('cdk-mouse-focused'); + })); + }); describe('FocusMonitor with "eventual" detection', () => { @@ -569,7 +586,7 @@ describe('FocusMonitor observable stream', () => { @Component({ - template: `` + template: `
` }) class PlainButton {} diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.ts b/src/cdk/a11y/focus-monitor/focus-monitor.ts index 3e42634ec91f..8688bdac29d9 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.ts @@ -235,11 +235,17 @@ export class FocusMonitor implements OnDestroy { // the shadow root, rather than the `document`, because the browser won't emit focus events // to the `document`, if focus is moving within the same shadow root. const rootNode = (_getShadowRoot(nativeElement) as HTMLElement|null) || this._getDocument(); + const cachedInfo = this._elementInfo.get(nativeElement); // Check if we're already monitoring this element. - if (this._elementInfo.has(nativeElement)) { - const cachedInfo = this._elementInfo.get(nativeElement)!; - cachedInfo.checkChildren = checkChildren; + if (cachedInfo) { + if (checkChildren) { + // TODO(COMP-318): this can be problematic, because it'll turn all non-checkChildren + // observers into ones that behave as if `checkChildren` was turned on. We need a more + // robust solution. + cachedInfo.checkChildren = true; + } + return cachedInfo.subject.asObservable(); }