summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortonikitoo <tonikitoo@igalia.com>2016-08-18 20:10:17 -0700
committerCommit bot <commit-bot@chromium.org>2016-08-18 20:10:17 -0700
commit618cb1f3e561b5d2a1dea9ec4653804f0da7267c (patch)
treea17067c25b751d6dfba46ab38114bd23a10ca2ff
parent7996fe888cb98597cd1608af05fb59f45c837fc6 (diff)
downloadpdfium-618cb1f3e561b5d2a1dea9ec4653804f0da7267c.tar.xz
Add initial Document::getAnnot supportchromium/2833
CL implements the first step in order to support Annotations manipulation in PDFium: Document::getAnnot. The method takes two arguments, an integer (page number) and a string (annotation name). When called, it iterates over the annotations on the given page number, searching for the one whose name matches the string in the second parameter. If found, then an Annot instance (see Annot.cpp/g added by this CL), is bound to a Javascript object and returned. With the use cases described in bug [1] as an initial test case, CL adds support to the following Annotation object properties: - hidden - name - type Idea is to keep evolving the implementation with more methods and properties in follow up CLs. [1] https://bugs.chromium.org/p/pdfium/issues/detail?id=492 BUG=pdfium:492 Review-Url: https://codereview.chromium.org/2260663002
-rw-r--r--BUILD.gn2
-rw-r--r--fpdfsdk/javascript/Annot.cpp89
-rw-r--r--fpdfsdk/javascript/Annot.h39
-rw-r--r--fpdfsdk/javascript/Document.cpp46
-rw-r--r--fpdfsdk/javascript/cjs_runtime.cpp4
-rw-r--r--pdfium.gyp2
-rw-r--r--testing/resources/javascript/document_methods.in14
-rw-r--r--testing/resources/javascript/document_methods_expected.txt7
8 files changed, 198 insertions, 5 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 1e87014594..ec2d55aec4 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -879,6 +879,8 @@ static_library("javascript") {
]
if (pdf_enable_v8) {
sources += [
+ "fpdfsdk/javascript/Annot.cpp",
+ "fpdfsdk/javascript/Annot.h",
"fpdfsdk/javascript/Consts.cpp",
"fpdfsdk/javascript/Consts.h",
"fpdfsdk/javascript/Document.cpp",
diff --git a/fpdfsdk/javascript/Annot.cpp b/fpdfsdk/javascript/Annot.cpp
new file mode 100644
index 0000000000..df123274d5
--- /dev/null
+++ b/fpdfsdk/javascript/Annot.cpp
@@ -0,0 +1,89 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/javascript/Annot.h"
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+
+BEGIN_JS_STATIC_CONST(CJS_Annot)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Annot)
+JS_STATIC_PROP_ENTRY(hidden)
+JS_STATIC_PROP_ENTRY(name)
+JS_STATIC_PROP_ENTRY(type)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Annot)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Annot, Annot)
+
+Annot::Annot(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
+
+Annot::~Annot() {}
+
+FX_BOOL Annot::hidden(IJS_Context* cc,
+ CJS_PropValue& vp,
+ CFX_WideString& sError) {
+ if (vp.IsGetting()) {
+ CPDF_Annot* pPDFAnnot = m_BAAnnot->GetPDFAnnot();
+ vp << CPDF_Annot::IsAnnotationHidden(pPDFAnnot->GetAnnotDict());
+ return TRUE;
+ }
+
+ bool bHidden;
+ vp >> bHidden;
+
+ uint32_t flags = m_BAAnnot->GetFlags();
+ if (bHidden) {
+ flags |= ANNOTFLAG_HIDDEN;
+ flags |= ANNOTFLAG_INVISIBLE;
+ flags |= ANNOTFLAG_NOVIEW;
+ flags &= ~ANNOTFLAG_PRINT;
+ } else {
+ flags &= ~ANNOTFLAG_HIDDEN;
+ flags &= ~ANNOTFLAG_INVISIBLE;
+ flags &= ~ANNOTFLAG_NOVIEW;
+ flags |= ANNOTFLAG_PRINT;
+ }
+ m_BAAnnot->SetFlags(flags);
+ return TRUE;
+}
+
+FX_BOOL Annot::name(IJS_Context* cc,
+ CJS_PropValue& vp,
+ CFX_WideString& sError) {
+ if (vp.IsGetting()) {
+ vp << m_BAAnnot->GetAnnotName();
+ return TRUE;
+ }
+
+ CFX_WideString annotName;
+ vp >> annotName;
+ m_BAAnnot->SetAnnotName(annotName);
+ return TRUE;
+}
+
+FX_BOOL Annot::type(IJS_Context* cc,
+ CJS_PropValue& vp,
+ CFX_WideString& sError) {
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
+ return FALSE;
+ }
+
+ vp << m_BAAnnot->GetType();
+ return TRUE;
+}
+
+void Annot::SetSDKAnnot(CPDFSDK_BAAnnot* annot) {
+ m_BAAnnot = annot;
+}
diff --git a/fpdfsdk/javascript/Annot.h b/fpdfsdk/javascript/Annot.h
new file mode 100644
index 0000000000..b3ea292aed
--- /dev/null
+++ b/fpdfsdk/javascript/Annot.h
@@ -0,0 +1,39 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_JAVASCRIPT_ANNOT_H_
+#define FPDFSDK_JAVASCRIPT_ANNOT_H_
+
+#include "fpdfsdk/include/cpdfsdk_baannot.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class Annot : public CJS_EmbedObj {
+ public:
+ explicit Annot(CJS_Object* pJSObject);
+ ~Annot() override;
+
+ FX_BOOL hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+ FX_BOOL name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+ FX_BOOL type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+ void SetSDKAnnot(CPDFSDK_BAAnnot* annot);
+
+ private:
+ CPDFSDK_BAAnnot* m_BAAnnot = nullptr;
+};
+
+class CJS_Annot : public CJS_Object {
+ public:
+ explicit CJS_Annot(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+ ~CJS_Annot() override {}
+
+ DECLARE_JS_CLASS();
+ JS_STATIC_PROP(hidden, Annot);
+ JS_STATIC_PROP(name, Annot);
+ JS_STATIC_PROP(type, Annot);
+};
+
+#endif // FPDFSDK_JAVASCRIPT_ANNOT_H_
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index e38f61d5fc..8fb07b085b 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -15,9 +15,11 @@
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
#include "core/fpdfdoc/include/cpdf_interform.h"
#include "core/fpdfdoc/include/cpdf_nametree.h"
+#include "fpdfsdk/include/cpdfsdk_annotiterator.h"
#include "fpdfsdk/include/cpdfsdk_interform.h"
#include "fpdfsdk/include/cpdfsdk_widget.h"
#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/javascript/Annot.h"
#include "fpdfsdk/javascript/Field.h"
#include "fpdfsdk/javascript/Icon.h"
#include "fpdfsdk/javascript/JS_Define.h"
@@ -1029,6 +1031,50 @@ FX_BOOL Document::getAnnot(IJS_Context* cc,
const std::vector<CJS_Value>& params,
CJS_Value& vRet,
CFX_WideString& sError) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ if (params.size() != 2) {
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+ return FALSE;
+ }
+
+ CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+ int nPageNo = params[0].ToInt(pRuntime);
+ CFX_WideString swAnnotName = params[1].ToCFXWideString(pRuntime);
+
+ CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(nPageNo);
+ if (!pPageView)
+ return FALSE;
+
+ CPDFSDK_AnnotIterator annotIterator(pPageView, false);
+ CPDFSDK_BAAnnot* pSDKBAAnnot = nullptr;
+ while (CPDFSDK_Annot* pSDKAnnotCur = annotIterator.Next()) {
+ CPDFSDK_BAAnnot* pBAAnnot = static_cast<CPDFSDK_BAAnnot*>(pSDKAnnotCur);
+ if (pBAAnnot && pBAAnnot->GetAnnotName() == swAnnotName) {
+ pSDKBAAnnot = pBAAnnot;
+ break;
+ }
+ }
+
+ if (!pSDKBAAnnot)
+ return FALSE;
+
+ v8::Local<v8::Object> pObj =
+ pRuntime->NewFxDynamicObj(CJS_Annot::g_nObjDefnID);
+ if (pObj.IsEmpty())
+ return FALSE;
+
+ CJS_Annot* pJS_Annot =
+ static_cast<CJS_Annot*>(pRuntime->GetObjectPrivate(pObj));
+ if (!pJS_Annot)
+ return FALSE;
+
+ Annot* pAnnot = static_cast<Annot*>(pJS_Annot->GetEmbedObject());
+ if (!pAnnot)
+ return FALSE;
+
+ pAnnot->SetSDKAnnot(pSDKBAAnnot);
+
+ vRet = CJS_Value(pRuntime, pJS_Annot);
return TRUE;
}
diff --git a/fpdfsdk/javascript/cjs_runtime.cpp b/fpdfsdk/javascript/cjs_runtime.cpp
index 7ea9b158a5..b12a3f5eeb 100644
--- a/fpdfsdk/javascript/cjs_runtime.cpp
+++ b/fpdfsdk/javascript/cjs_runtime.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/javascript/Annot.h"
#include "fpdfsdk/javascript/Consts.h"
#include "fpdfsdk/javascript/Document.h"
#include "fpdfsdk/javascript/Field.h"
@@ -175,9 +176,10 @@ void CJS_Runtime::DefineJSObjects() {
CJS_GlobalConsts::DefineJSObjects(this);
CJS_GlobalArrays::DefineJSObjects(this);
- // ObjDefIDs 21 - 22.
+ // ObjDefIDs 21 - 23.
CJS_TimerObj::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
CJS_PrintParamsObj::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
+ CJS_Annot::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
}
IJS_Context* CJS_Runtime::NewContext() {
diff --git a/pdfium.gyp b/pdfium.gyp
index 148c319eda..f2e0106b59 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -874,6 +874,8 @@
'fpdfsdk/javascript/JS_Runtime_Stub.cpp',
],
'sources': [
+ 'fpdfsdk/javascript/Annot.cpp',
+ 'fpdfsdk/javascript/Annot.h',
'fpdfsdk/javascript/Consts.cpp',
'fpdfsdk/javascript/Consts.h',
'fpdfsdk/javascript/Document.cpp',
diff --git a/testing/resources/javascript/document_methods.in b/testing/resources/javascript/document_methods.in
index 1c53dc24b5..bc0f3f1126 100644
--- a/testing/resources/javascript/document_methods.in
+++ b/testing/resources/javascript/document_methods.in
@@ -135,6 +135,18 @@ function testCalculateNow() {
// TODO(tsepez): test success cases.
}
+function testGetAnnot() {
+ // Method is present.
+ expect('typeof this.getAnnot', 'function');
+
+ // Method needs two arguments.
+ expectError('this.getAnnot()');
+ expectError('this.getAnnot(0)');
+ expectError('this.getAnnot(0, "test", 0)');
+
+ // TODO(tonikitoo): test success cases.
+}
+
function testGetField() {
// Method is present.
expect('typeof this.getField', 'function');
@@ -289,7 +301,6 @@ try {
testUnsupported('this.exportAsText');
testUnsupported('this.exportAsXFDF');
testUnsupported('this.extractPages');
- testUnsupported('this.getAnnot');
testUnsupported('this.getAnnot3D');
testUnsupported('this.getAnnots');
testUnsupported('this.getLinks');
@@ -307,6 +318,7 @@ try {
app.alert('*** Testing Supported Methods ***');
testAddIcon();
testCalculateNow();
+ testGetAnnot();
testGetField();
testGetIcon();
testGetNthFieldName();
diff --git a/testing/resources/javascript/document_methods_expected.txt b/testing/resources/javascript/document_methods_expected.txt
index d66de8b119..ed601f279b 100644
--- a/testing/resources/javascript/document_methods_expected.txt
+++ b/testing/resources/javascript/document_methods_expected.txt
@@ -29,9 +29,6 @@ Alert: PASS: this.exportAsXFDF(1, 2, "clams", [1, 2, 3]) = undefined
Alert: PASS: typeof this.extractPages = function
Alert: PASS: this.extractPages() = undefined
Alert: PASS: this.extractPages(1, 2, "clams", [1, 2, 3]) = undefined
-Alert: PASS: typeof this.getAnnot = function
-Alert: PASS: this.getAnnot() = undefined
-Alert: PASS: this.getAnnot(1, 2, "clams", [1, 2, 3]) = undefined
Alert: PASS: typeof this.getAnnot3D = function
Alert: PASS: this.getAnnot3D() = undefined
Alert: PASS: this.getAnnot3D(1, 2, "clams", [1, 2, 3]) = undefined
@@ -79,6 +76,10 @@ Alert: PASS: this.addIcon(1, 2, 3) threw error Document.addIcon: Incorrect numbe
Alert: PASS: this.addIcon("myicon", 3) threw error Document.addIcon: Incorrect parameter type.
Alert: PASS: this.addIcon("myicon", undefined) threw error Document.addIcon: Incorrect parameter type.
Alert: PASS: typeof this.calculateNow = function
+Alert: PASS: typeof this.getAnnot = function
+Alert: PASS: this.getAnnot() threw error Document.getAnnot: Incorrect number of parameters passed to function.
+Alert: PASS: this.getAnnot(0) threw error Document.getAnnot: Incorrect number of parameters passed to function.
+Alert: PASS: this.getAnnot(0, "test", 0) threw error Document.getAnnot: Incorrect number of parameters passed to function.
Alert: PASS: typeof this.getField = function
Alert: PASS: this.getField() threw error Document.getField: Incorrect number of parameters passed to function.
Alert: PASS: typeof this.getIcon = function