tor-browser

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

commit fc644383f5d49d8c9786c11f6add062b01968c8d
parent 4ca534f021c23fd2a77fcf9844e8d47eb357148b
Author: Hiroyuki Ikezoe <hikezoe.birchill@mozilla.com>
Date:   Wed, 15 Oct 2025 08:17:08 +0000

Bug 1994305 - Invoke DesiredAsyncPanZoomState::Update in HideCaretsAndDispatchCaretStateChangedEvent. r=TYLin,layout-reviewers,edgar

While moving the focus from a `user-select: text` element to `user-text:
none` element, no selectionchange event is fired. Rather `blur` event is
fired on the `user-select: text` element.

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

Diffstat:
Mdom/base/nsDOMWindowUtils.cpp | 6++++++
Mdom/interfaces/base/nsIDOMWindowUtils.idl | 5+++++
Mlayout/base/AccessibleCaretManager.cpp | 1+
Mlayout/base/tests/mochitest.toml | 3+++
Alayout/base/tests/test_re_enable_apz_on_blur.html | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp @@ -3055,6 +3055,12 @@ nsDOMWindowUtils::DisableApzForElement(Element* aElement) { return NS_OK; } +NS_IMETHODIMP +nsDOMWindowUtils::IsApzDisabledForElement(Element* aElement, bool* aOutResult) { + *aOutResult = nsLayoutUtils::ShouldDisableApzForElement(aElement); + return NS_OK; +} + static nsTArray<ScrollContainerFrame*> CollectScrollableAncestors( nsIFrame* aStart) { nsTArray<ScrollContainerFrame*> result; diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -1647,6 +1647,11 @@ cenum AsyncEnabledOption : 8 { void disableApzForElement(in Element aElement); /** + * Returns whether APZ is being disabled on the given |aElement|. + */ + boolean isApzDisabledForElement(in Element aElement); + + /** * Ask APZ to pan and zoom to the focused input element. */ [can_run_script] void zoomToFocusedInput(); diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp @@ -181,6 +181,7 @@ void AccessibleCaretManager::HideCaretsAndDispatchCaretStateChangedEvent() { mCarets.GetFirst()->SetAppearance(Appearance::None); mCarets.GetSecond()->SetAppearance(Appearance::None); mIsCaretPositionChanged = false; + mDesiredAsyncPanZoomState.Update(*this); DispatchCaretStateChangedEvent(CaretChangedReason::Visibilitychange); } } diff --git a/layout/base/tests/mochitest.toml b/layout/base/tests/mochitest.toml @@ -296,6 +296,9 @@ support-files = ["preserve3d_sorting_hit_testing_iframe.html"] ["test_preserve3d_sorting_hit_testing2.html"] support-files = ["preserve3d_sorting_hit_testing2_iframe.html"] +["test_re_enable_apz_on_blur.html"] +skip-if = ["os == 'win'"] + ["test_refreshDriver_hasPendingTick.html"] ["test_reftests_with_caret.html"] diff --git a/layout/base/tests/test_re_enable_apz_on_blur.html b/layout/base/tests/test_re_enable_apz_on_blur.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script src="/tests/SimpleTest/paint_listener.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> + <style> + html { + user-select: none; + } + textarea { + width: 100%; + height: 20px; + position: fixed; + bottom: 20px; + user-select: text; + } + </style> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +<textarea name="name" rows="1" cols="20" inputmode="none">text</textarea> +</body> +<script> +SimpleTest.waitForExplicitFinish(); + +SpecialPowers.pushPrefEnv({ + set: [ + ["layout.accessiblecaret.enabled", true], + ["layout.accessiblecaret.enabled_on_touch", true], + ], +}, async () => { + await SpecialPowers.spawnChrome([], () => { + browsingContext.touchEventsOverride = "enabled"; + }); + + const utils = SpecialPowers.DOMWindowUtils; + const target = document.querySelector("textarea"); + + const selectionchangePromise = new Promise(resolve => { + target.addEventListener("selectionchange", () => resolve()); + }); + ok(!utils.isApzDisabledForElement(target), + "APZ is not disabled on the textarea"); + + // Tap on the text area. + synthesizeTouch(target, 10, 10, { type: "touchstart" }); + synthesizeTouch(target, 10, 10, { type: "touchend" }); + + await selectionchangePromise; + + ok(utils.isApzDisabledForElement(target), + "Now APZ is disabled on the textarea"); + + const blurPromise = new Promise(resolve => { + target.addEventListener("blur", () => resolve()); + }); + target.blur(); + + await blurPromise; + + ok(!utils.isApzDisabledForElement(target), + "Now APZ is re-enabled on the textarea"); + + SimpleTest.finish(); +}); +</script> +</html>