Commit 64281514 authored by Ankit Kumar's avatar Ankit Kumar Committed by Commit Bot

Ensure current focused annotation is in view on key events

This CL ensures that current focused annotation is scrolled into view
if not already in view on key events. This ensures that user can see the
annotation in the viewport while performing key events on the same.

Bug: 1085614
Change-Id: I41162be9a096219e04682ec5240508819a5baf48
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2228250
Commit-Queue: Ankit Kumar 🌪️ <ankk@microsoft.com>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarKevin Babbitt <kbabbitt@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#776902}
parent f354340d
......@@ -1554,6 +1554,17 @@ bool PDFiumEngine::OnKeyDown(const pp::KeyboardInputEvent& event) {
OnChar(synthesized);
}
#if !defined(OS_MACOSX)
// macOS doesn't have keyboard-triggered context menus.
// Scroll focused annotation into view when context menu is invoked through
// keyboard <Shift-F10>.
if (event.GetKeyCode() == FWL_VKEY_F10 &&
(event.GetModifiers() & PP_INPUTEVENT_MODIFIER_SHIFTKEY)) {
DCHECK(!rv);
ScrollFocusedAnnotationIntoView();
}
#endif
return rv;
}
......@@ -1574,8 +1585,17 @@ bool PDFiumEngine::OnChar(const pp::KeyboardInputEvent& event) {
return false;
base::string16 str = base::UTF8ToUTF16(event.GetCharacterText().AsString());
return !!FORM_OnChar(form(), pages_[last_focused_page_]->GetPage(), str[0],
event.GetModifiers());
bool rv = !!FORM_OnChar(form(), pages_[last_focused_page_]->GetPage(), str[0],
event.GetModifiers());
// Scroll editable form text into view on char events. We should not scroll
// focused annotation on escape char event since escape char is used to
// dismiss focus from form controls.
if (rv && editable_form_text_area_ && event.GetKeyCode() != ui::VKEY_ESCAPE) {
ScrollFocusedAnnotationIntoView();
}
return rv;
}
void PDFiumEngine::StartFind(const std::string& text, bool case_sensitive) {
......@@ -3670,6 +3690,16 @@ void PDFiumEngine::SetSelection(
}
}
void PDFiumEngine::ScrollFocusedAnnotationIntoView() {
FPDF_ANNOTATION annot;
int page_index;
if (!FORM_GetFocusedAnnot(form(), &page_index, &annot))
return;
ScrollAnnotationIntoView(annot, page_index);
FPDFPage_CloseAnnot(annot);
}
void PDFiumEngine::ScrollAnnotationIntoView(FPDF_ANNOTATION annot,
int page_index) {
if (!PageIndexInBounds(page_index))
......
......@@ -583,6 +583,9 @@ class PDFiumEngine : public PDFEngine,
void SetSelection(const PP_PdfPageCharacterIndex& selection_start_index,
const PP_PdfPageCharacterIndex& selection_end_index);
// Scroll the current focused annotation into view if not already in view.
void ScrollFocusedAnnotationIntoView();
// Given |annot|, scroll the |annot| into view if not already in view.
void ScrollAnnotationIntoView(FPDF_ANNOTATION annot, int page_index);
......
......@@ -329,6 +329,10 @@ class PDFiumEngineTabbingTest : public PDFiumTestBase {
return engine->link_under_cursor_;
}
void ScrollFocusedAnnotationIntoView(PDFiumEngine* engine) {
engine->ScrollFocusedAnnotationIntoView();
}
protected:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
......@@ -868,4 +872,51 @@ TEST_F(PDFiumEngineTabbingTest, MaintainViewportWhenFocusIsUpdated) {
EXPECT_EQ(0, GetLastFocusedPage(engine.get()));
}
TEST_F(PDFiumEngineTabbingTest, ScrollFocusedAnnotationIntoView) {
StrictMock<ScrollingTestClient> client;
std::unique_ptr<PDFiumEngine> engine = InitializeEngine(
&client, FILE_PATH_LITERAL("annotation_form_fields.pdf"));
ASSERT_TRUE(engine);
ASSERT_EQ(2, engine->GetNumberOfPages());
engine->PluginSizeUpdated(pp::Size(60, 40));
{
InSequence sequence;
static constexpr PP_Point kScrollValues[] = {{510, 478}, {510, 478}};
for (const auto& scroll_value : kScrollValues) {
EXPECT_CALL(client, ScrollToY(scroll_value.y, false))
.WillOnce(Invoke([&engine, &scroll_value]() {
engine->ScrolledToYPosition(scroll_value.y);
}));
EXPECT_CALL(client, ScrollToX(scroll_value.x))
.WillOnce(Invoke([&engine, &scroll_value]() {
engine->ScrolledToXPosition(scroll_value.x);
}));
}
}
EXPECT_EQ(PDFiumEngine::FocusElementType::kNone,
GetFocusedElementType(engine.get()));
EXPECT_EQ(-1, GetLastFocusedPage(engine.get()));
// Tabbing to bring the document into focus.
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
EXPECT_EQ(PDFiumEngine::FocusElementType::kDocument,
GetFocusedElementType(engine.get()));
// Tab to an annotation.
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
EXPECT_EQ(PDFiumEngine::FocusElementType::kPage,
GetFocusedElementType(engine.get()));
// Scroll focused annotation out of viewport.
static constexpr PP_Point kScrollPosition = {242, 746};
engine->ScrolledToXPosition(kScrollPosition.x);
engine->ScrolledToYPosition(kScrollPosition.y);
// Scroll the focused annotation into view.
ScrollFocusedAnnotationIntoView(engine.get());
}
} // namespace chrome_pdf
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