Fix comment textarea scroll issue in Firefox (#34438) (#34446)

Backport #34438 by @silverwind

In the comment editor, there is a bug in Firefox where the scroll
position unexpectedly moves up, which is annoying. This is not
reproducible in Chrome and Safari. To reproduce here are some steps:

- Go into an editable issue
- Scroll page to bottom
- Focus the textarea and press Return many times, causing the textarea
to get a scrollbar
- Scroll page to bottom again
- Press Return once more
- Page should not scroll up.

This fixes the bug by adding a temporary margin, and I verified it works
in all browsers.

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Giteabot 2025-05-14 00:39:02 +08:00 committed by GitHub
parent 94b67f1967
commit 89f1df033a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -168,6 +168,7 @@ export function autosize(textarea: HTMLTextAreaElement, {viewportMarginBottom =
function resizeToFit() { function resizeToFit() {
if (isUserResized) return; if (isUserResized) return;
if (textarea.offsetWidth <= 0 && textarea.offsetHeight <= 0) return; if (textarea.offsetWidth <= 0 && textarea.offsetHeight <= 0) return;
const previousMargin = textarea.style.marginBottom;
try { try {
const {top, bottom} = overflowOffset(); const {top, bottom} = overflowOffset();
@ -183,6 +184,9 @@ export function autosize(textarea: HTMLTextAreaElement, {viewportMarginBottom =
const curHeight = parseFloat(computedStyle.height); const curHeight = parseFloat(computedStyle.height);
const maxHeight = curHeight + bottom - adjustedViewportMarginBottom; const maxHeight = curHeight + bottom - adjustedViewportMarginBottom;
// In Firefox, setting auto height momentarily may cause the page to scroll up
// unexpectedly, prevent this by setting a temporary margin.
textarea.style.marginBottom = `${textarea.clientHeight}px`;
textarea.style.height = 'auto'; textarea.style.height = 'auto';
let newHeight = textarea.scrollHeight + borderAddOn; let newHeight = textarea.scrollHeight + borderAddOn;
@ -203,6 +207,12 @@ export function autosize(textarea: HTMLTextAreaElement, {viewportMarginBottom =
textarea.style.height = `${newHeight}px`; textarea.style.height = `${newHeight}px`;
lastStyleHeight = textarea.style.height; lastStyleHeight = textarea.style.height;
} finally { } finally {
// restore previous margin
if (previousMargin) {
textarea.style.marginBottom = previousMargin;
} else {
textarea.style.removeProperty('margin-bottom');
}
// ensure that the textarea is fully scrolled to the end, when the cursor // ensure that the textarea is fully scrolled to the end, when the cursor
// is at the end during an input event // is at the end during an input event
if (textarea.selectionStart === textarea.selectionEnd && if (textarea.selectionStart === textarea.selectionEnd &&