Commit 9677e35e authored by WangHui's avatar WangHui Committed by Chromium LUCI CQ

find-in-page: Update the match rects with the size of mainframe.

Match rects in subframe should be recomputed when the size of parent
frame is changed since Find-in-page coordinates are represented as
normalized fractions of the main frame document

Bug:1147796

Change-Id: Iee446b54060b9977f0ed6db8b49c6bf63d1938c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2531797
Commit-Queue: HuiWang <wanghui210@huawei.com>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844346}
parent 73d3f0e3
......@@ -25,6 +25,10 @@
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/page/widget.mojom-test-utils.h"
#if defined(OS_ANDROID)
#include "ui/android/view_android.h"
#endif
namespace content {
namespace {
......@@ -725,6 +729,84 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, EmptyActiveMatchRect) {
EXPECT_EQ(gfx::RectF(), delegate()->active_match_rect());
}
class MainFrameSizeChangedWaiter : public WebContentsObserver {
public:
MainFrameSizeChangedWaiter(WebContents* web_contents)
: WebContentsObserver(web_contents) {}
void Wait() { run_loop_.Run(); }
private:
void FrameSizeChanged(RenderFrameHost* render_frame_host,
const gfx::Size& frame_size) override {
if (render_frame_host == web_contents()->GetMainFrame())
run_loop_.Quit();
}
base::RunLoop run_loop_;
};
// Tests match rects in the iframe are updated with the size of the main frame,
// and the active match rect should be in it.
IN_PROC_BROWSER_TEST_F(FindRequestManagerTest,
RectsUpdateWhenMainFrameSizeChanged) {
LoadAndWait("/find_in_page.html");
// Make a initial size for native view.
const int kWidth = 1080;
const int kHeight = 1286;
gfx::Size size(kWidth, kHeight);
contents()->GetNativeView()->OnSizeChanged(kWidth, kHeight);
contents()->GetNativeView()->OnPhysicalBackingSizeChanged(size);
// Make a FindRequest for "result".
auto options = blink::mojom::FindOptions::New();
options->run_synchronously_for_testing = true;
Find("result", options->Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
EXPECT_EQ(19, results.number_of_matches);
contents()->RequestFindMatchRects(-1);
delegate()->WaitForMatchRects();
// Change the size of native view.
const int kNewHeight = 2121;
size = gfx::Size(kWidth, kNewHeight);
contents()->GetNativeView()->OnSizeChanged(kWidth, kNewHeight);
contents()->GetNativeView()->OnPhysicalBackingSizeChanged(size);
// Wait for the size of the mainframe to change, and then the position
// of match rects should change as expected.
MainFrameSizeChangedWaiter(contents()).Wait();
contents()->RequestFindMatchRects(-1);
delegate()->WaitForMatchRects();
std::vector<gfx::RectF> new_rects = delegate()->find_match_rects();
// The first match should be active.
EXPECT_EQ(new_rects[0], delegate()->active_match_rect());
// Check that all active rects (including iframe) matches with corresponding
// match rect.
for (int i = 1; i < 19; i++) {
options->new_session = false;
options->forward = true;
Find("result", options->Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
EXPECT_EQ(19, results.number_of_matches);
// Request the find match rects.
contents()->RequestFindMatchRects(-1);
delegate()->WaitForMatchRects();
new_rects = delegate()->find_match_rects();
// The active rect should be equal to the corresponding match rect.
EXPECT_EQ(new_rects[i], delegate()->active_match_rect());
}
}
// TODO(wjmaclean): This test, if re-enabled, may require work to make it
// OOPIF-compatible.
// Tests requesting find match rects.
......
......@@ -601,6 +601,21 @@ void TextFinder::ClearFindMatchesCache() {
find_match_rects_are_valid_ = false;
}
void TextFinder::InvalidateFindMatchRects() {
// Increase version number is required to trigger FindMatchRects update when
// next find.
if (!find_matches_cache_.IsEmpty())
++find_match_markers_version_;
// For subframes, we need to recalculate the FindMatchRects when the
// document size of mainframe changed even if the document size of current
// frame has not changed because Find-in-page coordinates are represented as
// normalized fractions of the main frame document. So we need to force the
// FindMatchRects to be updated instead of changing according to the current
// document size.
find_match_rects_are_valid_ = false;
}
void TextFinder::UpdateFindMatchRects() {
IntSize current_document_size = OwnerFrame().DocumentSize();
if (document_size_for_current_find_match_rects_ != current_document_size) {
......@@ -941,4 +956,25 @@ void TextFinder::Scroll(std::unique_ptr<AsyncScrollContext> context) {
}
}
void TextFinder::IncreaseMarkerVersion() {
++find_match_markers_version_;
// This is called when the size of the content changes. Normally, the check
// for the document size changed at the beginning of UpdateFindMatchRects()
// would be responsible for invalidating the cached matches as well.
// However, a subframe might not change size but its match rects may still be
// affected because Find-in-page coordinates are represented as normalized
// fractions of the main frame document, so invalidate the cached matches of
// subframes as well.
for (Frame* frame = GetFrame()->Tree().TraverseNext(GetFrame()); frame;
frame = frame->Tree().TraverseNext(GetFrame())) {
auto* web_local_frame_impl =
WebLocalFrameImpl::FromFrame(To<LocalFrame>(frame));
if (web_local_frame_impl->GetTextFinder() &&
web_local_frame_impl->GetTextFinder()->TotalMatchCount() > 0) {
web_local_frame_impl->GetTextFinder()->InvalidateFindMatchRects();
}
}
}
} // namespace blink
......@@ -105,7 +105,7 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
bool FrameScoping() const { return frame_scoping_; }
int TotalMatchCount() const { return total_match_count_; }
bool ScopingInProgress() const { return scoping_in_progress_; }
void IncreaseMarkerVersion() { ++find_match_markers_version_; }
void IncreaseMarkerVersion();
// Finishes the current scoping effort and triggers any updates if
// appropriate.
......@@ -181,6 +181,11 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
// calculated again next time updateFindMatchRects is called.
void ClearFindMatchesCache();
// Forcing rects to be fully recomputed again next time UpdateFindMatchRects
// is called. This is different from ClearFindMatchesCache which will clear
// the matches cache.
void InvalidateFindMatchRects();
// Select a find-in-page match marker in the current frame using a cache
// match index returned by nearestFindMatch. Returns the ordinal of the new
// selected match or -1 in case of error. Also provides the bounding box of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment