Skip to content

Commit

Permalink
Use WindowOpenDispositions to open internal links in PDF Viewer.
Browse files Browse the repository at this point in the history
When clicking on a link in a PDF to another page/position in the same
document, open in a new window (if shift was pressed) or a new tab
(if ctrl was pressed or if the click was on the middle button).

Use PDF open params to do so, specifying page and y position.

Bug: 720180
Change-Id: I535b707d592056a020033cbbd00a689f3de8e821
Reviewed-on: https://chromium-review.googlesource.com/1112479
Commit-Queue: Henrique Nakashima <[email protected]>
Reviewed-by: Lei Zhang <[email protected]>
Cr-Commit-Position: refs/heads/master@{#570108}
  • Loading branch information
Henrique Nakashima authored and Commit Bot committed Jun 25, 2018
1 parent ce3de2d commit d0cada9
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 15 deletions.
108 changes: 108 additions & 0 deletions chrome/browser/pdf/pdf_extension_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,114 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionLinkClickTest, OpenPDFWithReplaceState) {
EXPECT_EQ("http://www.example.com/", url.spec());
}

class PDFExtensionInternalLinkClickTest : public PDFExtensionTest {
public:
PDFExtensionInternalLinkClickTest() : guest_contents_(nullptr) {}
~PDFExtensionInternalLinkClickTest() override {}

protected:
void LoadTestLinkPdfGetGuestContents() {
GURL test_pdf_url(
embedded_test_server()->GetURL("/pdf/test-internal-link.pdf"));
guest_contents_ = LoadPdfGetGuestContents(test_pdf_url);
ASSERT_TRUE(guest_contents_);
}

gfx::Point GetLinkPosition() {
// The whole first page is a link.
gfx::Point link_position(100, 100);
ConvertPageCoordToScreenCoord(guest_contents_, &link_position);
return link_position;
}

private:
WebContents* guest_contents_;
};

IN_PROC_BROWSER_TEST_F(PDFExtensionInternalLinkClickTest, CtrlLeft) {
LoadTestLinkPdfGetGuestContents();

WebContents* web_contents = GetActiveWebContents();

content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_TAB_ADDED,
content::NotificationService::AllSources());
content::SimulateMouseClickAt(web_contents, kDefaultKeyModifier,
blink::WebMouseEvent::Button::kLeft,
GetLinkPosition());
observer.Wait();

int tab_count = browser()->tab_strip_model()->count();
ASSERT_EQ(2, tab_count);

WebContents* active_web_contents = GetActiveWebContents();
ASSERT_EQ(web_contents, active_web_contents);

WebContents* new_web_contents =
browser()->tab_strip_model()->GetWebContentsAt(1);
ASSERT_TRUE(new_web_contents);
ASSERT_NE(web_contents, new_web_contents);

const GURL& url = new_web_contents->GetURL();
EXPECT_EQ("/pdf/test-internal-link.pdf", url.path());
EXPECT_EQ("page=2&zoom=100,0,200", url.ref());
}

IN_PROC_BROWSER_TEST_F(PDFExtensionInternalLinkClickTest, Middle) {
LoadTestLinkPdfGetGuestContents();

WebContents* web_contents = GetActiveWebContents();

content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_TAB_ADDED,
content::NotificationService::AllSources());
content::SimulateMouseClickAt(web_contents, 0,
blink::WebMouseEvent::Button::kMiddle,
GetLinkPosition());
observer.Wait();

int tab_count = browser()->tab_strip_model()->count();
ASSERT_EQ(2, tab_count);

WebContents* active_web_contents = GetActiveWebContents();
ASSERT_EQ(web_contents, active_web_contents);

WebContents* new_web_contents =
browser()->tab_strip_model()->GetWebContentsAt(1);
ASSERT_TRUE(new_web_contents);
ASSERT_NE(web_contents, new_web_contents);

