0

Deactivate touch selection when active client is invalidated.

Hide touch selection handles and menu after if the active client managed
by TouchSelectionControllerClientAura is invalidated. This is to prevent
stray handles and menu staying around after the active client is
destroyed (e.g. after reloading a web page where the active client
corresponds to an iframe).

Bug: b:312312220
Change-Id: I49c828d5d97d3e7347440a4a8643c82933158934
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5055932
Reviewed-by: Robert Flack <flackr@chromium.org>
Commit-Queue: Michelle Chen <michellegc@google.com>
Cr-Commit-Position: refs/heads/main@{#1229117}
This commit is contained in:
Michelle
2023-11-27 00:12:36 +00:00
committed by Chromium LUCI CQ
parent 85a3a323d7
commit 60f62ef86f
2 changed files with 61 additions and 0 deletions

@ -243,6 +243,7 @@ void TouchSelectionControllerClientAura::InvalidateClient(
ui::TouchSelectionControllerClient* client) {
DCHECK(client != &internal_client_);
if (client == active_client_) {
GetTouchSelectionController()->HideAndDisallowShowingAutomatically();
active_client_ = &internal_client_;
active_menu_client_ = this;
}

@ -994,6 +994,66 @@ IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
initial_selection_bounds_in_child_coords);
}
IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
TouchSelectionDeactivatedAfterReload) {
const GURL main_url(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(a)"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
WaitForHitTestData(root->current_frame_host());
InitSelectionController(true);
{
// Load touch selection test page into iframe.
const GURL child_url(
embedded_test_server()->GetURL("b.com", "/touch_selection.html"));
EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), child_url));
FrameTreeNode* child = root->child_at(0);
WaitForHitTestData(child->current_frame_host());
// Find the location of some text in the iframe to select.
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
gfx::PointF point_in_text;
JSONToPoint(EvalJs(child->current_frame_host(), "get_top_left_of_text()")
.ExtractString(),
&point_in_text);
point_in_text.Offset(2.0 * kCharacterWidth, 0.5f * kCharacterHeight);
point_in_text = child_view->TransformPointToRootCoordSpaceF(point_in_text);
// Long press some text in the iframe to show selection handles.
selection_controller_client()->InitWaitForSelectionEvent(
ui::SELECTION_HANDLES_SHOWN);
SelectWithLongTap(gfx::Point(point_in_text.x(), point_in_text.y()),
child_view);
selection_controller_client()->Wait();
}
// Touch selection handles and menu should be active.
EXPECT_EQ(
ui::TouchSelectionController::SELECTION_ACTIVE,
GetRenderWidgetHostViewAura()->selection_controller()->active_status());
EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
{
// Reload web contents.
TestNavigationObserver reload_observer(shell()->web_contents());
shell()->web_contents()->GetController().Reload(
content::ReloadType::NORMAL, false /* check_for_repost */);
reload_observer.Wait();
}
// Touch selection handles and menu should be deactivated.
EXPECT_EQ(
ui::TouchSelectionController::INACTIVE,
GetRenderWidgetHostViewAura()->selection_controller()->active_status());
EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
// Tests that tapping in a textfield brings up the insertion handle, but not the
// quick menu, initially. Then, successive taps on the insertion handle toggle
// the quick menu visibility.