Skip to content

Commit 7e1fd89

Browse files
crisbetommalerba
authored andcommitted
fix(text-field): unable to undo/redo in autosized text field on firefox (#19238)
1 parent de155e2 commit 7e1fd89

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

src/cdk/text-field/_text-field.scss

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,28 @@
2727
// removed when measuring is complete. We use `!important` rules here to make sure user-specified
2828
// rules do not interfere with the measurement.
2929
textarea.cdk-textarea-autosize-measuring {
30+
@include _cdk-textarea-autosize-measuring-base;
3031
height: auto !important;
3132
overflow: hidden !important;
32-
// Having 2px top and bottom padding seems to fix a bug where Chrome gets an incorrect
33-
// measurement. We just have to account for it later and subtract it off the final result.
34-
padding: 2px 0 !important;
35-
box-sizing: content-box !important;
3633
}
34+
35+
// Similar to the `cdk-textarea-autosize-measuring` class, but only applied on Firefox. We need
36+
// to use this class, because Firefox has a bug where changing the `overflow` breaks the user's
37+
// ability to undo/redo what they were typing (see #16629). This class is only scoped to Firefox,
38+
// because the measurements there don't seem to be affected by the `height: 0`, whereas on other
39+
// browsers they are, e.g. Chrome detects longer text and IE does't resize back to normal.
40+
// Identical issue report: https://bugzilla.mozilla.org/show_bug.cgi?id=448784
41+
textarea.cdk-textarea-autosize-measuring-firefox {
42+
@include _cdk-textarea-autosize-measuring-base;
43+
height: 0 !important;
44+
}
45+
}
46+
47+
@mixin _cdk-textarea-autosize-measuring-base {
48+
// Having 2px top and bottom padding seems to fix a bug where Chrome gets an incorrect
49+
// measurement. We just have to account for it later and subtract it off the final result.
50+
padding: 2px 0 !important;
51+
box-sizing: content-box !important;
3752
}
3853

3954
// Used to generate UIDs for keyframes used to change the text field autofill styles.

src/cdk/text-field/autosize.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
9494
/** Used to reference correct document/window */
9595
protected _document?: Document;
9696

97+
/** Class that should be applied to the textarea while it's being measured. */
98+
private _measuringClass: string;
99+
97100
constructor(private _elementRef: ElementRef<HTMLElement>,
98101
private _platform: Platform,
99102
private _ngZone: NgZone,
@@ -102,6 +105,9 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
102105
this._document = document;
103106

104107
this._textareaElement = this._elementRef.nativeElement as HTMLTextAreaElement;
108+
this._measuringClass = _platform.FIREFOX ?
109+
'cdk-textarea-autosize-measuring-firefox' :
110+
'cdk-textarea-autosize-measuring';
105111
}
106112

107113
/** Sets the minimum height of the textarea as determined by minRows. */
@@ -229,16 +235,16 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
229235
// Long placeholders that are wider than the textarea width may lead to a bigger scrollHeight
230236
// value. To ensure that the scrollHeight is not bigger than the content, the placeholders
231237
// need to be removed temporarily.
232-
textarea.classList.add('cdk-textarea-autosize-measuring');
238+
textarea.classList.add(this._measuringClass);
233239
textarea.placeholder = '';
234240

235-
// The cdk-textarea-autosize-measuring class includes a 2px padding to workaround an issue with
236-
// Chrome, so we account for that extra space here by subtracting 4 (2px top + 2px bottom).
241+
// The measuring class includes a 2px padding to workaround an issue with Chrome,
242+
// so we account for that extra space here by subtracting 4 (2px top + 2px bottom).
237243
const height = textarea.scrollHeight - 4;
238244

239245
// Use the scrollHeight to know how large the textarea *would* be if fit its entire value.
240246
textarea.style.height = `${height}px`;
241-
textarea.classList.remove('cdk-textarea-autosize-measuring');
247+
textarea.classList.remove(this._measuringClass);
242248
textarea.placeholder = placeholderText;
243249

244250
this._ngZone.runOutsideAngular(() => {

0 commit comments

Comments
 (0)