From 8564a0bf9ae3ff26b909ca907f3fc6c08bdb835e Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Mon, 9 Jul 2018 10:26:45 -0700 Subject: [PATCH] fix(autofill): avoid firing unnecessary event on initial render of input --- src/cdk/text-field/autofill.spec.ts | 13 ++++++++++++- src/cdk/text-field/autofill.ts | 14 ++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/cdk/text-field/autofill.spec.ts b/src/cdk/text-field/autofill.spec.ts index 97bd1bbc02de..624f8cca87d0 100644 --- a/src/cdk/text-field/autofill.spec.ts +++ b/src/cdk/text-field/autofill.spec.ts @@ -155,7 +155,7 @@ describe('AutofillMonitor', () => { let animationStartCallback: Function = () => {}; inputEl.addEventListener.and.callFake((_, cb) => animationStartCallback = cb); const autofillStream = autofillMonitor.monitor(inputEl); - const spy = jasmine.createSpy('zone spy'); + const spy = jasmine.createSpy('autofill spy'); autofillStream.subscribe(() => spy(NgZone.isInAngularZone())); expect(spy).not.toHaveBeenCalled(); @@ -163,6 +163,17 @@ describe('AutofillMonitor', () => { animationStartCallback({animationName: 'cdk-text-field-autofill-start', target: inputEl}); expect(spy).toHaveBeenCalledWith(true); }); + + it('should not emit on init if input is unfilled', () => { + const inputEl = testComponent.input1.nativeElement; + let animationStartCallback: Function = () => {}; + inputEl.addEventListener.and.callFake((_, cb) => animationStartCallback = cb); + const autofillStream = autofillMonitor.monitor(inputEl); + const spy = jasmine.createSpy('autofill spy'); + autofillStream.subscribe(() => spy()); + animationStartCallback({animationName: 'cdk-text-field-autofill-end', target: inputEl}); + expect(spy).not.toHaveBeenCalled(); + }); }); describe('cdkAutofill', () => { diff --git a/src/cdk/text-field/autofill.ts b/src/cdk/text-field/autofill.ts index a73827183eb3..814bcc2feb62 100644 --- a/src/cdk/text-field/autofill.ts +++ b/src/cdk/text-field/autofill.ts @@ -68,12 +68,18 @@ export class AutofillMonitor implements OnDestroy { } const result = new Subject(); + const cssClass = 'cdk-text-field-autofilled'; const listener = (event: AnimationEvent) => { - if (event.animationName === 'cdk-text-field-autofill-start') { - element.classList.add('cdk-text-field-autofilled'); + // Animation events fire on initial element render, we check for the presence of the autofill + // CSS class to make sure this is a real change in state, not just the initial render before + // we fire off events. + if (event.animationName === 'cdk-text-field-autofill-start' && + !element.classList.contains(cssClass)) { + element.classList.add(cssClass); 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'); + } else if (event.animationName === 'cdk-text-field-autofill-end' && + element.classList.contains(cssClass)) { + element.classList.remove(cssClass); this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: false})); } };