0

[unseasoned-viewer] Implement PdfViewWebPlugin::LinkAtPosition()

Similar to the Pepper implementation, return the link under the cursor,
which is updated upon PdfViewWebPlugin::HandleInputEvent(). Ignore the
position param of the method.

Meanwhile, bubble the `link_under_cursor_` state from PDFiumEngine up
to PdfViewPluginBase, since the state is more pertinent to the PDFEngine
client.

Bug: 1191817
Change-Id: I96671a7be79b0e03c6fa485f83b62bf1f9cfbc59
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2976675
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Daniel Hosseinian <dhoss@chromium.org>
Cr-Commit-Position: refs/heads/master@{#894530}
This commit is contained in:
Daniel Hosseinian
2021-06-22 04:03:47 +00:00
committed by Chromium LUCI CQ
parent 6c67ccf3e6
commit 8b508ab904
9 changed files with 54 additions and 38 deletions

@ -976,11 +976,6 @@ void OutOfProcessInstance::SetSelectedText(const std::string& selected_text) {
pp::PDF::SetSelectedText(this, selected_text.c_str());
}
void OutOfProcessInstance::SetLinkUnderCursor(
const std::string& link_under_cursor) {
pp::PDF::SetLinkUnderCursor(this, link_under_cursor.c_str());
}
bool OutOfProcessInstance::IsValidLink(const std::string& url) {
return pp::Var(url).is_string();
}
@ -1024,6 +1019,10 @@ void OutOfProcessInstance::SetContentRestrictions(int content_restrictions) {
pp::PDF::SetContentRestriction(this, content_restrictions);
}
void OutOfProcessInstance::NotifyLinkUnderCursor() {
pp::PDF::SetLinkUnderCursor(this, link_under_cursor().c_str());
}
void OutOfProcessInstance::NotifySelectionChanged(const gfx::PointF& left,
int left_height,
const gfx::PointF& right,

@ -105,7 +105,6 @@ class OutOfProcessInstance : public PdfViewPluginBase,
bool case_sensitive) override;
pp::Instance* GetPluginInstance() override;
void SetSelectedText(const std::string& selected_text) override;
void SetLinkUnderCursor(const std::string& link_under_cursor) override;
bool IsValidLink(const std::string& url) override;
std::unique_ptr<Graphics> CreatePaintGraphics(const gfx::Size& size) override;
bool BindPaintGraphics(Graphics& graphics) override;
@ -140,6 +139,7 @@ class OutOfProcessInstance : public PdfViewPluginBase,
void PluginDidStartLoading() override;
void PluginDidStopLoading() override;
void InvokePrintDialog() override;
void NotifyLinkUnderCursor() override;
void NotifySelectionChanged(const gfx::PointF& left,
int left_height,
const gfx::PointF& right,

@ -464,6 +464,15 @@ void PdfViewPluginBase::DocumentFocusChanged(bool document_has_focus) {
SendMessage(std::move(message));
}
void PdfViewPluginBase::SetLinkUnderCursor(
const std::string& link_under_cursor) {
if (link_under_cursor_ == link_under_cursor)
return;
link_under_cursor_ = link_under_cursor;
NotifyLinkUnderCursor();
}
// TODO(crbug.com/1191817): Add tests for input events. Unit testing should be
// feasible now that the Pepper dependency is removed for input events.
bool PdfViewPluginBase::HandleInputEvent(const blink::WebInputEvent& event) {

@ -107,6 +107,7 @@ class PdfViewPluginBase : public PDFEngine::Client,
void SelectionChanged(const gfx::Rect& left, const gfx::Rect& right) override;
void EnteredEditMode() override;
void DocumentFocusChanged(bool document_has_focus) override;
void SetLinkUnderCursor(const std::string& link_under_cursor) override;
// PaintManager::Client:
void OnPaint(const std::vector<gfx::Rect>& paint_rects,
@ -314,6 +315,11 @@ class PdfViewPluginBase : public PDFEngine::Client,
// document.
virtual void InvokePrintDialog() = 0;
// Notifies the embedder about a new link under the cursor.
// TODO(crbug.com/702993): This is only needed by `OutOfProcessInstance`.
// Remove this method when that class ceases to exist.
virtual void NotifyLinkUnderCursor() {}
// Notifies the embedder of the top-left and bottom-right coordinates of the
// current selection.
virtual void NotifySelectionChanged(const gfx::PointF& left,
@ -335,6 +341,8 @@ class PdfViewPluginBase : public PDFEngine::Client,
cursor_type_ = cursor_type;
}
const std::string& link_under_cursor() const { return link_under_cursor_; }
bool full_frame() const { return full_frame_; }
void set_full_frame(bool full_frame) { full_frame_ = full_frame; }
@ -489,6 +497,9 @@ class PdfViewPluginBase : public PDFEngine::Client,
// The current cursor type.
ui::mojom::CursorType cursor_type_ = ui::mojom::CursorType::kPointer;
// The URL currently under the cursor.
std::string link_under_cursor_;
// True if the plugin occupies the entire frame (not embedded).
bool full_frame_ = false;

@ -71,6 +71,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/range/range.h"
#include "ui/gfx/skia_util.h"
#include "url/gurl.h"
#include "v8/include/v8.h"
namespace chrome_pdf {
@ -454,6 +455,11 @@ bool PdfViewWebPlugin::ExecuteEditCommand(const blink::WebString& name,
return false;
}
blink::WebURL PdfViewWebPlugin::LinkAtPosition(
const gfx::Point& /*position*/) const {
return GURL(link_under_cursor());
}
bool PdfViewWebPlugin::StartFind(const blink::WebString& search_text,
bool case_sensitive,
int /*identifier*/) {
@ -532,11 +538,6 @@ void PdfViewWebPlugin::SetSelectedText(const std::string& selected_text) {
selected_text_, /*offset=*/0, gfx::Range(0, selected_text_.length()));
}
void PdfViewWebPlugin::SetLinkUnderCursor(
const std::string& link_under_cursor) {
NOTIMPLEMENTED();
}
bool PdfViewWebPlugin::IsValidLink(const std::string& url) {
return base::Value(url).is_string();
}

@ -152,6 +152,7 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
bool CanRedo() const override;
bool ExecuteEditCommand(const blink::WebString& name,
const blink::WebString& value) override;
blink::WebURL LinkAtPosition(const gfx::Point& /*position*/) const override;
bool StartFind(const blink::WebString& search_text,
bool case_sensitive,
int /*identifier*/) override;
@ -176,7 +177,6 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
bool case_sensitive) override;
pp::Instance* GetPluginInstance() override;
void SetSelectedText(const std::string& selected_text) override;
void SetLinkUnderCursor(const std::string& link_under_cursor) override;
bool IsValidLink(const std::string& url) override;
std::unique_ptr<Graphics> CreatePaintGraphics(const gfx::Size& size) override;
bool BindPaintGraphics(Graphics& graphics) override;

@ -4206,11 +4206,7 @@ void PDFiumEngine::UpdatePageCount() {
#endif // defined(PDF_ENABLE_XFA)
void PDFiumEngine::UpdateLinkUnderCursor(const std::string& target_url) {
if (link_under_cursor_ == target_url)
return;
link_under_cursor_ = target_url;
client_->SetLinkUnderCursor(link_under_cursor_);
client_->SetLinkUnderCursor(target_url);
}
void PDFiumEngine::SetLinkUnderCursorForAnnotation(FPDF_ANNOTATION annot,

@ -776,9 +776,6 @@ class PDFiumEngine : public PDFEngine,
// Whether to render PDF annotations.
bool render_annots_ = true;
// The link currently under the cursor.
std::string link_under_cursor_;
// Pending progressive paints.
class ProgressivePaint {
public:

@ -541,6 +541,7 @@ class TabbingTestClient : public TestClient {
// Mock PDFEngine::Client methods.
MOCK_METHOD(void, DocumentFocusChanged, (bool), (override));
MOCK_METHOD(void, SetLinkUnderCursor, (const std::string&), (override));
};
class PDFiumEngineTabbingTest : public PDFiumTestBase {
@ -579,10 +580,6 @@ class PDFiumEngineTabbingTest : public PDFiumTestBase {
return engine->selection_.size();
}
const std::string& GetLinkUnderCursor(PDFiumEngine* engine) {
return engine->link_under_cursor_;
}
void ScrollFocusedAnnotationIntoView(PDFiumEngine* engine) {
engine->ScrollFocusedAnnotationIntoView();
}
@ -603,28 +600,34 @@ TEST_F(PDFiumEngineTabbingTest, LinkUnderCursorTest) {
scoped_feature_list.InitAndEnableFeature(
chrome_pdf::features::kTabAcrossPDFAnnotations);
TestClient client;
TabbingTestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("annots.pdf"));
ASSERT_TRUE(engine);
// Initial value of link under cursor.
EXPECT_EQ("", GetLinkUnderCursor(engine.get()));
// Tab to right before the first non-link annotation.
EXPECT_CALL(client, DocumentFocusChanged(true));
ASSERT_TRUE(HandleTabEvent(engine.get(), /*modifiers=*/0));
// Tab through non-link annotations and validate link under cursor.
for (int i = 0; i < 4; i++) {
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
EXPECT_EQ("", GetLinkUnderCursor(engine.get()));
{
InSequence sequence;
EXPECT_CALL(client, SetLinkUnderCursor(""));
EXPECT_CALL(client, DocumentFocusChanged(false));
EXPECT_CALL(client, SetLinkUnderCursor("")).Times(2);
}
for (int i = 0; i < 3; i++)
ASSERT_TRUE(HandleTabEvent(engine.get(), /*modifiers=*/0));
// Tab to Link annotation.
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
EXPECT_EQ("https://www.google.com/", GetLinkUnderCursor(engine.get()));
EXPECT_CALL(client, SetLinkUnderCursor("https://www.google.com/"));
ASSERT_TRUE(HandleTabEvent(engine.get(), /*modifiers=*/0));
// Tab to previous annotation.
EXPECT_CALL(client, SetLinkUnderCursor(""));
ASSERT_TRUE(
HandleTabEvent(engine.get(), blink::WebInputEvent::Modifiers::kShiftKey));
EXPECT_EQ("", GetLinkUnderCursor(engine.get()));
}
TEST_F(PDFiumEngineTabbingTest, TabbingSupportedAnnots) {
@ -693,7 +696,7 @@ TEST_F(PDFiumEngineTabbingTest, TabbingForwardTest) {
* ++ Page 2
* ++++ Annotation
*/
TabbingTestClient client;
NiceMock<TabbingTestClient> client;
std::unique_ptr<PDFiumEngine> engine = InitializeEngine(
&client, FILE_PATH_LITERAL("annotation_form_fields.pdf"));
ASSERT_TRUE(engine);
@ -745,7 +748,7 @@ TEST_F(PDFiumEngineTabbingTest, TabbingBackwardTest) {
* ++ Page 2
* ++++ Annotation
*/
TabbingTestClient client;
NiceMock<TabbingTestClient> client;
std::unique_ptr<PDFiumEngine> engine = InitializeEngine(
&client, FILE_PATH_LITERAL("annotation_form_fields.pdf"));
ASSERT_TRUE(engine);
@ -852,7 +855,7 @@ TEST_F(PDFiumEngineTabbingTest, NoFocusableItemTabbingTest) {
* ++ Page 1
* ++ Page 2
*/
TabbingTestClient client;
NiceMock<TabbingTestClient> client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world2.pdf"));
ASSERT_TRUE(engine);
@ -901,7 +904,7 @@ TEST_F(PDFiumEngineTabbingTest, RestoringDocumentFocusTest) {
* ++ Page 2
* ++++ Annotation
*/
TabbingTestClient client;
NiceMock<TabbingTestClient> client;
std::unique_ptr<PDFiumEngine> engine = InitializeEngine(
&client, FILE_PATH_LITERAL("annotation_form_fields.pdf"));
ASSERT_TRUE(engine);
@ -946,7 +949,7 @@ TEST_F(PDFiumEngineTabbingTest, RestoringAnnotFocusTest) {
* ++ Page 2
* ++++ Annotation
*/
TabbingTestClient client;
NiceMock<TabbingTestClient> client;
std::unique_ptr<PDFiumEngine> engine = InitializeEngine(
&client, FILE_PATH_LITERAL("annotation_form_fields.pdf"));
ASSERT_TRUE(engine);