Skip to content

Commit c2fc3f4

Browse files
mmalerbajosephperrott
authored andcommitted
fix(autofill): avoid firing unnecessary event on initial render of input (#12116)
1 parent b23cecd commit c2fc3f4

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

src/cdk/text-field/autofill.spec.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,25 @@ describe('AutofillMonitor', () => {
155155
let animationStartCallback: Function = () => {};
156156
inputEl.addEventListener.and.callFake((_, cb) => animationStartCallback = cb);
157157
const autofillStream = autofillMonitor.monitor(inputEl);
158-
const spy = jasmine.createSpy('zone spy');
158+
const spy = jasmine.createSpy('autofill spy');
159159

160160
autofillStream.subscribe(() => spy(NgZone.isInAngularZone()));
161161
expect(spy).not.toHaveBeenCalled();
162162

163163
animationStartCallback({animationName: 'cdk-text-field-autofill-start', target: inputEl});
164164
expect(spy).toHaveBeenCalledWith(true);
165165
});
166+
167+
it('should not emit on init if input is unfilled', () => {
168+
const inputEl = testComponent.input1.nativeElement;
169+
let animationStartCallback: Function = () => {};
170+
inputEl.addEventListener.and.callFake((_, cb) => animationStartCallback = cb);
171+
const autofillStream = autofillMonitor.monitor(inputEl);
172+
const spy = jasmine.createSpy('autofill spy');
173+
autofillStream.subscribe(() => spy());
174+
animationStartCallback({animationName: 'cdk-text-field-autofill-end', target: inputEl});
175+
expect(spy).not.toHaveBeenCalled();
176+
});
166177
});
167178

168179
describe('cdkAutofill', () => {

src/cdk/text-field/autofill.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,18 @@ export class AutofillMonitor implements OnDestroy {
6868
}
6969

7070
const result = new Subject<AutofillEvent>();
71+
const cssClass = 'cdk-text-field-autofilled';
7172
const listener = (event: AnimationEvent) => {
72-
if (event.animationName === 'cdk-text-field-autofill-start') {
73-
element.classList.add('cdk-text-field-autofilled');
73+
// Animation events fire on initial element render, we check for the presence of the autofill
74+
// CSS class to make sure this is a real change in state, not just the initial render before
75+
// we fire off events.
76+
if (event.animationName === 'cdk-text-field-autofill-start' &&
77+
!element.classList.contains(cssClass)) {
78+
element.classList.add(cssClass);
7479
this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: true}));
75-
} else if (event.animationName === 'cdk-text-field-autofill-end') {
76-
element.classList.remove('cdk-text-field-autofilled');
80+
} else if (event.animationName === 'cdk-text-field-autofill-end' &&
81+
element.classList.contains(cssClass)) {
82+
element.classList.remove(cssClass);
7783
this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: false}));
7884
}
7985
};

0 commit comments

Comments
 (0)