Enhance tabbing support to include links and highlights
This CL adds ability to tab across links and highlights (along with already supported widgets) behind a newly added feature flag kTabAcrossPDFAnnotations. This is done by calling the newly added PDFium API FPDFAnnot_SetFocusableSubtypes(). A unit test has also been added to validate the added support. Here is the related CL: https://pdfium-review.googlesource.com/c/pdfium/+/60011/ Bug: 994500 Change-Id: I00312c00f3e6373949a4723cc65778fdb32ab963 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1783695 Reviewed-by: Ian Prest <iapres@microsoft.com> Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Neha Gupta <negupta@microsoft.com> Cr-Commit-Position: refs/heads/master@{#759380}
This commit is contained in:
@ -32,5 +32,8 @@ const base::Feature kSaveEditedPDFForm = {"SaveEditedPDFForm",
|
||||
#endif // defined(OS_CHROMEOS)
|
||||
};
|
||||
|
||||
const base::Feature kTabAcrossPDFAnnotations = {
|
||||
"TabAcrossPDFAnnotations", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
|
||||
} // namespace features
|
||||
} // namespace chrome_pdf
|
||||
|
@ -18,6 +18,7 @@ extern const base::Feature kAccessiblePDFHighlight;
|
||||
extern const base::Feature kPDFAnnotations;
|
||||
extern const base::Feature kPDFTwoUpView;
|
||||
extern const base::Feature kSaveEditedPDFForm;
|
||||
extern const base::Feature kTabAcrossPDFAnnotations;
|
||||
|
||||
} // namespace features
|
||||
} // namespace chrome_pdf
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "pdf/document_loader_impl.h"
|
||||
#include "pdf/draw_utils/coordinates.h"
|
||||
#include "pdf/draw_utils/shadow.h"
|
||||
#include "pdf/pdf_features.h"
|
||||
#include "pdf/pdf_transform.h"
|
||||
#include "pdf/pdfium/pdfium_api_string_buffer_adapter.h"
|
||||
#include "pdf/pdfium/pdfium_document.h"
|
||||
@ -2709,6 +2711,14 @@ void PDFiumEngine::LoadForm() {
|
||||
FPDF_SetFormFieldHighlightColor(form(), FPDF_FORMFIELD_UNKNOWN,
|
||||
kFormHighlightColor);
|
||||
FPDF_SetFormFieldHighlightAlpha(form(), kFormHighlightAlpha);
|
||||
|
||||
if (base::FeatureList::IsEnabled(features::kTabAcrossPDFAnnotations)) {
|
||||
static constexpr FPDF_ANNOTATION_SUBTYPE kFocusableAnnotSubtypes[] = {
|
||||
FPDF_ANNOT_LINK, FPDF_ANNOT_HIGHLIGHT, FPDF_ANNOT_WIDGET};
|
||||
FPDF_BOOL ret = FPDFAnnot_SetFocusableSubtypes(
|
||||
form(), kFocusableAnnotSubtypes, base::size(kFocusableAnnotSubtypes));
|
||||
DCHECK(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,11 @@
|
||||
|
||||
#include "pdf/pdfium/pdfium_engine.h"
|
||||
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "pdf/document_layout.h"
|
||||
#include "pdf/document_metadata.h"
|
||||
#include "pdf/pdf_features.h"
|
||||
#include "pdf/pdfium/pdfium_page.h"
|
||||
#include "pdf/pdfium/pdfium_test_base.h"
|
||||
#include "pdf/test/test_client.h"
|
||||
@ -258,6 +260,62 @@ class PDFiumEngineTabbingTest : public PDFiumTestBase {
|
||||
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
|
||||
};
|
||||
|
||||
TEST_F(PDFiumEngineTabbingTest, TabbingSupportedAnnots) {
|
||||
/*
|
||||
* Document structure
|
||||
* Document
|
||||
* ++ Page 1
|
||||
* ++++ Widget annotation
|
||||
* ++++ Widget annotation
|
||||
* ++++ Highlight annotation
|
||||
* ++++ Link annotation
|
||||
*/
|
||||
|
||||
// Enable feature flag.
|
||||
base::test::ScopedFeatureList scoped_feature_list;
|
||||
scoped_feature_list.InitAndEnableFeature(
|
||||
chrome_pdf::features::kTabAcrossPDFAnnotations);
|
||||
|
||||
TestClient client;
|
||||
std::unique_ptr<PDFiumEngine> engine =
|
||||
InitializeEngine(&client, FILE_PATH_LITERAL("annots.pdf"));
|
||||
ASSERT_TRUE(engine);
|
||||
|
||||
ASSERT_EQ(1, engine->GetNumberOfPages());
|
||||
|
||||
ASSERT_EQ(PDFiumEngine::FocusElementType::kNone,
|
||||
GetFocusedElementType(engine.get()));
|
||||
EXPECT_EQ(-1, GetLastFocusedPage(engine.get()));
|
||||
|
||||
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
|
||||
EXPECT_EQ(PDFiumEngine::FocusElementType::kDocument,
|
||||
GetFocusedElementType(engine.get()));
|
||||
|
||||
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
|
||||
EXPECT_EQ(PDFiumEngine::FocusElementType::kPage,
|
||||
GetFocusedElementType(engine.get()));
|
||||
EXPECT_EQ(0, GetLastFocusedPage(engine.get()));
|
||||
|
||||
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
|
||||
EXPECT_EQ(PDFiumEngine::FocusElementType::kPage,
|
||||
GetFocusedElementType(engine.get()));
|
||||
EXPECT_EQ(0, GetLastFocusedPage(engine.get()));
|
||||
|
||||
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
|
||||
EXPECT_EQ(PDFiumEngine::FocusElementType::kPage,
|
||||
GetFocusedElementType(engine.get()));
|
||||
EXPECT_EQ(0, GetLastFocusedPage(engine.get()));
|
||||
|
||||
ASSERT_TRUE(HandleTabEvent(engine.get(), 0));
|
||||
EXPECT_EQ(PDFiumEngine::FocusElementType::kPage,
|
||||
GetFocusedElementType(engine.get()));
|
||||
EXPECT_EQ(0, GetLastFocusedPage(engine.get()));
|
||||
|
||||
ASSERT_FALSE(HandleTabEvent(engine.get(), 0));
|
||||
EXPECT_EQ(PDFiumEngine::FocusElementType::kNone,
|
||||
GetFocusedElementType(engine.get()));
|
||||
}
|
||||
|
||||
TEST_F(PDFiumEngineTabbingTest, TabbingForwardTest) {
|
||||
/*
|
||||
* Document structure
|
||||
|
80
pdf/test/data/annots.in
Normal file
80
pdf/test/data/annots.in
Normal file
@ -0,0 +1,80 @@
|
||||
{{header}}
|
||||
{{object 1 0}} <<
|
||||
/Type /Catalog
|
||||
/Pages 2 0 R
|
||||
/AcroForm [5 0 R 6 0 R]
|
||||
>>
|
||||
endobj
|
||||
{{object 2 0}} <<
|
||||
/Type /Pages
|
||||
/Count 1
|
||||
/Kids [3 0 R]
|
||||
>>
|
||||
endobj
|
||||
{{object 3 0}} <<
|
||||
/Type /Page
|
||||
/Parent 2 0 R
|
||||
/Annots [5 0 R 6 0 R 7 0 R 8 0 R]
|
||||
/Contents 4 0 R
|
||||
/Tabs /R
|
||||
>>
|
||||
endobj
|
||||
{{object 4 0}} <<
|
||||
{{streamlen}}
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
70 340 Td
|
||||
14 Tf
|
||||
(External Link ) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
{{object 5 0}} <<
|
||||
/Type /Annot
|
||||
/Subtype /Widget
|
||||
/FT /Tx
|
||||
/Parent 3 0 R
|
||||
/T (TextField)
|
||||
/Rect [69 670 220 690]
|
||||
>>
|
||||
endobj
|
||||
{{object 6 0}} <<
|
||||
/Type /Annot
|
||||
/Subtype /Widget
|
||||
/FT /Btn
|
||||
/Rect [69 360 220 380]
|
||||
/A <<
|
||||
/URI (https://www.google.com)
|
||||
/S /URI
|
||||
>>
|
||||
/F 4
|
||||
/T (button)
|
||||
/Ff 65536
|
||||
>>
|
||||
endobj
|
||||
{{object 7 0}} <<
|
||||
/Type /Annot
|
||||
/Subtype /Link
|
||||
/Rect [69 338 180 358]
|
||||
/A <<
|
||||
/Type /Action
|
||||
/S /URI
|
||||
/URI (https://www.google.com/)
|
||||
>>
|
||||
/F 4
|
||||
>>
|
||||
endobj
|
||||
{{object 8 0}} <<
|
||||
/Type /Annot
|
||||
/Subtype /Highlight
|
||||
/F 4
|
||||
/QuadPoints [120 358 150 358 120 338 150 338]
|
||||
/C [1 0.90196 0]
|
||||
/Rect [120 338 150 358]
|
||||
>>
|
||||
endobj
|
||||
{{xref}}
|
||||
{{trailer}}
|
||||
{{startxref}}
|
||||
%%EOF
|
95
pdf/test/data/annots.pdf
Normal file
95
pdf/test/data/annots.pdf
Normal file
@ -0,0 +1,95 @@
|
||||
%PDF-1.7
|
||||
%<25><><EFBFBD><EFBFBD>
|
||||
1 0 obj <<
|
||||
/Type /Catalog
|
||||
/Pages 2 0 R
|
||||
/AcroForm [5 0 R 6 0 R]
|
||||
>>
|
||||
endobj
|
||||
2 0 obj <<
|
||||
/Type /Pages
|
||||
/Count 1
|
||||
/Kids [3 0 R]
|
||||
>>
|
||||
endobj
|
||||
3 0 obj <<
|
||||
/Type /Page
|
||||
/Parent 2 0 R
|
||||
/Annots [5 0 R 6 0 R 7 0 R 8 0 R]
|
||||
/Contents 4 0 R
|
||||
/Tabs /R
|
||||
>>
|
||||
endobj
|
||||
4 0 obj <<
|
||||
/Length 42
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
70 340 Td
|
||||
14 Tf
|
||||
(External Link ) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
5 0 obj <<
|
||||
/Type /Annot
|
||||
/Subtype /Widget
|
||||
/FT /Tx
|
||||
/Parent 3 0 R
|
||||
/T (TextField)
|
||||
/Rect [69 670 220 690]
|
||||
>>
|
||||
endobj
|
||||
6 0 obj <<
|
||||
/Type /Annot
|
||||
/Subtype /Widget
|
||||
/FT /Btn
|
||||
/Rect [69 360 220 380]
|
||||
/A <<
|
||||
/URI (https://www.google.com)
|
||||
/S /URI
|
||||
>>
|
||||
/F 4
|
||||
/T (button)
|
||||
/Ff 65536
|
||||
>>
|
||||
endobj
|
||||
7 0 obj <<
|
||||
/Type /Annot
|
||||
/Subtype /Link
|
||||
/Rect [69 338 180 358]
|
||||
/A <<
|
||||
/Type /Action
|
||||
/S /URI
|
||||
/URI (https://www.google.com/)
|
||||
>>
|
||||
/F 4
|
||||
>>
|
||||
endobj
|
||||
8 0 obj <<
|
||||
/Type /Annot
|
||||
/Subtype /Highlight
|
||||
/F 4
|
||||
/QuadPoints [120 358 150 358 120 338 150 338]
|
||||
/C [1 0.90196 0]
|
||||
/Rect [120 338 150 358]
|
||||
>>
|
||||
endobj
|
||||
xref
|
||||
0 9
|
||||
0000000000 65535 f
|
||||
0000000015 00000 n
|
||||
0000000094 00000 n
|
||||
0000000157 00000 n
|
||||
0000000273 00000 n
|
||||
0000000366 00000 n
|
||||
0000000489 00000 n
|
||||
0000000672 00000 n
|
||||
0000000835 00000 n
|
||||
trailer <<
|
||||
/Root 1 0 R
|
||||
/Size 9
|
||||
>>
|
||||
startxref
|
||||
993
|
||||
%%EOF
|
Reference in New Issue
Block a user