From 449bd4fb2b94f256dafd98acb86856dbc86ced6c Mon Sep 17 00:00:00 2001 From: mmalerba Date: Fri, 15 Jun 2018 13:24:23 -0700 Subject: [PATCH] fix(autofill): listen for animation events outside the zone, but emit autofill events inside (#11798) --- src/cdk/text-field/autofill.spec.ts | 15 ++++++++++++++- src/cdk/text-field/autofill.ts | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/cdk/text-field/autofill.spec.ts b/src/cdk/text-field/autofill.spec.ts index 598c202bf29e..97bd1bbc02de 100644 --- a/src/cdk/text-field/autofill.spec.ts +++ b/src/cdk/text-field/autofill.spec.ts @@ -7,7 +7,7 @@ */ import {supportsPassiveEventListeners} from '@angular/cdk/platform'; -import {Component, ElementRef, ViewChild} from '@angular/core'; +import {Component, ElementRef, NgZone, ViewChild} from '@angular/core'; import {ComponentFixture, inject, TestBed} from '@angular/core/testing'; import {EMPTY} from 'rxjs'; import {AutofillEvent, AutofillMonitor} from './autofill'; @@ -150,6 +150,19 @@ describe('AutofillMonitor', () => { expect(spy).toHaveBeenCalled(); }); + it('should emit on stream inside the NgZone', () => { + const inputEl = testComponent.input1.nativeElement; + let animationStartCallback: Function = () => {}; + inputEl.addEventListener.and.callFake((_, cb) => animationStartCallback = cb); + const autofillStream = autofillMonitor.monitor(inputEl); + const spy = jasmine.createSpy('zone spy'); + + autofillStream.subscribe(() => spy(NgZone.isInAngularZone())); + expect(spy).not.toHaveBeenCalled(); + + animationStartCallback({animationName: 'cdk-text-field-autofill-start', target: inputEl}); + expect(spy).toHaveBeenCalledWith(true); + }); }); describe('cdkAutofill', () => { diff --git a/src/cdk/text-field/autofill.ts b/src/cdk/text-field/autofill.ts index d0fd8f4e9af4..a73827183eb3 100644 --- a/src/cdk/text-field/autofill.ts +++ b/src/cdk/text-field/autofill.ts @@ -71,10 +71,10 @@ export class AutofillMonitor implements OnDestroy { const listener = (event: AnimationEvent) => { if (event.animationName === 'cdk-text-field-autofill-start') { element.classList.add('cdk-text-field-autofilled'); - result.next({target: event.target as Element, isAutofilled: true}); + this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: true})); } else if (event.animationName === 'cdk-text-field-autofill-end') { element.classList.remove('cdk-text-field-autofilled'); - result.next({target: event.target as Element, isAutofilled: false}); + this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: false})); } };