fix(focus-monitor): reenter ngzone before emitting (#10549)

This commit is contained in:
mmalerba
2018-05-04 11:18:07 -07:00
committed by Joey Perrott
parent 01ec602b0b
commit 37193d823b
2 changed files with 45 additions and 8 deletions
@@ -5,7 +5,7 @@ import {
dispatchMouseEvent,
patchElementFocus,
} from '@angular/cdk/testing';
import {Component} from '@angular/core';
import {Component, NgZone} from '@angular/core';
import {ComponentFixture, fakeAsync, flush, inject, TestBed, tick} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {A11yModule} from '../index';
@@ -212,7 +212,6 @@ describe('FocusMonitor', () => {
expect(buttonElement.classList.length).toBe(0, 'button should not have any focus classes');
}));
});
@@ -224,7 +223,7 @@ describe('cdkMonitorFocus', () => {
ButtonWithFocusClasses,
ComplexComponentWithMonitorElementFocus,
ComplexComponentWithMonitorSubtreeFocus,
ComplexComponentWithMonitorSubtreeFocusAnfMonitorElementFocus,
ComplexComponentWithMonitorSubtreeFocusAndMonitorElementFocus,
],
}).compileComponents();
});
@@ -394,7 +393,7 @@ describe('cdkMonitorFocus', () => {
});
describe('complex component with cdkMonitorSubtreeFocus and cdkMonitorElementFocus', () => {
let fixture: ComponentFixture<ComplexComponentWithMonitorSubtreeFocusAnfMonitorElementFocus>;
let fixture: ComponentFixture<ComplexComponentWithMonitorSubtreeFocusAndMonitorElementFocus>;
let parentElement: HTMLElement;
let childElement: HTMLElement;
let focusMonitor: FocusMonitor;
@@ -402,7 +401,7 @@ describe('cdkMonitorFocus', () => {
beforeEach(inject([FocusMonitor], (fm: FocusMonitor) => {
focusMonitor = fm;
fixture =
TestBed.createComponent(ComplexComponentWithMonitorSubtreeFocusAnfMonitorElementFocus);
TestBed.createComponent(ComplexComponentWithMonitorSubtreeFocusAndMonitorElementFocus);
fixture.detectChanges();
parentElement = fixture.debugElement.query(By.css('div')).nativeElement;
@@ -424,6 +423,40 @@ describe('cdkMonitorFocus', () => {
});
});
describe('FocusMonitor observable stream', () => {
let fixture: ComponentFixture<PlainButton>;
let buttonElement: HTMLElement;
let focusMonitor: FocusMonitor;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [A11yModule],
declarations: [
PlainButton,
],
}).compileComponents();
});
beforeEach(inject([FocusMonitor], (fm: FocusMonitor) => {
fixture = TestBed.createComponent(PlainButton);
focusMonitor = fm;
fixture.detectChanges();
buttonElement = fixture.debugElement.nativeElement.querySelector('button');
patchElementFocus(buttonElement);
}));
it('should emit inside the NgZone', fakeAsync(() => {
const spy = jasmine.createSpy('zone spy');
focusMonitor.monitor(buttonElement).subscribe(() => spy(NgZone.isInAngularZone()));
expect(spy).not.toHaveBeenCalled();
buttonElement.focus();
fixture.detectChanges();
tick();
expect(spy).toHaveBeenCalledWith(true);
}));
});
@Component({
template: `<button>focus me!</button>`
@@ -453,4 +486,4 @@ class ComplexComponentWithMonitorSubtreeFocus {}
@Component({
template: `<div cdkMonitorSubtreeFocus><button cdkMonitorElementFocus></button></div>`
})
class ComplexComponentWithMonitorSubtreeFocusAnfMonitorElementFocus {}
class ComplexComponentWithMonitorSubtreeFocusAndMonitorElementFocus {}
+6 -2
View File
@@ -314,7 +314,7 @@ export class FocusMonitor implements OnDestroy {
}
this._setClasses(element, origin);
elementInfo.subject.next(origin);
this._emitOrigin(elementInfo.subject, origin);
this._lastFocusOrigin = origin;
}
@@ -334,7 +334,11 @@ export class FocusMonitor implements OnDestroy {
}
this._setClasses(element);
elementInfo.subject.next(null);
this._emitOrigin(elementInfo.subject, null);
}
private _emitOrigin(subject: Subject<FocusOrigin>, origin: FocusOrigin) {
this._ngZone.run(() => subject.next(origin));
}
private _incrementMonitoredElementCount() {