Skip to content

Commit 0638419

Browse files
authored
fix(material/input): resolve memory leak on iOS (#24599)
1 parent d8c7c48 commit 0638419

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

src/material/input/input.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -308,24 +308,7 @@ export class MatInput
308308
// exists on iOS, we only bother to install the listener on iOS.
309309
if (_platform.IOS) {
310310
ngZone.runOutsideAngular(() => {
311-
_elementRef.nativeElement.addEventListener('keyup', (event: Event) => {
312-
const el = event.target as HTMLInputElement;
313-
314-
// Note: We specifically check for 0, rather than `!el.selectionStart`, because the two
315-
// indicate different things. If the value is 0, it means that the caret is at the start
316-
// of the input, whereas a value of `null` means that the input doesn't support
317-
// manipulating the selection range. Inputs that don't support setting the selection range
318-
// will throw an error so we want to avoid calling `setSelectionRange` on them. See:
319-
// https://html.spec.whatwg.org/multipage/input.html#do-not-apply
320-
if (!el.value && el.selectionStart === 0 && el.selectionEnd === 0) {
321-
// Note: Just setting `0, 0` doesn't fix the issue. Setting
322-
// `1, 1` fixes it for the first time that you type text and
323-
// then hold delete. Toggling to `1, 1` and then back to
324-
// `0, 0` seems to completely fix it.
325-
el.setSelectionRange(1, 1);
326-
el.setSelectionRange(0, 0);
327-
}
328-
});
311+
_elementRef.nativeElement.addEventListener('keyup', this._iOSKeyupListener);
329312
});
330313
}
331314

@@ -360,6 +343,10 @@ export class MatInput
360343
if (this._platform.isBrowser) {
361344
this._autofillMonitor.stopMonitoring(this._elementRef.nativeElement);
362345
}
346+
347+
if (this._platform.IOS) {
348+
this._elementRef.nativeElement.removeEventListener('keyup', this._iOSKeyupListener);
349+
}
363350
}
364351

365352
ngDoCheck() {
@@ -519,4 +506,23 @@ export class MatInput
519506
const element = this._elementRef.nativeElement as HTMLSelectElement;
520507
return this._isNativeSelect && (element.multiple || element.size > 1);
521508
}
509+
510+
private _iOSKeyupListener = (event: Event): void => {
511+
const el = event.target as HTMLInputElement;
512+
513+
// Note: We specifically check for 0, rather than `!el.selectionStart`, because the two
514+
// indicate different things. If the value is 0, it means that the caret is at the start
515+
// of the input, whereas a value of `null` means that the input doesn't support
516+
// manipulating the selection range. Inputs that don't support setting the selection range
517+
// will throw an error so we want to avoid calling `setSelectionRange` on them. See:
518+
// https://html.spec.whatwg.org/multipage/input.html#do-not-apply
519+
if (!el.value && el.selectionStart === 0 && el.selectionEnd === 0) {
520+
// Note: Just setting `0, 0` doesn't fix the issue. Setting
521+
// `1, 1` fixes it for the first time that you type text and
522+
// then hold delete. Toggling to `1, 1` and then back to
523+
// `0, 0` seems to completely fix it.
524+
el.setSelectionRange(1, 1);
525+
el.setSelectionRange(0, 0);
526+
}
527+
};
522528
}

0 commit comments

Comments
 (0)