const GURL& url = new_web_contents->GetURL();
EXPECT_EQ("/pdf/test-internal-link.pdf", url.path());
EXPECT_EQ("page=2&zoom=100,0,200", url.ref());
}

IN_PROC_BROWSER_TEST_F(PDFExtensionInternalLinkClickTest, ShiftLeft) {
LoadTestLinkPdfGetGuestContents();

ASSERT_EQ(1U, chrome::GetTotalBrowserCount());

WebContents* web_contents = GetActiveWebContents();

content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_BROWSER_OPENED,
content::NotificationService::AllSources());
content::SimulateMouseClickAt(web_contents, blink::WebInputEvent::kShiftKey,
blink::WebMouseEvent::Button::kLeft,
GetLinkPosition());
observer.Wait();

ASSERT_EQ(2U, chrome::GetTotalBrowserCount());

WebContents* active_web_contents =
chrome::FindLastActive()->tab_strip_model()->GetActiveWebContents();
ASSERT_NE(web_contents, active_web_contents);

const GURL& url = active_web_contents->GetURL();
EXPECT_EQ("/pdf/test-internal-link.pdf", url.path());
EXPECT_EQ("page=2&zoom=100,0,200", url.ref());
}

class PDFExtensionClipboardTest : public PDFExtensionTest {
public:
PDFExtensionClipboardTest() : guest_contents_(nullptr) {}
Expand Down
Binary file added chrome/test/data/pdf/test-internal-link.pdf
Binary file not shown.
44 changes: 29 additions & 15 deletions pdf/pdfium/pdfium_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
Expand Down Expand Up @@ -1508,18 +1509,18 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {

// Open link on mouse up for same link for which mouse down happened earlier.
if (mouse_down_state_.Matches(area, target)) {
if (area == PDFiumPage::WEBLINK_AREA) {
uint32_t modifiers = event.GetModifiers();
bool middle_button =
!!(modifiers & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN);
bool alt_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_ALTKEY);
bool ctrl_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_CONTROLKEY);
bool meta_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_METAKEY);
bool shift_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_SHIFTKEY);
uint32_t modifiers = event.GetModifiers();
bool middle_button =
!!(modifiers & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN);
bool alt_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_ALTKEY);
bool ctrl_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_CONTROLKEY);
bool meta_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_METAKEY);
bool shift_key = !!(modifiers & PP_INPUTEVENT_MODIFIER_SHIFTKEY);

WindowOpenDisposition disposition = ui::DispositionFromClick(
middle_button, alt_key, ctrl_key, meta_key, shift_key);
WindowOpenDisposition disposition = ui::DispositionFromClick(
middle_button, alt_key, ctrl_key, meta_key, shift_key);

if (area == PDFiumPage::WEBLINK_AREA) {
client_->NavigateTo(target.url, disposition);
SetInFormTextArea(false);
return true;
Expand All @@ -1528,12 +1529,25 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
if (!PageIndexInBounds(target.page))
return true;

pp::Rect page_rect(GetPageScreenRect(target.page));
int y = position_.y() + page_rect.y();
if (target.y_in_pixels)
y += target.y_in_pixels.value() * current_zoom_;
client_->ScrollToY(y, /*compensate_for_toolbar=*/true);
if (disposition == WindowOpenDisposition::CURRENT_TAB) {
pp::Rect page_rect(GetPageScreenRect(target.page));
int y = position_.y() + page_rect.y();
if (target.y_in_pixels)
y += target.y_in_pixels.value() * current_zoom_;

client_->ScrollToY(y, /*compensate_for_toolbar=*/true);
} else {
std::string parameters =
base::StringPrintf("#page=%d", target.page + 1);
if (target.y_in_pixels) {
parameters += base::StringPrintf(
"&zoom=100,0,%d", static_cast<int>(target.y_in_pixels.value()));
}

client_->NavigateTo(parameters, disposition);
}
SetInFormTextArea(false);

return true;
}
}
Expand Down

0 comments on commit d0cada9

Please sign in to comment.