tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit f4ee9ffe0839d5db2fed0a17a110d38c698fe07f
parent 454911cd834f085439203f6e66a285ceaeeeac40
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Fri,  3 Oct 2025 08:41:04 +0000

Bug 1787062 - Unify how <input> and <textarea> get initialized a bit. r=masayuki,smaug

Make the anonymous content creation synchronously so that we don't need
to update layout after-the-fact, and make editor creation lazy like we
do for <input>.

I think we should try to remove the trailing <br> for <textarea> after
this (just so that editor doesn't insert it). But this is green on try
and fixes the issue so worth landing incrementally.

Differential Revision: https://phabricator.services.mozilla.com/D267252

Diffstat:
Mlayout/forms/nsTextControlFrame.cpp | 16+++++-----------
Atesting/web-platform/tests/html/rendering/widgets/textarea-scroll-restoration.html | 49+++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp @@ -437,12 +437,7 @@ nsresult nsTextControlFrame::CreateAnonymousContent( } bool nsTextControlFrame::ShouldInitializeEagerly() const { - // textareas are eagerly initialized. - if (!IsSingleLineTextControl()) { - return true; - } - - // Also, input elements which have a cached selection should get eager + // Input elements which have a cached selection should get eager // editor initialization. TextControlElement* textControlElement = ControlElement(); if (textControlElement->HasCachedSelection()) { @@ -459,6 +454,7 @@ bool nsTextControlFrame::ShouldInitializeEagerly() const { // If text in the editor is being dragged, we need the editor to create // new source node for the drag session (TextEditor creates the text node // in the anonymous <div> element. + // XXX UpdateValueDisplay creates it now, is this needed? if (nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession(PresContext())) { if (dragSession->IsDraggingTextInTextControl()) { @@ -955,7 +951,9 @@ nsresult nsTextControlFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, AttrModType aModType) { if (aAttribute == nsGkAtoms::value && !mEditorHasBeenInitialized) { - UpdateValueDisplay(true); + if (IsSingleLineTextControl()) { + UpdateValueDisplay(true); + } return NS_OK; } @@ -1055,10 +1053,6 @@ void nsTextControlFrame::SetInitialChildList(ChildListID aListID, nsresult nsTextControlFrame::UpdateValueDisplay(bool aNotify, bool aBeforeEditorInit, const nsAString* aValue) { - if (!IsSingleLineTextControl()) { // textareas don't use this - return NS_OK; - } - MOZ_ASSERT(mRootNode, "Must have a div content\n"); MOZ_ASSERT(!mEditorHasBeenInitialized, "Do not call this after editor has been initialized"); diff --git a/testing/web-platform/tests/html/rendering/widgets/textarea-scroll-restoration.html b/testing/web-platform/tests/html/rendering/widgets/textarea-scroll-restoration.html @@ -0,0 +1,49 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Test textarea scroll restoration</title> +<link rel="help" href="https://html.spec.whatwg.org/#the-textarea-element-2"> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.com"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="container"> + <textarea id="textarea" rows=3> + A + B + C + D + E + F + G + H + I + </textarea> +</div> +<script> + +function frame() { + return new Promise(r => { + requestAnimationFrame(() => requestAnimationFrame(r)); + }); +} + +let container = document.getElementById("container"); +let textarea = document.getElementById("textarea"); + +async function test_restoration() { + textarea.scrollTop = 10000; + await frame(); + let top = textarea.scrollTop; + assert_not_equals(top, 0, "Should've scrolled down"); + container.style.display = "inline-block"; + assert_equals(textarea.scrollTop, top, "Should've preserved the scroll position"); + container.style.display = ""; +} + +promise_test(test_restoration); +promise_test(async function() { + textarea.focus(); + await frame(); + await test_restoration(); +}, "after focus"); +</script>