Skip to content

Commit 1748717

Browse files
arturovtwagnermaciel
authored andcommitted
fix(material/input): resolve memory leak on iOS (#24599)
(cherry picked from commit 0638419)
1 parent 4a4ebe7 commit 1748717

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
@@ -297,24 +297,7 @@ export class MatInput
297297
// exists on iOS, we only bother to install the listener on iOS.
298298
if (_platform.IOS) {
299299
ngZone.runOutsideAngular(() => {
300-
_elementRef.nativeElement.addEventListener('keyup', (event: Event) => {
301-
const el = event.target as HTMLInputElement;
302-
303-
// Note: We specifically check for 0, rather than `!el.selectionStart`, because the two
304-
// indicate different things. If the value is 0, it means that the caret is at the start
305-
// of the input, whereas a value of `null` means that the input doesn't support
306-
// manipulating the selection range. Inputs that don't support setting the selection range
307-
// will throw an error so we want to avoid calling `setSelectionRange` on them. See:
308-
// https://html.spec.whatwg.org/multipage/input.html#do-not-apply
309-
if (!el.value && el.selectionStart === 0 && el.selectionEnd === 0) {
310-
// Note: Just setting `0, 0` doesn't fix the issue. Setting
311-
// `1, 1` fixes it for the first time that you type text and
312-
// then hold delete. Toggling to `1, 1` and then back to
313-
// `0, 0` seems to completely fix it.
314-
el.setSelectionRange(1, 1);
315-
el.setSelectionRange(0, 0);
316-
}
317-
});
300+
_elementRef.nativeElement.addEventListener('keyup', this._iOSKeyupListener);
318301
});
319302
}
320303

@@ -349,6 +332,10 @@ export class MatInput
349332
if (this._platform.isBrowser) {
350333
this._autofillMonitor.stopMonitoring(this._elementRef.nativeElement);
351334
}
335+
336+
if (this._platform.IOS) {
337+
this._elementRef.nativeElement.removeEventListener('keyup', this._iOSKeyupListener);
338+
}
352339
}
353340

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

0 commit comments

Comments
 (0)