summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/page/scrolling
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/page/scrolling')
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h1
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc314
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h60
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc87
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h27
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc6
14 files changed, 621 insertions, 135 deletions
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc
index a59dcfae2cb..bd4499fa183 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc
@@ -231,34 +231,20 @@ TEST_F(ElementFragmentAnchorTest, AnchorRemovedBeforeBeginFrameCrash) {
"text/css");
LoadURL("https://example.com/test.html#anchor");
- if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
- main_resource.Complete(R"HTML(
+ main_resource.Complete(R"HTML(
<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="sheet.css">
<div style="height: 1000px;"></div>
<input id="anchor">Bottom of the page</input>
)HTML");
- // We're still waiting on the stylesheet to load so the load event shouldn't
- // yet dispatch and parsing is deferred. This will install the anchor.
- ASSERT_FALSE(GetDocument().IsLoadCompleted());
- ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
- ASSERT_TRUE(static_cast<ElementFragmentAnchor*>(
- GetDocument().View()->GetFragmentAnchor())
- ->anchor_node_);
- } else {
- main_resource.Complete(R"HTML(
- <!DOCTYPE html>
- <div style="height: 1000px;"></div>
- <input id="anchor">Bottom of the page</input>
- <link rel="stylesheet" type="text/css" href="sheet.css">
- )HTML");
-
- // We're still waiting on the stylesheet to load so the load event shouldn't
- // yet dispatch and parsing is deferred. This will install the anchor.
- ASSERT_FALSE(GetDocument().IsLoadCompleted());
- ASSERT_FALSE(GetDocument().View()->GetFragmentAnchor());
- }
+ // We're still waiting on the stylesheet to load so the load event shouldn't
+ // yet dispatch and parsing is deferred. This will install the anchor.
+ ASSERT_FALSE(GetDocument().IsLoadCompleted());
+ ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
+ ASSERT_TRUE(static_cast<ElementFragmentAnchor*>(
+ GetDocument().View()->GetFragmentAnchor())
+ ->anchor_node_);
// Remove the fragment anchor from the DOM and perform GC.
GetDocument().getElementById("anchor")->remove();
@@ -271,18 +257,12 @@ TEST_F(ElementFragmentAnchorTest, AnchorRemovedBeforeBeginFrameCrash) {
css_resource.Complete("");
test::RunPendingTasks();
- if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
- // We should still have a fragment anchor but its node pointer should be
- // gone since it's a WeakMember.
- ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
- ASSERT_FALSE(static_cast<ElementFragmentAnchor*>(
- GetDocument().View()->GetFragmentAnchor())
- ->anchor_node_);
- } else {
- // The fragment shouldn't have installed since the targeted element was
- // removed.
- ASSERT_FALSE(GetDocument().View()->GetFragmentAnchor());
- }
+ // We should still have a fragment anchor but its node pointer should be
+ // gone since it's a WeakMember.
+ ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
+ ASSERT_FALSE(static_cast<ElementFragmentAnchor*>(
+ GetDocument().View()->GetFragmentAnchor())
+ ->anchor_node_);
// We'd normally focus the fragment during BeginFrame. Make sure we don't
// crash since it's been GC'd.
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
index 8d90be489a7..579103d4490 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -1338,7 +1338,7 @@ TEST_P(ScrollingTest, NonFastScrollableRegionsForPlugins) {
}
#fixed {
position: fixed;
- top: 500px;
+ left: 300px;
}
</style>
<div id="fixed">
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
index 62c621a9e41..f79143f1a5c 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
@@ -21,6 +21,17 @@ namespace {
// This is experimentally determined and corresponds to the UA decided
// parameter as mentioned in spec.
constexpr float kProximityRatio = 1.0 / 3.0;
+
+cc::SnapAlignment AdjustForRtlWritingMode(cc::SnapAlignment align) {
+ if (align == cc::SnapAlignment::kStart)
+ return cc::SnapAlignment::kEnd;
+
+ if (align == cc::SnapAlignment::kEnd)
+ return cc::SnapAlignment::kStart;
+
+ return align;
+}
+
} // namespace
// TODO(sunyunjia): Move the static functions to an anonymous namespace.
@@ -328,25 +339,54 @@ void SnapCoordinator::UpdateSnapContainerData(LayoutBox& snap_container) {
}
}
+// https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align
+// After normalization:
+// * inline corresponds to x, and block corresponds to y
+// * start corresponds to left or top
+// * end corresponds to right or bottom
+// In other words, the adjusted logical properties map to a physical layout
+// as if the writing mode were horizontal left to right and top to bottom.
static cc::ScrollSnapAlign GetPhysicalAlignment(
const ComputedStyle& area_style,
- const ComputedStyle& container_style) {
+ const ComputedStyle& container_style,
+ const PhysicalRect& area_rect,
+ const PhysicalRect& container_rect) {
cc::ScrollSnapAlign align = area_style.GetScrollSnapAlign();
- if (container_style.IsHorizontalWritingMode())
- return align;
-
- cc::SnapAlignment tmp = align.alignment_inline;
- align.alignment_inline = align.alignment_block;
- align.alignment_block = tmp;
-
- if (container_style.IsFlippedBlocksWritingMode()) {
- if (align.alignment_inline == cc::SnapAlignment::kStart) {
- align.alignment_inline = cc::SnapAlignment::kEnd;
- } else if (align.alignment_inline == cc::SnapAlignment::kEnd) {
- align.alignment_inline = cc::SnapAlignment::kStart;
- }
+ cc::ScrollSnapAlign adjusted_alignment;
+ // Start and end alignments are resolved with respect to the writing mode of
+ // the snap container unless the scroll snap area is larger than the snapport,
+ // in which case they are resolved with respect to the writing mode of the box
+ // itself. (This allows items in a container to have consistent snap alignment
+ // in general, while ensuring that start always aligns the item to allow
+ // reading its contents from the beginning.)
+ WritingDirectionMode writing_direction =
+ container_style.GetWritingDirection();
+ WritingDirectionMode area_writing_direction =
+ area_style.GetWritingDirection();
+ if (area_writing_direction.IsHorizontal()) {
+ if (area_rect.Width() > container_rect.Width())
+ writing_direction = area_writing_direction;
+ } else {
+ if (area_rect.Height() > container_rect.Height())
+ writing_direction = area_writing_direction;
}
- return align;
+
+ bool rtl = (writing_direction.IsRtl());
+ if (writing_direction.IsHorizontal()) {
+ adjusted_alignment.alignment_inline =
+ rtl ? AdjustForRtlWritingMode(align.alignment_inline)
+ : align.alignment_inline;
+ adjusted_alignment.alignment_block = align.alignment_block;
+ } else {
+ bool flipped = writing_direction.IsFlippedBlocks();
+ adjusted_alignment.alignment_inline =
+ flipped ? AdjustForRtlWritingMode(align.alignment_block)
+ : align.alignment_block;
+ adjusted_alignment.alignment_block =
+ rtl ? AdjustForRtlWritingMode(align.alignment_inline)
+ : align.alignment_inline;
+ }
+ return adjusted_alignment;
}
cc::SnapAreaData SnapCoordinator::CalculateSnapAreaData(
@@ -372,9 +412,10 @@ cc::SnapAreaData SnapCoordinator::CalculateSnapAreaData(
area_rect.Expand(area_margin);
snap_area_data.rect = FloatRect(area_rect);
- cc::ScrollSnapAlign align =
- GetPhysicalAlignment(*area_style, *container_style);
- snap_area_data.scroll_snap_align = align;
+ PhysicalRect container_rect = snap_container.PhysicalBorderBoxRect();
+
+ snap_area_data.scroll_snap_align = GetPhysicalAlignment(
+ *area_style, *container_style, area_rect, container_rect);
snap_area_data.must_snap =
(area_style->ScrollSnapStop() == EScrollSnapStop::kAlways);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
index bbf710d1038..e194eea0423 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h"
+#include "components/shared_highlighting/core/common/shared_highlighting_features.h"
+#include "components/shared_highlighting/core/common/text_fragments_utils.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -16,6 +18,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h"
@@ -243,10 +246,6 @@ bool TextFragmentAnchor::Invoke() {
frame_->GetDocument()->Markers().RemoveMarkersOfTypes(
DocumentMarker::MarkerTypes::TextFragment());
- // TODO(bokan): Once BlockHTMLParserOnStyleSheets is launched, there won't be
- // a way for the user to scroll before we invoke and scroll the anchor. We
- // should confirm if we can remove tracking this after that point or if we
- // need a replacement metric.
if (user_scrolled_ && !did_scroll_into_view_)
metrics_->ScrollCancelled();
@@ -290,7 +289,8 @@ void TextFragmentAnchor::DidScroll(mojom::blink::ScrollType type) {
return;
}
- Dismiss();
+ if (ShouldDismissOnScrollOrClick())
+ Dismiss();
user_scrolled_ = true;
if (did_non_zero_scroll_ &&
@@ -474,6 +474,16 @@ bool TextFragmentAnchor::Dismiss() {
dismissed_ = true;
metrics_->Dismissed();
+ KURL url(
+ shared_highlighting::RemoveTextFragments(frame_->GetDocument()->Url()));
+
+ // Replace the current history entry with the new url, so that the text
+ // fragment shown in the URL matches the state of the highlight on the page.
+ // This is equivalent to history.replaceState in javascript.
+ frame_->DomWindow()->document()->Loader()->RunURLAndHistoryUpdateSteps(
+ url, /*data=*/nullptr, WebFrameLoadType::kReplaceCurrentItem,
+ mojom::blink::ScrollRestorationType::kAuto);
+
return dismissed_;
}
@@ -514,4 +524,9 @@ bool TextFragmentAnchor::HasSearchEngineSource() {
return IsKnownSearchEngine(referrer);
}
+bool TextFragmentAnchor::ShouldDismissOnScrollOrClick() {
+ return !base::FeatureList::IsEnabled(
+ shared_highlighting::kSharedHighlightingV2);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
index 4ffc0281d75..755c7213430 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h
@@ -86,6 +86,8 @@ class CORE_EXPORT TextFragmentAnchor final : public FragmentAnchor,
void NoMatchFound() override {}
+ static bool ShouldDismissOnScrollOrClick();
+
private:
// Called when the search is finished. Reports metrics and activates the
// element fragment anchor if we didn't find a match.
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
index b6f8d7c6900..8ec12602976 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_ANCHOR_METRICS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_ANCHOR_METRICS_H_
+#include "base/time/tick_clock.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h"
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
index f1300e5bfb9..efb0a70eed0 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc
@@ -839,12 +839,6 @@ INSTANTIATE_TEST_SUITE_P(
// Test that the ScrollCancelled metric gets reported when a user scroll cancels
// the scroll into view.
TEST_P(TextFragmentAnchorScrollMetricsTest, ScrollCancelled) {
- // This test isn't relevant with this flag enabled. When it's enabled,
- // there's no way to block rendering and the fragment is installed and
- // invoked as soon as parsing finishes which means the user cannot scroll
- // before this point.
- ScopedBlockHTMLParserOnStyleSheetsForTest block_parser(false);
-
SimRequest request("https://example.com/test.html#:~:text=test", "text/html");
SimSubresourceRequest css_request("https://example.com/test.css", "text/css");
LoadURL("https://example.com/test.html#:~:text=test");
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
index a21b452b331..b3ddbadfcfb 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
@@ -2,11 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
+#include "components/shared_highlighting/core/common/shared_highlighting_features.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mouse_event_init.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
+#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -15,8 +20,11 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/page/context_menu_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_finder.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
@@ -922,37 +930,12 @@ TEST_P(TextFragmentAnchorScrollTest, ScrollCancelled) {
GetDocument().View()->UpdateAllLifecyclePhasesForTest();
mojom::blink::ScrollType scroll_type = GetParam();
- if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
- scroll_type);
- // Set the target text to visible and change its position to cause a layout
- // and invoke the fragment anchor in the next begin frame.
- css_request.Complete("p { visibility: visible; top: 1001px; }");
- img_request.Complete("");
- } else {
- // Set the target text to visible and change its position to cause a layout
- // and invoke the fragment anchor in the next begin frame.
- css_request.Complete("p { visibility: visible; top: 1001px; }");
- RunPendingTasks();
- Compositor().BeginFrame();
- Element& p = *GetDocument().getElementById("text");
-
- // We should have invoked the fragment and scrolled the <p> into view, but
- // load should not yet be complete due to the image.
- EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)));
- ASSERT_FALSE(GetDocument().IsLoadCompleted());
-
- // Before invoking again, perform a user scroll. This should abort future
- // scrolls during fragment invocation.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 0),
- scroll_type);
- ASSERT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
-
- img_request.Complete("");
- RunPendingTasks();
- ASSERT_TRUE(GetDocument().IsLoadCompleted());
- }
-
+ GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
+ scroll_type);
+ // Set the target text to visible and change its position to cause a layout
+ // and invoke the fragment anchor in the next begin frame.
+ css_request.Complete("p { visibility: visible; top: 1001px; }");
+ img_request.Complete("");
RunAsyncMatchingTasks();
// Render two frames to handle the async step added by the beforematch event.
@@ -983,6 +966,9 @@ TEST_P(TextFragmentAnchorScrollTest, ScrollCancelled) {
// Test that user scrolling dismisses the highlight.
TEST_P(TextFragmentAnchorScrollTest, DismissTextHighlightOnUserScroll) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndDisableFeature(
+ shared_highlighting::kSharedHighlightingV2);
SimRequest request(
"https://example.com/"
"test.html#:~:text=test%20page&text=more%20text",
@@ -1030,6 +1016,54 @@ TEST_P(TextFragmentAnchorScrollTest, DismissTextHighlightOnUserScroll) {
}
}
+// Test that user scrolling doesn't dismiss the highlight, when the
+// SharedHighlightingV2 flag is enabled.
+TEST_P(TextFragmentAnchorScrollTest, DontDismissTextHighlightOnUserScroll) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndEnableFeature(
+ shared_highlighting::kSharedHighlightingV2);
+ SimRequest request(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text",
+ "text/html");
+ LoadURL(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 2200px;
+ }
+ #first {
+ position: absolute;
+ top: 1000px;
+ }
+ #second {
+ position: absolute;
+ top: 2000px;
+ }
+ </style>
+ <p id="first">This is a test page</p>
+ <p id="second">With some more text</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ ASSERT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ mojom::blink::ScrollType scroll_type = GetParam();
+ LayoutViewport()->ScrollBy(ScrollOffset(0, -10), scroll_type);
+
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+ EXPECT_TRUE(GetDocument().View()->GetFragmentAnchor());
+}
+
// Ensure that the text fragment anchor has no effect in an iframe. This is
// disabled in iframes by design, for security reasons.
TEST_F(TextFragmentAnchorTest, DisabledInIframes) {
@@ -1482,6 +1516,9 @@ TEST_F(TextFragmentAnchorTest, CheckForWordBoundaryWithPartialWord) {
// Test dismissing the text highlight with a click
TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithClick) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndDisableFeature(
+ shared_highlighting::kSharedHighlightingV2);
SimRequest request(
"https://example.com/"
"test.html#:~:text=test%20page&text=more%20text",
@@ -1513,6 +1550,15 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithClick) {
Compositor().BeginFrame();
Compositor().BeginFrame();
+ KURL url = GetDocument()
+ .GetFrame()
+ ->Loader()
+ .GetDocumentLoader()
+ ->GetHistoryItem()
+ ->Url();
+ EXPECT_EQ(
+ "https://example.com/test.html#:~:text=test%20page&text=more%20text",
+ url.GetString());
EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
SimulateClick(100, 100);
@@ -1521,10 +1567,67 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithClick) {
// Ensure the fragment is uninstalled
EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor());
+ url = GetDocument()
+ .GetFrame()
+ ->Loader()
+ .GetDocumentLoader()
+ ->GetHistoryItem()
+ ->Url();
+ EXPECT_EQ("https://example.com/test.html", url.GetString());
+}
+
+// Test not dismissing the text highlight with a click, if the
+// SharedHighlightingV2 flag is enabled.
+TEST_F(TextFragmentAnchorTest, DontDismissTextHighlightWithClick) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndEnableFeature(
+ shared_highlighting::kSharedHighlightingV2);
+ SimRequest request(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text",
+ "text/html");
+ LoadURL(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 2200px;
+ }
+ #first {
+ position: absolute;
+ top: 1000px;
+ }
+ #second {
+ position: absolute;
+ top: 2000px;
+ }
+ </style>
+ <p id="first">This is a test page</p>
+ <p id="second">With some more text</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ SimulateClick(100, 100);
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ // Ensure the fragment is still installed
+ EXPECT_TRUE(GetDocument().View()->GetFragmentAnchor());
}
// Test dismissing the text highlight with a tap
TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithTap) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndDisableFeature(
+ shared_highlighting::kSharedHighlightingV2);
SimRequest request(
"https://example.com/"
"test.html#:~:text=test%20page&text=more%20text",
@@ -1556,6 +1659,15 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithTap) {
Compositor().BeginFrame();
Compositor().BeginFrame();
+ KURL url = GetDocument()
+ .GetFrame()
+ ->Loader()
+ .GetDocumentLoader()
+ ->GetHistoryItem()
+ ->Url();
+ EXPECT_EQ(
+ "https://example.com/test.html#:~:text=test%20page&text=more%20text",
+ url.GetString());
EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
SimulateTap(100, 100);
@@ -1564,10 +1676,67 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithTap) {
// Ensure the fragment is uninstalled
EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor());
+ url = GetDocument()
+ .GetFrame()
+ ->Loader()
+ .GetDocumentLoader()
+ ->GetHistoryItem()
+ ->Url();
+ EXPECT_EQ("https://example.com/test.html", url.GetString());
+}
+
+// Test not dismissing the text highlight with a tap, if the
+// SharedHighlightingV2 flag is enabled.
+TEST_F(TextFragmentAnchorTest, DontDismissTextHighlightWithTap) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndEnableFeature(
+ shared_highlighting::kSharedHighlightingV2);
+ SimRequest request(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text",
+ "text/html");
+ LoadURL(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 2200px;
+ }
+ #first {
+ position: absolute;
+ top: 1000px;
+ }
+ #second {
+ position: absolute;
+ top: 2000px;
+ }
+ </style>
+ <p id="first">This is a test page</p>
+ <p id="second">With some more text</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ SimulateTap(100, 100);
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ // Ensure the fragment is installed
+ EXPECT_TRUE(GetDocument().View()->GetFragmentAnchor());
}
// Test that we don't dismiss a text highlight before it's scrolled into view
TEST_F(TextFragmentAnchorTest, DismissTextHighlightOutOfView) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndDisableFeature(
+ shared_highlighting::kSharedHighlightingV2);
SimRequest request("https://example.com/test.html#:~:text=test", "text/html");
SimSubresourceRequest css_request("https://example.com/test.css", "text/css");
LoadURL("https://example.com/test.html#:~:text=test");
@@ -1609,6 +1778,9 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightOutOfView) {
// Test dismissing a text highlight that didn't require a scroll into view
TEST_F(TextFragmentAnchorTest, DismissTextHighlightInView) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndDisableFeature(
+ shared_highlighting::kSharedHighlightingV2);
SimRequest request(
"https://example.com/"
"test.html#:~:text=test%20page&text=more%20text",
@@ -2127,6 +2299,86 @@ TEST_F(TextFragmentAnchorTest, IsInSameUninterruptedBlock_BlockInterruption) {
EXPECT_FALSE(TextFragmentFinder::IsInSameUninterruptedBlock(start, end));
}
+TEST_F(TextFragmentAnchorTest, OpenedFromHighlightDoesNotSelectAdditionalText) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndEnableFeature(
+ shared_highlighting::kSharedHighlightingV2);
+ SimRequest request("https://www.test.com/#:~:text=First%20test,page%20three",
+ "text/html");
+ LoadURL("https://www.test.com/#:~:text=First%20test,page%20three");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ p {
+ font-size: 12px;
+ }
+ </style>
+ <p id="one">First test page one</p>
+ <p id="two">Second test page two</p>
+ <p id="three">Third test page three</p>
+ <p id="four">Fourth test page four</p>
+ </html>)HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ Element* middle_element = GetDocument().getElementById("two");
+ Element* last_element = GetDocument().getElementById("four");
+
+ WebView().GetSettings()->SetEditingBehavior(
+ mojom::EditingBehavior::kEditingMacBehavior);
+
+ // Create a mouse event in the middle of <p> two.
+ WebMouseEvent mouse_down_event(WebInputEvent::Type::kMouseDown,
+ WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests());
+ const DOMRect* middle_rect = middle_element->getBoundingClientRect();
+ gfx::PointF middle_elem_point(((middle_rect->left() + 1)),
+ ((middle_rect->top() + 1)));
+ mouse_down_event.SetPositionInWidget(middle_elem_point.x(),
+ middle_elem_point.y());
+ mouse_down_event.SetPositionInScreen(middle_elem_point.x(),
+ middle_elem_point.y());
+ mouse_down_event.click_count = 1;
+ mouse_down_event.button = WebMouseEvent::Button::kRight;
+
+ // Corresponding release event (Windows shows context menu on release).
+ WebMouseEvent mouse_up_event(mouse_down_event);
+ mouse_up_event.SetType(WebInputEvent::Type::kMouseUp);
+
+ WebView().MainFrameViewWidget()->HandleInputEvent(
+ WebCoalescedInputEvent(mouse_down_event, ui::LatencyInfo()));
+ WebView().MainFrameViewWidget()->HandleInputEvent(
+ WebCoalescedInputEvent(mouse_up_event, ui::LatencyInfo()));
+
+ // No additional text should be selected.
+ FrameSelection& selection = GetDocument().GetFrame()->Selection();
+ EXPECT_TRUE(selection.SelectedText().IsEmpty());
+
+ // Create a mouse event at the center of <p> four.
+ const DOMRect* last_rect = last_element->getBoundingClientRect();
+ gfx::PointF last_elem_point(((last_rect->left() + 1)),
+ ((last_rect->top() + 1)));
+ mouse_down_event.SetPositionInWidget(last_elem_point.x(),
+ last_elem_point.y());
+ mouse_down_event.SetPositionInScreen(last_elem_point.x(),
+ last_elem_point.y());
+
+ // Corresponding release event (Windows shows context menu on release).
+ WebMouseEvent last_mouse_up_event(mouse_down_event);
+ last_mouse_up_event.SetType(WebInputEvent::Type::kMouseUp);
+
+ WebView().MainFrameViewWidget()->HandleInputEvent(
+ WebCoalescedInputEvent(mouse_down_event, ui::LatencyInfo()));
+ WebView().MainFrameViewWidget()->HandleInputEvent(
+ WebCoalescedInputEvent(last_mouse_up_event, ui::LatencyInfo()));
+
+ // The text underneath the cursor should be selected.
+ EXPECT_FALSE(selection.SelectedText().IsEmpty());
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc
new file mode 100644
index 00000000000..af6bea11989
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.cc
@@ -0,0 +1,69 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h"
+
+#include "components/shared_highlighting/core/common/shared_highlighting_features.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/renderer/core/editing/markers/document_marker.h"
+#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
+#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+
+namespace blink {
+
+TextFragmentHandler::TextFragmentHandler(LocalFrame* main_frame)
+ : text_fragment_selector_generator_(
+ MakeGarbageCollected<TextFragmentSelectorGenerator>(main_frame)) {}
+
+void TextFragmentHandler::BindTextFragmentReceiver(
+ mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> producer) {
+ selector_producer_.reset();
+ selector_producer_.Bind(
+ std::move(producer),
+ text_fragment_selector_generator_->GetFrame()->GetTaskRunner(
+ blink::TaskType::kInternalDefault));
+}
+
+TextFragmentSelectorGenerator*
+TextFragmentHandler::GetTextFragmentSelectorGenerator() {
+ return text_fragment_selector_generator_;
+}
+
+void TextFragmentHandler::Cancel() {
+ GetTextFragmentSelectorGenerator()->Cancel();
+}
+
+void TextFragmentHandler::RequestSelector(RequestSelectorCallback callback) {
+ GetTextFragmentSelectorGenerator()->RequestSelector(std::move(callback));
+}
+
+void TextFragmentHandler::RemoveFragments() {
+ DCHECK(
+ base::FeatureList::IsEnabled(shared_highlighting::kSharedHighlightingV2));
+
+ GetTextFragmentSelectorGenerator()
+ ->GetFrame()
+ ->View()
+ ->DismissFragmentAnchor();
+}
+
+// static
+bool TextFragmentHandler::IsOverTextFragment(HitTestResult result) {
+ DocumentMarkerController& marker_controller =
+ result.InnerNodeFrame()->GetDocument()->Markers();
+ PositionWithAffinity pos_with_affinity = result.GetPosition();
+ const Position marker_position = pos_with_affinity.GetPosition();
+ auto markers = marker_controller.MarkersAroundPosition(
+ ToPositionInFlatTree(marker_position),
+ DocumentMarker::MarkerTypes::TextFragment());
+ return !markers.IsEmpty();
+}
+
+void TextFragmentHandler::Trace(Visitor* visitor) const {
+ visitor->Trace(text_fragment_selector_generator_);
+ visitor->Trace(selector_producer_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h
new file mode 100644
index 00000000000..c3933da3136
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h
@@ -0,0 +1,60 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_HANDLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_HANDLER_H_
+
+#include "third_party/blink/public/mojom/link_to_text/link_to_text.mojom-blink.h"
+#include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
+
+namespace blink {
+
+class LocalFrame;
+
+// TextFragmentHandler is responsible for handling text fragment operations
+// on a LocalFrame. Generating text fragment selectors for a selection is
+// delegated to TextFragmentSelectorGenerator.
+class CORE_EXPORT TextFragmentHandler final
+ : public GarbageCollected<TextFragmentHandler>,
+ public blink::mojom::blink::TextFragmentReceiver {
+ public:
+ explicit TextFragmentHandler(LocalFrame* main_frame);
+
+ void BindTextFragmentReceiver(
+ mojo::PendingReceiver<mojom::blink::TextFragmentReceiver> producer);
+
+ // Cancel any pending selector requests.
+ void Cancel() override;
+
+ // Requests selector for current selection.
+ void RequestSelector(RequestSelectorCallback callback) override;
+
+ // Remove all text fragments from the current frame.
+ void RemoveFragments() override;
+
+ // Determine if |result| represents a click on an existing highlight.
+ static bool IsOverTextFragment(HitTestResult result);
+
+ void Trace(Visitor*) const;
+
+ TextFragmentSelectorGenerator* GetTextFragmentSelectorGenerator();
+
+ private:
+ // Class responsible for generating text fragment selectors for the current
+ // selection.
+ Member<TextFragmentSelectorGenerator> text_fragment_selector_generator_;
+
+ // Used for communication between |TextFragmentHandler| in renderer
+ // and |TextFragmentSelectorClientImpl| in browser.
+ HeapMojoReceiver<blink::mojom::blink::TextFragmentReceiver,
+ TextFragmentHandler>
+ selector_producer_{this, nullptr};
+
+ DISALLOW_COPY_AND_ASSIGN(TextFragmentHandler);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_TEXT_FRAGMENT_HANDLER_H_
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc
new file mode 100644
index 00000000000..e85446d2d5f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_handler_test.cc
@@ -0,0 +1,87 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h"
+
+#include <gtest/gtest.h>
+
+#include "base/test/scoped_feature_list.h"
+#include "components/shared_highlighting/core/common/shared_highlighting_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+using test::RunPendingTasks;
+
+class TextFragmentHandlerTest : public SimTest {
+ public:
+ void SetUp() override {
+ SimTest::SetUp();
+ WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
+ }
+
+ void RunAsyncMatchingTasks() {
+ auto* scheduler =
+ ThreadScheduler::Current()->GetWebMainThreadSchedulerForTest();
+ blink::scheduler::RunIdleTasksForTesting(scheduler,
+ base::BindOnce([]() {}));
+ RunPendingTasks();
+ }
+};
+
+TEST_F(TextFragmentHandlerTest, RemoveTextFragments) {
+ base::test::ScopedFeatureList feature_list_;
+ feature_list_.InitAndEnableFeature(
+ shared_highlighting::kSharedHighlightingV2);
+ SimRequest request(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text",
+ "text/html");
+ LoadURL(
+ "https://example.com/"
+ "test.html#:~:text=test%20page&text=more%20text");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 2200px;
+ }
+ #first {
+ position: absolute;
+ top: 1000px;
+ }
+ #second {
+ position: absolute;
+ top: 2000px;
+ }
+ </style>
+ <p id="first">This is a test page</p>
+ <p id="second">With some more text</p>
+ )HTML");
+ RunAsyncMatchingTasks();
+
+ // Render two frames to handle the async step added by the beforematch event.
+ Compositor().BeginFrame();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+
+ GetDocument().GetFrame()->GetTextFragmentHandler()->RemoveFragments();
+
+ EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
+
+ // Ensure the fragment is uninstalled
+ EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor());
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
index f61ac5e7f75..da327c933f3 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h"
#include "base/metrics/histogram_macros.h"
+#include "base/strings/strcat.h"
#include "base/time/default_tick_clock.h"
#include "components/shared_highlighting/core/common/shared_highlighting_features.h"
#include "components/shared_highlighting/core/common/shared_highlighting_metrics.h"
@@ -181,15 +182,15 @@ constexpr int kMaxRangeWords = 10;
constexpr int kMaxIterationCountToRecord = 10;
constexpr int kMinWordCount_ = 3;
-void TextFragmentSelectorGenerator::UpdateSelection(
- LocalFrame* selection_frame,
- const EphemeralRangeInFlatTree& selection_range) {
- DCHECK(selection_frame);
-
+TextFragmentSelectorGenerator::TextFragmentSelectorGenerator(
+ LocalFrame* main_frame)
+ : selection_frame_(main_frame) {
// Scroll-to-text doesn't support iframes.
- DCHECK(selection_frame->IsMainFrame());
+ DCHECK(main_frame->IsMainFrame());
+}
- selection_frame_ = selection_frame;
+void TextFragmentSelectorGenerator::UpdateSelection(
+ const EphemeralRangeInFlatTree& selection_range) {
selection_range_ = MakeGarbageCollected<Range>(
selection_range.GetDocument(),
ToPositionInDOMTree(selection_range.StartPosition()),
@@ -201,17 +202,6 @@ void TextFragmentSelectorGenerator::UpdateSelection(
}
}
-void TextFragmentSelectorGenerator::BindTextFragmentSelectorProducer(
- mojo::PendingReceiver<mojom::blink::TextFragmentSelectorProducer>
- producer) {
- DCHECK(selection_frame_);
-
- selector_producer_.reset();
- selector_producer_.Bind(
- std::move(producer),
- selection_frame_->GetTaskRunner(blink::TaskType::kInternalDefault));
-}
-
void TextFragmentSelectorGenerator::AdjustSelection() {
if (!selection_range_)
return;
@@ -436,14 +426,16 @@ void TextFragmentSelectorGenerator::ClearSelection() {
if (selection_range_) {
selection_range_->Dispose();
selection_range_ = nullptr;
- selection_frame_ = nullptr;
}
}
+void TextFragmentSelectorGenerator::Detach() {
+ selection_frame_ = nullptr;
+}
+
void TextFragmentSelectorGenerator::Trace(Visitor* visitor) const {
visitor->Trace(selection_frame_);
visitor->Trace(selection_range_);
- visitor->Trace(selector_producer_);
visitor->Trace(finder_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h
index bd6be400528..25ef77500ce 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator.h
@@ -15,6 +15,8 @@
namespace blink {
+using RequestSelectorCallback = base::OnceCallback<void(const WTF::String&)>;
+
class LocalFrame;
// TextFragmentSelectorGenerator is responsible for generating text fragment
@@ -30,18 +32,12 @@ class LocalFrame;
// match is uniquely identified or no new context/range can be added.
class CORE_EXPORT TextFragmentSelectorGenerator final
: public GarbageCollected<TextFragmentSelectorGenerator>,
- public TextFragmentFinder::Client,
- public blink::mojom::blink::TextFragmentSelectorProducer {
+ public TextFragmentFinder::Client {
public:
- explicit TextFragmentSelectorGenerator() = default;
-
- void BindTextFragmentSelectorProducer(
- mojo::PendingReceiver<mojom::blink::TextFragmentSelectorProducer>
- producer);
+ explicit TextFragmentSelectorGenerator(LocalFrame* main_frame);
// Sets the frame and range of the current selection.
- void UpdateSelection(LocalFrame* selection_frame,
- const EphemeralRangeInFlatTree& selection_range);
+ void UpdateSelection(const EphemeralRangeInFlatTree& selection_range);
// Adjust the selection start/end to a valid position. That includes skipping
// non text start/end nodes and extending selection from start and end to
@@ -49,10 +45,10 @@ class CORE_EXPORT TextFragmentSelectorGenerator final
void AdjustSelection();
// blink::mojom::blink::TextFragmentSelectorProducer interface
- void Cancel() override;
+ void Cancel();
// Requests selector for current selection.
- void RequestSelector(RequestSelectorCallback callback) override;
+ void RequestSelector(RequestSelectorCallback callback);
// TextFragmentFinder::Client interface
void DidFindMatch(const EphemeralRangeInFlatTree& match,
@@ -75,8 +71,12 @@ class CORE_EXPORT TextFragmentSelectorGenerator final
// Releases members if necessary.
void ClearSelection();
+ void Detach();
+
void Trace(Visitor*) const;
+ LocalFrame* GetFrame() { return selection_frame_; }
+
private:
// Used for determining the next step of selector generation.
enum GenerationStep { kExact, kRange, kContext };
@@ -136,11 +136,6 @@ class CORE_EXPORT TextFragmentSelectorGenerator final
Member<Range> selection_range_;
std::unique_ptr<TextFragmentSelector> selector_;
- // Used for communication between |TextFragmentSelectorGenerator| in renderer
- // and |TextFragmentSelectorClientImpl| in browser.
- HeapMojoReceiver<blink::mojom::blink::TextFragmentSelectorProducer,
- TextFragmentSelectorGenerator>
- selector_producer_{this, nullptr};
RequestSelectorCallback pending_generate_selector_callback_;
GenerationStep step_ = kExact;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
index 473285eb21c..9060ddd81ce 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_generator_test.cc
@@ -98,9 +98,8 @@ class TextFragmentSelectorGeneratorTest
GetDocument()
.GetFrame()
->GetTextFragmentSelectorGenerator()
- ->UpdateSelection(GetDocument().GetFrame(),
- ToEphemeralRangeInFlatTree(
- EphemeralRange(selected_start, selected_end)));
+ ->UpdateSelection(ToEphemeralRangeInFlatTree(
+ EphemeralRange(selected_start, selected_end)));
bool callback_called = false;
String selector;
@@ -1270,7 +1269,6 @@ TEST_P(TextFragmentSelectorGeneratorTest, SecondGenerationCrash) {
// This shouldn't crash.
GetDocument().GetFrame()->GetTextFragmentSelectorGenerator()->UpdateSelection(
- GetDocument().GetFrame(),
ToEphemeralRangeInFlatTree(EphemeralRange(start, end)));
base::RunLoop().RunUntilIdle();
}