1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <stdint.h>
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
12*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
13*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
14*3ac0a46fSAndroid Build Coastguard Worker
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/page/cpdf_annotcontext.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_array.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_dictionary.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_nametree.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/data_vector.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/stl_util.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_helpers.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_interactiveform.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_pageview.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_widget.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/formfiller/cffl_formfield.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/ijs_event_context.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/ijs_runtime.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
30*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/contains.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/notreached.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/safe_conversions.h"
33*3ac0a46fSAndroid Build Coastguard Worker
34*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
35*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/fpdfxfa/cpdfxfa_widget.h"
36*3ac0a46fSAndroid Build Coastguard Worker #endif
37*3ac0a46fSAndroid Build Coastguard Worker
38*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXCT_ARROW ==
39*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(IPWL_FillerNotify::CursorStyle::kArrow),
40*3ac0a46fSAndroid Build Coastguard Worker "kArrow value mismatch");
41*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXCT_NESW ==
42*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(IPWL_FillerNotify::CursorStyle::kNESW),
43*3ac0a46fSAndroid Build Coastguard Worker "kNEWS value mismatch");
44*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXCT_NWSE ==
45*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(IPWL_FillerNotify::CursorStyle::kNWSE),
46*3ac0a46fSAndroid Build Coastguard Worker "kNWSE value mismatch");
47*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXCT_VBEAM ==
48*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(IPWL_FillerNotify::CursorStyle::kVBeam),
49*3ac0a46fSAndroid Build Coastguard Worker "kVBeam value mismatch");
50*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXCT_HBEAM ==
51*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(IPWL_FillerNotify::CursorStyle::kHBeam),
52*3ac0a46fSAndroid Build Coastguard Worker "HBeam value mismatch");
53*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXCT_HAND ==
54*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(IPWL_FillerNotify::CursorStyle::kHand),
55*3ac0a46fSAndroid Build Coastguard Worker "kHand value mismatch");
56*3ac0a46fSAndroid Build Coastguard Worker
AsFPDFWideString(ByteString * bsUTF16LE)57*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING AsFPDFWideString(ByteString* bsUTF16LE) {
58*3ac0a46fSAndroid Build Coastguard Worker // Force a private version of the string, since we're about to hand it off
59*3ac0a46fSAndroid Build Coastguard Worker // to the embedder. Should the embedder modify it by accident, it won't
60*3ac0a46fSAndroid Build Coastguard Worker // corrupt other shares of the string beyond |bsUTF16LE|.
61*3ac0a46fSAndroid Build Coastguard Worker return reinterpret_cast<FPDF_WIDESTRING>(
62*3ac0a46fSAndroid Build Coastguard Worker bsUTF16LE->GetBuffer(bsUTF16LE->GetLength()).data());
63*3ac0a46fSAndroid Build Coastguard Worker }
64*3ac0a46fSAndroid Build Coastguard Worker
CPDFSDK_FormFillEnvironment(CPDF_Document * pDoc,FPDF_FORMFILLINFO * pFFinfo)65*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment(
66*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc,
67*3ac0a46fSAndroid Build Coastguard Worker FPDF_FORMFILLINFO* pFFinfo)
68*3ac0a46fSAndroid Build Coastguard Worker : m_pInfo(pFFinfo),
69*3ac0a46fSAndroid Build Coastguard Worker m_pCPDFDoc(pDoc),
70*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveFormFiller(
71*3ac0a46fSAndroid Build Coastguard Worker std::make_unique<CFFL_InteractiveFormFiller>(this)) {
72*3ac0a46fSAndroid Build Coastguard Worker DCHECK(m_pCPDFDoc);
73*3ac0a46fSAndroid Build Coastguard Worker }
74*3ac0a46fSAndroid Build Coastguard Worker
~CPDFSDK_FormFillEnvironment()75*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() {
76*3ac0a46fSAndroid Build Coastguard Worker m_bBeingDestroyed = true;
77*3ac0a46fSAndroid Build Coastguard Worker ClearAllFocusedAnnots();
78*3ac0a46fSAndroid Build Coastguard Worker
79*3ac0a46fSAndroid Build Coastguard Worker // |m_PageMap| will try to access |m_pInteractiveForm| when it cleans itself
80*3ac0a46fSAndroid Build Coastguard Worker // up. Make sure it is deleted before |m_pInteractiveForm|.
81*3ac0a46fSAndroid Build Coastguard Worker m_PageMap.clear();
82*3ac0a46fSAndroid Build Coastguard Worker
83*3ac0a46fSAndroid Build Coastguard Worker // Must destroy the |m_pInteractiveFormFiller| before the environment (|this|)
84*3ac0a46fSAndroid Build Coastguard Worker // because any created form widgets hold a pointer to the environment.
85*3ac0a46fSAndroid Build Coastguard Worker // Those widgets may call things like KillTimer() as they are shutdown.
86*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveFormFiller.reset();
87*3ac0a46fSAndroid Build Coastguard Worker
88*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->Release)
89*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->Release(m_pInfo);
90*3ac0a46fSAndroid Build Coastguard Worker }
91*3ac0a46fSAndroid Build Coastguard Worker
InvalidateRect(CPDFSDK_Widget * widget,const CFX_FloatRect & rect)92*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::InvalidateRect(CPDFSDK_Widget* widget,
93*3ac0a46fSAndroid Build Coastguard Worker const CFX_FloatRect& rect) {
94*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pPage = widget->GetPage();
95*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
96*3ac0a46fSAndroid Build Coastguard Worker return;
97*3ac0a46fSAndroid Build Coastguard Worker
98*3ac0a46fSAndroid Build Coastguard Worker CFX_Matrix device2page =
99*3ac0a46fSAndroid Build Coastguard Worker widget->GetPageView()->GetCurrentMatrix().GetInverse();
100*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF left_top = device2page.Transform(CFX_PointF(rect.left, rect.top));
101*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF right_bottom =
102*3ac0a46fSAndroid Build Coastguard Worker device2page.Transform(CFX_PointF(rect.right, rect.bottom));
103*3ac0a46fSAndroid Build Coastguard Worker
104*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect rcPDF(left_top.x, right_bottom.y, right_bottom.x, left_top.y);
105*3ac0a46fSAndroid Build Coastguard Worker rcPDF.Normalize();
106*3ac0a46fSAndroid Build Coastguard Worker Invalidate(pPage, rcPDF.GetOuterRect());
107*3ac0a46fSAndroid Build Coastguard Worker }
108*3ac0a46fSAndroid Build Coastguard Worker
OutputSelectedRect(CFFL_FormField * pFormField,const CFX_FloatRect & rect)109*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::OutputSelectedRect(
110*3ac0a46fSAndroid Build Coastguard Worker CFFL_FormField* pFormField,
111*3ac0a46fSAndroid Build Coastguard Worker const CFX_FloatRect& rect) {
112*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || !m_pInfo->FFI_OutputSelectedRect)
113*3ac0a46fSAndroid Build Coastguard Worker return;
114*3ac0a46fSAndroid Build Coastguard Worker
115*3ac0a46fSAndroid Build Coastguard Worker auto* pPage = FPDFPageFromIPDFPage(pFormField->GetSDKWidget()->GetPage());
116*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pPage);
117*3ac0a46fSAndroid Build Coastguard Worker
118*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptA = pFormField->PWLtoFFL(CFX_PointF(rect.left, rect.bottom));
119*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptB = pFormField->PWLtoFFL(CFX_PointF(rect.right, rect.top));
120*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_OutputSelectedRect(m_pInfo, pPage, ptA.x, ptB.y, ptB.x, ptA.y);
121*3ac0a46fSAndroid Build Coastguard Worker }
122*3ac0a46fSAndroid Build Coastguard Worker
IsSelectionImplemented() const123*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::IsSelectionImplemented() const {
124*3ac0a46fSAndroid Build Coastguard Worker FPDF_FORMFILLINFO* pInfo = GetFormFillInfo();
125*3ac0a46fSAndroid Build Coastguard Worker return pInfo && pInfo->FFI_OutputSelectedRect;
126*3ac0a46fSAndroid Build Coastguard Worker }
127*3ac0a46fSAndroid Build Coastguard Worker
128*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_V8
GetCurrentView()129*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() {
130*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pPage = GetCurrentPage();
131*3ac0a46fSAndroid Build Coastguard Worker return pPage ? GetOrCreatePageView(pPage) : nullptr;
132*3ac0a46fSAndroid Build Coastguard Worker }
133*3ac0a46fSAndroid Build Coastguard Worker
GetCurrentPage() const134*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* CPDFSDK_FormFillEnvironment::GetCurrentPage() const {
135*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_GetCurrentPage) {
136*3ac0a46fSAndroid Build Coastguard Worker return IPDFPageFromFPDFPage(m_pInfo->FFI_GetCurrentPage(
137*3ac0a46fSAndroid Build Coastguard Worker m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc)));
138*3ac0a46fSAndroid Build Coastguard Worker }
139*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
140*3ac0a46fSAndroid Build Coastguard Worker }
141*3ac0a46fSAndroid Build Coastguard Worker
GetLanguage()142*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_FormFillEnvironment::GetLanguage() {
143*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
144*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetLanguage)
145*3ac0a46fSAndroid Build Coastguard Worker return WideString();
146*3ac0a46fSAndroid Build Coastguard Worker
147*3ac0a46fSAndroid Build Coastguard Worker int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, nullptr, 0);
148*3ac0a46fSAndroid Build Coastguard Worker if (nRequiredLen <= 0)
149*3ac0a46fSAndroid Build Coastguard Worker return WideString();
150*3ac0a46fSAndroid Build Coastguard Worker
151*3ac0a46fSAndroid Build Coastguard Worker DataVector<uint8_t> pBuff(nRequiredLen);
152*3ac0a46fSAndroid Build Coastguard Worker int nActualLen =
153*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_GetLanguage(m_pInfo, pBuff.data(), nRequiredLen);
154*3ac0a46fSAndroid Build Coastguard Worker if (nActualLen <= 0 || nActualLen > nRequiredLen)
155*3ac0a46fSAndroid Build Coastguard Worker return WideString();
156*3ac0a46fSAndroid Build Coastguard Worker
157*3ac0a46fSAndroid Build Coastguard Worker return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
158*3ac0a46fSAndroid Build Coastguard Worker nActualLen / sizeof(uint16_t));
159*3ac0a46fSAndroid Build Coastguard Worker #else // PDF_ENABLE_XFA
160*3ac0a46fSAndroid Build Coastguard Worker return WideString();
161*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
162*3ac0a46fSAndroid Build Coastguard Worker }
163*3ac0a46fSAndroid Build Coastguard Worker
GetPlatform()164*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_FormFillEnvironment::GetPlatform() {
165*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
166*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetPlatform)
167*3ac0a46fSAndroid Build Coastguard Worker return WideString();
168*3ac0a46fSAndroid Build Coastguard Worker
169*3ac0a46fSAndroid Build Coastguard Worker int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, nullptr, 0);
170*3ac0a46fSAndroid Build Coastguard Worker if (nRequiredLen <= 0)
171*3ac0a46fSAndroid Build Coastguard Worker return WideString();
172*3ac0a46fSAndroid Build Coastguard Worker
173*3ac0a46fSAndroid Build Coastguard Worker DataVector<uint8_t> pBuff(nRequiredLen);
174*3ac0a46fSAndroid Build Coastguard Worker int nActualLen =
175*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_GetPlatform(m_pInfo, pBuff.data(), nRequiredLen);
176*3ac0a46fSAndroid Build Coastguard Worker if (nActualLen <= 0 || nActualLen > nRequiredLen)
177*3ac0a46fSAndroid Build Coastguard Worker return WideString();
178*3ac0a46fSAndroid Build Coastguard Worker
179*3ac0a46fSAndroid Build Coastguard Worker return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
180*3ac0a46fSAndroid Build Coastguard Worker nActualLen / sizeof(uint16_t));
181*3ac0a46fSAndroid Build Coastguard Worker #else // PDF_ENABLE_XFA
182*3ac0a46fSAndroid Build Coastguard Worker return WideString();
183*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
184*3ac0a46fSAndroid Build Coastguard Worker }
185*3ac0a46fSAndroid Build Coastguard Worker
JS_appAlert(const WideString & Msg,const WideString & Title,int Type,int Icon)186*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_FormFillEnvironment::JS_appAlert(const WideString& Msg,
187*3ac0a46fSAndroid Build Coastguard Worker const WideString& Title,
188*3ac0a46fSAndroid Build Coastguard Worker int Type,
189*3ac0a46fSAndroid Build Coastguard Worker int Icon) {
190*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
191*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->app_alert)
192*3ac0a46fSAndroid Build Coastguard Worker return -1;
193*3ac0a46fSAndroid Build Coastguard Worker
194*3ac0a46fSAndroid Build Coastguard Worker ByteString bsMsg = Msg.ToUTF16LE();
195*3ac0a46fSAndroid Build Coastguard Worker ByteString bsTitle = Title.ToUTF16LE();
196*3ac0a46fSAndroid Build Coastguard Worker return js_platform->app_alert(js_platform, AsFPDFWideString(&bsMsg),
197*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsTitle), Type, Icon);
198*3ac0a46fSAndroid Build Coastguard Worker }
199*3ac0a46fSAndroid Build Coastguard Worker
JS_appResponse(const WideString & Question,const WideString & Title,const WideString & Default,const WideString & Label,FPDF_BOOL bPassword,pdfium::span<uint8_t> response)200*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_FormFillEnvironment::JS_appResponse(
201*3ac0a46fSAndroid Build Coastguard Worker const WideString& Question,
202*3ac0a46fSAndroid Build Coastguard Worker const WideString& Title,
203*3ac0a46fSAndroid Build Coastguard Worker const WideString& Default,
204*3ac0a46fSAndroid Build Coastguard Worker const WideString& Label,
205*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bPassword,
206*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<uint8_t> response) {
207*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
208*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->app_response)
209*3ac0a46fSAndroid Build Coastguard Worker return -1;
210*3ac0a46fSAndroid Build Coastguard Worker
211*3ac0a46fSAndroid Build Coastguard Worker ByteString bsQuestion = Question.ToUTF16LE();
212*3ac0a46fSAndroid Build Coastguard Worker ByteString bsTitle = Title.ToUTF16LE();
213*3ac0a46fSAndroid Build Coastguard Worker ByteString bsDefault = Default.ToUTF16LE();
214*3ac0a46fSAndroid Build Coastguard Worker ByteString bsLabel = Label.ToUTF16LE();
215*3ac0a46fSAndroid Build Coastguard Worker return js_platform->app_response(
216*3ac0a46fSAndroid Build Coastguard Worker js_platform, AsFPDFWideString(&bsQuestion), AsFPDFWideString(&bsTitle),
217*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsDefault), AsFPDFWideString(&bsLabel), bPassword,
218*3ac0a46fSAndroid Build Coastguard Worker response.data(), pdfium::base::checked_cast<int>(response.size()));
219*3ac0a46fSAndroid Build Coastguard Worker }
220*3ac0a46fSAndroid Build Coastguard Worker
JS_appBeep(int nType)221*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::JS_appBeep(int nType) {
222*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
223*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->app_beep)
224*3ac0a46fSAndroid Build Coastguard Worker return;
225*3ac0a46fSAndroid Build Coastguard Worker
226*3ac0a46fSAndroid Build Coastguard Worker js_platform->app_beep(js_platform, nType);
227*3ac0a46fSAndroid Build Coastguard Worker }
228*3ac0a46fSAndroid Build Coastguard Worker
JS_fieldBrowse()229*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_FormFillEnvironment::JS_fieldBrowse() {
230*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
231*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->Field_browse)
232*3ac0a46fSAndroid Build Coastguard Worker return WideString();
233*3ac0a46fSAndroid Build Coastguard Worker
234*3ac0a46fSAndroid Build Coastguard Worker const int nRequiredLen = js_platform->Field_browse(js_platform, nullptr, 0);
235*3ac0a46fSAndroid Build Coastguard Worker if (nRequiredLen <= 0)
236*3ac0a46fSAndroid Build Coastguard Worker return WideString();
237*3ac0a46fSAndroid Build Coastguard Worker
238*3ac0a46fSAndroid Build Coastguard Worker DataVector<uint8_t> pBuff(nRequiredLen);
239*3ac0a46fSAndroid Build Coastguard Worker const int nActualLen =
240*3ac0a46fSAndroid Build Coastguard Worker js_platform->Field_browse(js_platform, pBuff.data(), nRequiredLen);
241*3ac0a46fSAndroid Build Coastguard Worker if (nActualLen <= 0 || nActualLen > nRequiredLen)
242*3ac0a46fSAndroid Build Coastguard Worker return WideString();
243*3ac0a46fSAndroid Build Coastguard Worker
244*3ac0a46fSAndroid Build Coastguard Worker // Don't include trailing NUL.
245*3ac0a46fSAndroid Build Coastguard Worker pBuff.resize(nActualLen - 1);
246*3ac0a46fSAndroid Build Coastguard Worker
247*3ac0a46fSAndroid Build Coastguard Worker // Use FromDefANSI() per "local encoding" comment in fpdf_formfill.h.
248*3ac0a46fSAndroid Build Coastguard Worker return WideString::FromDefANSI(ByteStringView(pBuff));
249*3ac0a46fSAndroid Build Coastguard Worker }
250*3ac0a46fSAndroid Build Coastguard Worker
JS_docmailForm(pdfium::span<const uint8_t> mailData,FPDF_BOOL bUI,const WideString & To,const WideString & Subject,const WideString & CC,const WideString & BCC,const WideString & Msg)251*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::JS_docmailForm(
252*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<const uint8_t> mailData,
253*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bUI,
254*3ac0a46fSAndroid Build Coastguard Worker const WideString& To,
255*3ac0a46fSAndroid Build Coastguard Worker const WideString& Subject,
256*3ac0a46fSAndroid Build Coastguard Worker const WideString& CC,
257*3ac0a46fSAndroid Build Coastguard Worker const WideString& BCC,
258*3ac0a46fSAndroid Build Coastguard Worker const WideString& Msg) {
259*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
260*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->Doc_mail)
261*3ac0a46fSAndroid Build Coastguard Worker return;
262*3ac0a46fSAndroid Build Coastguard Worker
263*3ac0a46fSAndroid Build Coastguard Worker ByteString bsTo = To.ToUTF16LE();
264*3ac0a46fSAndroid Build Coastguard Worker ByteString bsSubject = Subject.ToUTF16LE();
265*3ac0a46fSAndroid Build Coastguard Worker ByteString bsCC = CC.ToUTF16LE();
266*3ac0a46fSAndroid Build Coastguard Worker ByteString bsBcc = BCC.ToUTF16LE();
267*3ac0a46fSAndroid Build Coastguard Worker ByteString bsMsg = Msg.ToUTF16LE();
268*3ac0a46fSAndroid Build Coastguard Worker js_platform->Doc_mail(js_platform, const_cast<uint8_t*>(mailData.data()),
269*3ac0a46fSAndroid Build Coastguard Worker pdfium::base::checked_cast<int>(mailData.size()), bUI,
270*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsTo), AsFPDFWideString(&bsSubject),
271*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsCC), AsFPDFWideString(&bsBcc),
272*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsMsg));
273*3ac0a46fSAndroid Build Coastguard Worker }
274*3ac0a46fSAndroid Build Coastguard Worker
JS_docprint(FPDF_BOOL bUI,int nStart,int nEnd,FPDF_BOOL bSilent,FPDF_BOOL bShrinkToFit,FPDF_BOOL bPrintAsImage,FPDF_BOOL bReverse,FPDF_BOOL bAnnotations)275*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::JS_docprint(FPDF_BOOL bUI,
276*3ac0a46fSAndroid Build Coastguard Worker int nStart,
277*3ac0a46fSAndroid Build Coastguard Worker int nEnd,
278*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bSilent,
279*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bShrinkToFit,
280*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bPrintAsImage,
281*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bReverse,
282*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bAnnotations) {
283*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
284*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->Doc_print)
285*3ac0a46fSAndroid Build Coastguard Worker return;
286*3ac0a46fSAndroid Build Coastguard Worker
287*3ac0a46fSAndroid Build Coastguard Worker js_platform->Doc_print(js_platform, bUI, nStart, nEnd, bSilent, bShrinkToFit,
288*3ac0a46fSAndroid Build Coastguard Worker bPrintAsImage, bReverse, bAnnotations);
289*3ac0a46fSAndroid Build Coastguard Worker }
290*3ac0a46fSAndroid Build Coastguard Worker
JS_docgotoPage(int nPageNum)291*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::JS_docgotoPage(int nPageNum) {
292*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
293*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->Doc_gotoPage)
294*3ac0a46fSAndroid Build Coastguard Worker return;
295*3ac0a46fSAndroid Build Coastguard Worker
296*3ac0a46fSAndroid Build Coastguard Worker js_platform->Doc_gotoPage(js_platform, nPageNum);
297*3ac0a46fSAndroid Build Coastguard Worker }
298*3ac0a46fSAndroid Build Coastguard Worker
JS_docGetFilePath()299*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_FormFillEnvironment::JS_docGetFilePath() {
300*3ac0a46fSAndroid Build Coastguard Worker return GetFilePath();
301*3ac0a46fSAndroid Build Coastguard Worker }
302*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_V8
303*3ac0a46fSAndroid Build Coastguard Worker
GetFilePath() const304*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_FormFillEnvironment::GetFilePath() const {
305*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
306*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->Doc_getFilePath)
307*3ac0a46fSAndroid Build Coastguard Worker return WideString();
308*3ac0a46fSAndroid Build Coastguard Worker
309*3ac0a46fSAndroid Build Coastguard Worker const int nRequiredLen =
310*3ac0a46fSAndroid Build Coastguard Worker js_platform->Doc_getFilePath(js_platform, nullptr, 0);
311*3ac0a46fSAndroid Build Coastguard Worker if (nRequiredLen <= 0)
312*3ac0a46fSAndroid Build Coastguard Worker return WideString();
313*3ac0a46fSAndroid Build Coastguard Worker
314*3ac0a46fSAndroid Build Coastguard Worker DataVector<uint8_t> pBuff(nRequiredLen);
315*3ac0a46fSAndroid Build Coastguard Worker const int nActualLen =
316*3ac0a46fSAndroid Build Coastguard Worker js_platform->Doc_getFilePath(js_platform, pBuff.data(), nRequiredLen);
317*3ac0a46fSAndroid Build Coastguard Worker if (nActualLen <= 0 || nActualLen > nRequiredLen)
318*3ac0a46fSAndroid Build Coastguard Worker return WideString();
319*3ac0a46fSAndroid Build Coastguard Worker
320*3ac0a46fSAndroid Build Coastguard Worker // Don't include trailing NUL.
321*3ac0a46fSAndroid Build Coastguard Worker pBuff.resize(nActualLen - 1);
322*3ac0a46fSAndroid Build Coastguard Worker
323*3ac0a46fSAndroid Build Coastguard Worker // Use FromDefANSI() per "local encoding" comment in fpdf_formfill.h.
324*3ac0a46fSAndroid Build Coastguard Worker return WideString::FromDefANSI(ByteStringView(pBuff));
325*3ac0a46fSAndroid Build Coastguard Worker }
326*3ac0a46fSAndroid Build Coastguard Worker
SubmitForm(pdfium::span<const uint8_t> form_data,const WideString & URL)327*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::SubmitForm(
328*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<const uint8_t> form_data,
329*3ac0a46fSAndroid Build Coastguard Worker const WideString& URL) {
330*3ac0a46fSAndroid Build Coastguard Worker IPDF_JSPLATFORM* js_platform = GetJSPlatform();
331*3ac0a46fSAndroid Build Coastguard Worker if (!js_platform || !js_platform->Doc_submitForm)
332*3ac0a46fSAndroid Build Coastguard Worker return;
333*3ac0a46fSAndroid Build Coastguard Worker
334*3ac0a46fSAndroid Build Coastguard Worker ByteString bsUrl = URL.ToUTF16LE();
335*3ac0a46fSAndroid Build Coastguard Worker js_platform->Doc_submitForm(
336*3ac0a46fSAndroid Build Coastguard Worker js_platform, const_cast<uint8_t*>(form_data.data()),
337*3ac0a46fSAndroid Build Coastguard Worker fxcrt::CollectionSize<int>(form_data), AsFPDFWideString(&bsUrl));
338*3ac0a46fSAndroid Build Coastguard Worker }
339*3ac0a46fSAndroid Build Coastguard Worker
GetIJSRuntime()340*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime* CPDFSDK_FormFillEnvironment::GetIJSRuntime() {
341*3ac0a46fSAndroid Build Coastguard Worker if (!m_pIJSRuntime)
342*3ac0a46fSAndroid Build Coastguard Worker m_pIJSRuntime = IJS_Runtime::Create(this);
343*3ac0a46fSAndroid Build Coastguard Worker return m_pIJSRuntime.get();
344*3ac0a46fSAndroid Build Coastguard Worker }
345*3ac0a46fSAndroid Build Coastguard Worker
Invalidate(IPDF_Page * page,const FX_RECT & rect)346*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::Invalidate(IPDF_Page* page,
347*3ac0a46fSAndroid Build Coastguard Worker const FX_RECT& rect) {
348*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_Invalidate) {
349*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_Invalidate(m_pInfo, FPDFPageFromIPDFPage(page), rect.left,
350*3ac0a46fSAndroid Build Coastguard Worker rect.top, rect.right, rect.bottom);
351*3ac0a46fSAndroid Build Coastguard Worker }
352*3ac0a46fSAndroid Build Coastguard Worker }
353*3ac0a46fSAndroid Build Coastguard Worker
SetCursor(IPWL_FillerNotify::CursorStyle nCursorType)354*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::SetCursor(
355*3ac0a46fSAndroid Build Coastguard Worker IPWL_FillerNotify::CursorStyle nCursorType) {
356*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_SetCursor)
357*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_SetCursor(m_pInfo, static_cast<int>(nCursorType));
358*3ac0a46fSAndroid Build Coastguard Worker }
359*3ac0a46fSAndroid Build Coastguard Worker
SetTimer(int uElapse,TimerCallback lpTimerFunc)360*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_FormFillEnvironment::SetTimer(int uElapse,
361*3ac0a46fSAndroid Build Coastguard Worker TimerCallback lpTimerFunc) {
362*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_SetTimer)
363*3ac0a46fSAndroid Build Coastguard Worker return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
364*3ac0a46fSAndroid Build Coastguard Worker return CFX_Timer::HandlerIface::kInvalidTimerID;
365*3ac0a46fSAndroid Build Coastguard Worker }
366*3ac0a46fSAndroid Build Coastguard Worker
KillTimer(int nTimerID)367*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::KillTimer(int nTimerID) {
368*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_KillTimer)
369*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
370*3ac0a46fSAndroid Build Coastguard Worker }
371*3ac0a46fSAndroid Build Coastguard Worker
OnChange()372*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::OnChange() {
373*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_OnChange)
374*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_OnChange(m_pInfo);
375*3ac0a46fSAndroid Build Coastguard Worker }
376*3ac0a46fSAndroid Build Coastguard Worker
ExecuteNamedAction(const ByteString & namedAction)377*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::ExecuteNamedAction(
378*3ac0a46fSAndroid Build Coastguard Worker const ByteString& namedAction) {
379*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
380*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction.c_str());
381*3ac0a46fSAndroid Build Coastguard Worker }
382*3ac0a46fSAndroid Build Coastguard Worker
OnSetFieldInputFocus(const WideString & text)383*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::OnSetFieldInputFocus(const WideString& text) {
384*3ac0a46fSAndroid Build Coastguard Worker OnSetFieldInputFocusInternal(text, true);
385*3ac0a46fSAndroid Build Coastguard Worker }
386*3ac0a46fSAndroid Build Coastguard Worker
OnSetFieldInputFocusInternal(const WideString & text,bool bFocus)387*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::OnSetFieldInputFocusInternal(
388*3ac0a46fSAndroid Build Coastguard Worker const WideString& text,
389*3ac0a46fSAndroid Build Coastguard Worker bool bFocus) {
390*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus) {
391*3ac0a46fSAndroid Build Coastguard Worker size_t nCharacters = text.GetLength();
392*3ac0a46fSAndroid Build Coastguard Worker ByteString bsUTFText = text.ToUTF16LE();
393*3ac0a46fSAndroid Build Coastguard Worker auto* pBuffer = reinterpret_cast<const unsigned short*>(bsUTFText.c_str());
394*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_SetTextFieldFocus(
395*3ac0a46fSAndroid Build Coastguard Worker m_pInfo, pBuffer, pdfium::base::checked_cast<FPDF_DWORD>(nCharacters),
396*3ac0a46fSAndroid Build Coastguard Worker bFocus);
397*3ac0a46fSAndroid Build Coastguard Worker }
398*3ac0a46fSAndroid Build Coastguard Worker }
399*3ac0a46fSAndroid Build Coastguard Worker
OnCalculate(ObservedPtr<CPDFSDK_Annot> & pAnnot)400*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::OnCalculate(
401*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot>& pAnnot) {
402*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot.Get());
403*3ac0a46fSAndroid Build Coastguard Worker if (pWidget)
404*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->OnCalculate(pWidget->GetFormField());
405*3ac0a46fSAndroid Build Coastguard Worker }
406*3ac0a46fSAndroid Build Coastguard Worker
OnFormat(ObservedPtr<CPDFSDK_Annot> & pAnnot)407*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::OnFormat(ObservedPtr<CPDFSDK_Annot>& pAnnot) {
408*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot.Get());
409*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pWidget);
410*3ac0a46fSAndroid Build Coastguard Worker
411*3ac0a46fSAndroid Build Coastguard Worker absl::optional<WideString> sValue =
412*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->OnFormat(pWidget->GetFormField());
413*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
414*3ac0a46fSAndroid Build Coastguard Worker return;
415*3ac0a46fSAndroid Build Coastguard Worker
416*3ac0a46fSAndroid Build Coastguard Worker if (sValue.has_value()) {
417*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->ResetFieldAppearance(pWidget->GetFormField(), sValue);
418*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm->UpdateField(pWidget->GetFormField());
419*3ac0a46fSAndroid Build Coastguard Worker }
420*3ac0a46fSAndroid Build Coastguard Worker }
421*3ac0a46fSAndroid Build Coastguard Worker
DoURIAction(const ByteString & bsURI,Mask<FWL_EVENTFLAG> modifiers)422*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoURIAction(const ByteString& bsURI,
423*3ac0a46fSAndroid Build Coastguard Worker Mask<FWL_EVENTFLAG> modifiers) {
424*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo)
425*3ac0a46fSAndroid Build Coastguard Worker return;
426*3ac0a46fSAndroid Build Coastguard Worker
427*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo->version >= 2 && m_pInfo->FFI_DoURIActionWithKeyboardModifier) {
428*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_DoURIActionWithKeyboardModifier(m_pInfo, bsURI.c_str(),
429*3ac0a46fSAndroid Build Coastguard Worker modifiers.UncheckedValue());
430*3ac0a46fSAndroid Build Coastguard Worker return;
431*3ac0a46fSAndroid Build Coastguard Worker }
432*3ac0a46fSAndroid Build Coastguard Worker
433*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo->FFI_DoURIAction)
434*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_DoURIAction(m_pInfo, bsURI.c_str());
435*3ac0a46fSAndroid Build Coastguard Worker }
436*3ac0a46fSAndroid Build Coastguard Worker
DoGoToAction(int nPageIndex,int zoomMode,pdfium::span<float> fPosArray)437*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoGoToAction(int nPageIndex,
438*3ac0a46fSAndroid Build Coastguard Worker int zoomMode,
439*3ac0a46fSAndroid Build Coastguard Worker pdfium::span<float> fPosArray) {
440*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->FFI_DoGoToAction) {
441*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray.data(),
442*3ac0a46fSAndroid Build Coastguard Worker fxcrt::CollectionSize<int>(fPosArray));
443*3ac0a46fSAndroid Build Coastguard Worker }
444*3ac0a46fSAndroid Build Coastguard Worker }
445*3ac0a46fSAndroid Build Coastguard Worker
446*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
GetPageViewCount() const447*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_FormFillEnvironment::GetPageViewCount() const {
448*3ac0a46fSAndroid Build Coastguard Worker return fxcrt::CollectionSize<int>(m_PageMap);
449*3ac0a46fSAndroid Build Coastguard Worker }
450*3ac0a46fSAndroid Build Coastguard Worker
DisplayCaret(IPDF_Page * page,FPDF_BOOL bVisible,double left,double top,double right,double bottom)451*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DisplayCaret(IPDF_Page* page,
452*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL bVisible,
453*3ac0a46fSAndroid Build Coastguard Worker double left,
454*3ac0a46fSAndroid Build Coastguard Worker double top,
455*3ac0a46fSAndroid Build Coastguard Worker double right,
456*3ac0a46fSAndroid Build Coastguard Worker double bottom) {
457*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_DisplayCaret) {
458*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_DisplayCaret(m_pInfo, FPDFPageFromIPDFPage(page), bVisible,
459*3ac0a46fSAndroid Build Coastguard Worker left, top, right, bottom);
460*3ac0a46fSAndroid Build Coastguard Worker }
461*3ac0a46fSAndroid Build Coastguard Worker }
462*3ac0a46fSAndroid Build Coastguard Worker
GetCurrentPageIndex() const463*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_FormFillEnvironment::GetCurrentPageIndex() const {
464*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetCurrentPageIndex)
465*3ac0a46fSAndroid Build Coastguard Worker return -1;
466*3ac0a46fSAndroid Build Coastguard Worker return m_pInfo->FFI_GetCurrentPageIndex(
467*3ac0a46fSAndroid Build Coastguard Worker m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc));
468*3ac0a46fSAndroid Build Coastguard Worker }
469*3ac0a46fSAndroid Build Coastguard Worker
SetCurrentPage(int iCurPage)470*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::SetCurrentPage(int iCurPage) {
471*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_SetCurrentPage)
472*3ac0a46fSAndroid Build Coastguard Worker return;
473*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_SetCurrentPage(m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc),
474*3ac0a46fSAndroid Build Coastguard Worker iCurPage);
475*3ac0a46fSAndroid Build Coastguard Worker }
476*3ac0a46fSAndroid Build Coastguard Worker
GotoURL(const WideString & wsURL)477*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::GotoURL(const WideString& wsURL) {
478*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GotoURL)
479*3ac0a46fSAndroid Build Coastguard Worker return;
480*3ac0a46fSAndroid Build Coastguard Worker
481*3ac0a46fSAndroid Build Coastguard Worker ByteString bsTo = wsURL.ToUTF16LE();
482*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_GotoURL(m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc),
483*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsTo));
484*3ac0a46fSAndroid Build Coastguard Worker }
485*3ac0a46fSAndroid Build Coastguard Worker
GetPageViewRect(IPDF_Page * page)486*3ac0a46fSAndroid Build Coastguard Worker FS_RECTF CPDFSDK_FormFillEnvironment::GetPageViewRect(IPDF_Page* page) {
487*3ac0a46fSAndroid Build Coastguard Worker FS_RECTF rect = {0.0f, 0.0f, 0.0f, 0.0f};
488*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetPageViewRect)
489*3ac0a46fSAndroid Build Coastguard Worker return rect;
490*3ac0a46fSAndroid Build Coastguard Worker
491*3ac0a46fSAndroid Build Coastguard Worker double left;
492*3ac0a46fSAndroid Build Coastguard Worker double top;
493*3ac0a46fSAndroid Build Coastguard Worker double right;
494*3ac0a46fSAndroid Build Coastguard Worker double bottom;
495*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_GetPageViewRect(m_pInfo, FPDFPageFromIPDFPage(page), &left, &top,
496*3ac0a46fSAndroid Build Coastguard Worker &right, &bottom);
497*3ac0a46fSAndroid Build Coastguard Worker
498*3ac0a46fSAndroid Build Coastguard Worker rect.left = static_cast<float>(left);
499*3ac0a46fSAndroid Build Coastguard Worker rect.top = static_cast<float>(top);
500*3ac0a46fSAndroid Build Coastguard Worker rect.bottom = static_cast<float>(bottom);
501*3ac0a46fSAndroid Build Coastguard Worker rect.right = static_cast<float>(right);
502*3ac0a46fSAndroid Build Coastguard Worker return rect;
503*3ac0a46fSAndroid Build Coastguard Worker }
504*3ac0a46fSAndroid Build Coastguard Worker
PopupMenu(IPDF_Page * page,int menuFlag,const CFX_PointF & pt)505*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::PopupMenu(IPDF_Page* page,
506*3ac0a46fSAndroid Build Coastguard Worker int menuFlag,
507*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& pt) {
508*3ac0a46fSAndroid Build Coastguard Worker return m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_PopupMenu &&
509*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_PopupMenu(m_pInfo, FPDFPageFromIPDFPage(page), nullptr,
510*3ac0a46fSAndroid Build Coastguard Worker menuFlag, pt.x, pt.y);
511*3ac0a46fSAndroid Build Coastguard Worker }
512*3ac0a46fSAndroid Build Coastguard Worker
EmailTo(FPDF_FILEHANDLER * fileHandler,FPDF_WIDESTRING pTo,FPDF_WIDESTRING pSubject,FPDF_WIDESTRING pCC,FPDF_WIDESTRING pBcc,FPDF_WIDESTRING pMsg)513*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::EmailTo(FPDF_FILEHANDLER* fileHandler,
514*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING pTo,
515*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING pSubject,
516*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING pCC,
517*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING pBcc,
518*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING pMsg) {
519*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_EmailTo)
520*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc, pMsg);
521*3ac0a46fSAndroid Build Coastguard Worker }
522*3ac0a46fSAndroid Build Coastguard Worker
UploadTo(FPDF_FILEHANDLER * fileHandler,int fileFlag,FPDF_WIDESTRING uploadTo)523*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::UploadTo(FPDF_FILEHANDLER* fileHandler,
524*3ac0a46fSAndroid Build Coastguard Worker int fileFlag,
525*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING uploadTo) {
526*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_UploadTo)
527*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo);
528*3ac0a46fSAndroid Build Coastguard Worker }
529*3ac0a46fSAndroid Build Coastguard Worker
OpenFile(int fileType,FPDF_WIDESTRING wsURL,const char * mode)530*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* CPDFSDK_FormFillEnvironment::OpenFile(int fileType,
531*3ac0a46fSAndroid Build Coastguard Worker FPDF_WIDESTRING wsURL,
532*3ac0a46fSAndroid Build Coastguard Worker const char* mode) {
533*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_OpenFile)
534*3ac0a46fSAndroid Build Coastguard Worker return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode);
535*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
536*3ac0a46fSAndroid Build Coastguard Worker }
537*3ac0a46fSAndroid Build Coastguard Worker
DownloadFromURL(const WideString & url)538*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> CPDFSDK_FormFillEnvironment::DownloadFromURL(
539*3ac0a46fSAndroid Build Coastguard Worker const WideString& url) {
540*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_DownloadFromURL)
541*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
542*3ac0a46fSAndroid Build Coastguard Worker
543*3ac0a46fSAndroid Build Coastguard Worker ByteString bstrURL = url.ToUTF16LE();
544*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* fileHandler =
545*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_DownloadFromURL(m_pInfo, AsFPDFWideString(&bstrURL));
546*3ac0a46fSAndroid Build Coastguard Worker
547*3ac0a46fSAndroid Build Coastguard Worker return MakeSeekableStream(fileHandler);
548*3ac0a46fSAndroid Build Coastguard Worker }
549*3ac0a46fSAndroid Build Coastguard Worker
PostRequestURL(const WideString & wsURL,const WideString & wsData,const WideString & wsContentType,const WideString & wsEncode,const WideString & wsHeader)550*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_FormFillEnvironment::PostRequestURL(
551*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsURL,
552*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsData,
553*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsContentType,
554*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsEncode,
555*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsHeader) {
556*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_PostRequestURL)
557*3ac0a46fSAndroid Build Coastguard Worker return WideString();
558*3ac0a46fSAndroid Build Coastguard Worker
559*3ac0a46fSAndroid Build Coastguard Worker ByteString bsURL = wsURL.ToUTF16LE();
560*3ac0a46fSAndroid Build Coastguard Worker ByteString bsData = wsData.ToUTF16LE();
561*3ac0a46fSAndroid Build Coastguard Worker ByteString bsContentType = wsContentType.ToUTF16LE();
562*3ac0a46fSAndroid Build Coastguard Worker ByteString bsEncode = wsEncode.ToUTF16LE();
563*3ac0a46fSAndroid Build Coastguard Worker ByteString bsHeader = wsHeader.ToUTF16LE();
564*3ac0a46fSAndroid Build Coastguard Worker
565*3ac0a46fSAndroid Build Coastguard Worker FPDF_BSTR response;
566*3ac0a46fSAndroid Build Coastguard Worker FPDF_BStr_Init(&response);
567*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_PostRequestURL(
568*3ac0a46fSAndroid Build Coastguard Worker m_pInfo, AsFPDFWideString(&bsURL), AsFPDFWideString(&bsData),
569*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsContentType), AsFPDFWideString(&bsEncode),
570*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsHeader), &response);
571*3ac0a46fSAndroid Build Coastguard Worker
572*3ac0a46fSAndroid Build Coastguard Worker WideString wsRet =
573*3ac0a46fSAndroid Build Coastguard Worker WideString::FromUTF16LE(reinterpret_cast<FPDF_WIDESTRING>(response.str),
574*3ac0a46fSAndroid Build Coastguard Worker response.len / sizeof(FPDF_WCHAR));
575*3ac0a46fSAndroid Build Coastguard Worker
576*3ac0a46fSAndroid Build Coastguard Worker FPDF_BStr_Clear(&response);
577*3ac0a46fSAndroid Build Coastguard Worker return wsRet;
578*3ac0a46fSAndroid Build Coastguard Worker }
579*3ac0a46fSAndroid Build Coastguard Worker
PutRequestURL(const WideString & wsURL,const WideString & wsData,const WideString & wsEncode)580*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL CPDFSDK_FormFillEnvironment::PutRequestURL(
581*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsURL,
582*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsData,
583*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsEncode) {
584*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_PutRequestURL)
585*3ac0a46fSAndroid Build Coastguard Worker return false;
586*3ac0a46fSAndroid Build Coastguard Worker
587*3ac0a46fSAndroid Build Coastguard Worker ByteString bsURL = wsURL.ToUTF16LE();
588*3ac0a46fSAndroid Build Coastguard Worker ByteString bsData = wsData.ToUTF16LE();
589*3ac0a46fSAndroid Build Coastguard Worker ByteString bsEncode = wsEncode.ToUTF16LE();
590*3ac0a46fSAndroid Build Coastguard Worker
591*3ac0a46fSAndroid Build Coastguard Worker return m_pInfo->FFI_PutRequestURL(m_pInfo, AsFPDFWideString(&bsURL),
592*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsData),
593*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsEncode));
594*3ac0a46fSAndroid Build Coastguard Worker }
595*3ac0a46fSAndroid Build Coastguard Worker
PageEvent(int iPageCount,uint32_t dwEventType) const596*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount,
597*3ac0a46fSAndroid Build Coastguard Worker uint32_t dwEventType) const {
598*3ac0a46fSAndroid Build Coastguard Worker if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_PageEvent)
599*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType);
600*3ac0a46fSAndroid Build Coastguard Worker }
601*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
602*3ac0a46fSAndroid Build Coastguard Worker
ClearAllFocusedAnnots()603*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() {
604*3ac0a46fSAndroid Build Coastguard Worker for (auto& it : m_PageMap) {
605*3ac0a46fSAndroid Build Coastguard Worker if (it.second->IsValidSDKAnnot(GetFocusAnnot())) {
606*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_PageView> pObserved(it.second.get());
607*3ac0a46fSAndroid Build Coastguard Worker KillFocusAnnot({});
608*3ac0a46fSAndroid Build Coastguard Worker if (!pObserved)
609*3ac0a46fSAndroid Build Coastguard Worker break;
610*3ac0a46fSAndroid Build Coastguard Worker }
611*3ac0a46fSAndroid Build Coastguard Worker }
612*3ac0a46fSAndroid Build Coastguard Worker }
613*3ac0a46fSAndroid Build Coastguard Worker
GetOrCreatePageView(IPDF_Page * pUnderlyingPage)614*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetOrCreatePageView(
615*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pUnderlyingPage) {
616*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pExisting = GetPageView(pUnderlyingPage);
617*3ac0a46fSAndroid Build Coastguard Worker if (pExisting)
618*3ac0a46fSAndroid Build Coastguard Worker return pExisting;
619*3ac0a46fSAndroid Build Coastguard Worker
620*3ac0a46fSAndroid Build Coastguard Worker auto pNew = std::make_unique<CPDFSDK_PageView>(this, pUnderlyingPage);
621*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pPageView = pNew.get();
622*3ac0a46fSAndroid Build Coastguard Worker m_PageMap[pUnderlyingPage] = std::move(pNew);
623*3ac0a46fSAndroid Build Coastguard Worker
624*3ac0a46fSAndroid Build Coastguard Worker // Delay to load all the annotations, to avoid endless loop.
625*3ac0a46fSAndroid Build Coastguard Worker pPageView->LoadFXAnnots();
626*3ac0a46fSAndroid Build Coastguard Worker return pPageView;
627*3ac0a46fSAndroid Build Coastguard Worker }
628*3ac0a46fSAndroid Build Coastguard Worker
GetPageView(IPDF_Page * pUnderlyingPage)629*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(
630*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pUnderlyingPage) {
631*3ac0a46fSAndroid Build Coastguard Worker auto it = m_PageMap.find(pUnderlyingPage);
632*3ac0a46fSAndroid Build Coastguard Worker return it != m_PageMap.end() ? it->second.get() : nullptr;
633*3ac0a46fSAndroid Build Coastguard Worker }
634*3ac0a46fSAndroid Build Coastguard Worker
GetTimerHandler()635*3ac0a46fSAndroid Build Coastguard Worker CFX_Timer::HandlerIface* CPDFSDK_FormFillEnvironment::GetTimerHandler() {
636*3ac0a46fSAndroid Build Coastguard Worker return this;
637*3ac0a46fSAndroid Build Coastguard Worker }
638*3ac0a46fSAndroid Build Coastguard Worker
GetPageViewAtIndex(int nIndex)639*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageViewAtIndex(int nIndex) {
640*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pTempPage = GetPage(nIndex);
641*3ac0a46fSAndroid Build Coastguard Worker return pTempPage ? GetPageView(pTempPage) : nullptr;
642*3ac0a46fSAndroid Build Coastguard Worker }
643*3ac0a46fSAndroid Build Coastguard Worker
ProcJavascriptAction()644*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::ProcJavascriptAction() {
645*3ac0a46fSAndroid Build Coastguard Worker auto name_tree = CPDF_NameTree::Create(m_pCPDFDoc, "JavaScript");
646*3ac0a46fSAndroid Build Coastguard Worker if (!name_tree)
647*3ac0a46fSAndroid Build Coastguard Worker return;
648*3ac0a46fSAndroid Build Coastguard Worker
649*3ac0a46fSAndroid Build Coastguard Worker size_t count = name_tree->GetCount();
650*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < count; ++i) {
651*3ac0a46fSAndroid Build Coastguard Worker WideString name;
652*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action(ToDictionary(name_tree->LookupValueAndName(i, &name)));
653*3ac0a46fSAndroid Build Coastguard Worker DoActionJavaScript(action, name);
654*3ac0a46fSAndroid Build Coastguard Worker }
655*3ac0a46fSAndroid Build Coastguard Worker }
656*3ac0a46fSAndroid Build Coastguard Worker
ProcOpenAction()657*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::ProcOpenAction() {
658*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pRoot = m_pCPDFDoc->GetRoot();
659*3ac0a46fSAndroid Build Coastguard Worker if (!pRoot)
660*3ac0a46fSAndroid Build Coastguard Worker return false;
661*3ac0a46fSAndroid Build Coastguard Worker
662*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pOpenAction(pRoot->GetDictFor("OpenAction"));
663*3ac0a46fSAndroid Build Coastguard Worker if (!pOpenAction)
664*3ac0a46fSAndroid Build Coastguard Worker pOpenAction = pRoot->GetArrayFor("OpenAction");
665*3ac0a46fSAndroid Build Coastguard Worker if (!pOpenAction)
666*3ac0a46fSAndroid Build Coastguard Worker return false;
667*3ac0a46fSAndroid Build Coastguard Worker
668*3ac0a46fSAndroid Build Coastguard Worker if (pOpenAction->IsArray())
669*3ac0a46fSAndroid Build Coastguard Worker return true;
670*3ac0a46fSAndroid Build Coastguard Worker
671*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pDict = ToDictionary(pOpenAction);
672*3ac0a46fSAndroid Build Coastguard Worker if (!pDict)
673*3ac0a46fSAndroid Build Coastguard Worker return false;
674*3ac0a46fSAndroid Build Coastguard Worker
675*3ac0a46fSAndroid Build Coastguard Worker DoActionDocOpen(CPDF_Action(std::move(pDict)));
676*3ac0a46fSAndroid Build Coastguard Worker return true;
677*3ac0a46fSAndroid Build Coastguard Worker }
678*3ac0a46fSAndroid Build Coastguard Worker
RemovePageView(IPDF_Page * pUnderlyingPage)679*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::RemovePageView(IPDF_Page* pUnderlyingPage) {
680*3ac0a46fSAndroid Build Coastguard Worker auto it = m_PageMap.find(pUnderlyingPage);
681*3ac0a46fSAndroid Build Coastguard Worker if (it == m_PageMap.end())
682*3ac0a46fSAndroid Build Coastguard Worker return;
683*3ac0a46fSAndroid Build Coastguard Worker
684*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pPageView = it->second.get();
685*3ac0a46fSAndroid Build Coastguard Worker if (pPageView->IsLocked() || pPageView->IsBeingDestroyed())
686*3ac0a46fSAndroid Build Coastguard Worker return;
687*3ac0a46fSAndroid Build Coastguard Worker
688*3ac0a46fSAndroid Build Coastguard Worker // Mark the page view so we do not come into |RemovePageView| a second
689*3ac0a46fSAndroid Build Coastguard Worker // time while we're in the process of removing.
690*3ac0a46fSAndroid Build Coastguard Worker pPageView->SetBeingDestroyed();
691*3ac0a46fSAndroid Build Coastguard Worker
692*3ac0a46fSAndroid Build Coastguard Worker // This must happen before we remove |pPageView| from the map because
693*3ac0a46fSAndroid Build Coastguard Worker // |KillFocusAnnot| can call into the |GetPage| method which will
694*3ac0a46fSAndroid Build Coastguard Worker // look for this page view in the map, if it doesn't find it a new one will
695*3ac0a46fSAndroid Build Coastguard Worker // be created. We then have two page views pointing to the same page and
696*3ac0a46fSAndroid Build Coastguard Worker // bad things happen.
697*3ac0a46fSAndroid Build Coastguard Worker if (pPageView->IsValidSDKAnnot(GetFocusAnnot()))
698*3ac0a46fSAndroid Build Coastguard Worker KillFocusAnnot({});
699*3ac0a46fSAndroid Build Coastguard Worker
700*3ac0a46fSAndroid Build Coastguard Worker // Remove the page from the map to make sure we don't accidentally attempt
701*3ac0a46fSAndroid Build Coastguard Worker // to use the |pPageView| while we're cleaning it up.
702*3ac0a46fSAndroid Build Coastguard Worker m_PageMap.erase(it);
703*3ac0a46fSAndroid Build Coastguard Worker }
704*3ac0a46fSAndroid Build Coastguard Worker
GetPage(int nIndex) const705*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) const {
706*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || !m_pInfo->FFI_GetPage)
707*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
708*3ac0a46fSAndroid Build Coastguard Worker return IPDFPageFromFPDFPage(m_pInfo->FFI_GetPage(
709*3ac0a46fSAndroid Build Coastguard Worker m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc), nIndex));
710*3ac0a46fSAndroid Build Coastguard Worker }
711*3ac0a46fSAndroid Build Coastguard Worker
GetInteractiveForm()712*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* CPDFSDK_FormFillEnvironment::GetInteractiveForm() {
713*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInteractiveForm)
714*3ac0a46fSAndroid Build Coastguard Worker m_pInteractiveForm = std::make_unique<CPDFSDK_InteractiveForm>(this);
715*3ac0a46fSAndroid Build Coastguard Worker return m_pInteractiveForm.get();
716*3ac0a46fSAndroid Build Coastguard Worker }
717*3ac0a46fSAndroid Build Coastguard Worker
UpdateAllViews(CPDFSDK_Annot * pAnnot)718*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_Annot* pAnnot) {
719*3ac0a46fSAndroid Build Coastguard Worker for (const auto& it : m_PageMap) {
720*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_PageView> pObserved(it.second.get());
721*3ac0a46fSAndroid Build Coastguard Worker if (pObserved) {
722*3ac0a46fSAndroid Build Coastguard Worker pObserved->UpdateView(pAnnot);
723*3ac0a46fSAndroid Build Coastguard Worker if (!pObserved)
724*3ac0a46fSAndroid Build Coastguard Worker break;
725*3ac0a46fSAndroid Build Coastguard Worker }
726*3ac0a46fSAndroid Build Coastguard Worker }
727*3ac0a46fSAndroid Build Coastguard Worker }
728*3ac0a46fSAndroid Build Coastguard Worker
GetFocusAnnot() const729*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_FormFillEnvironment::GetFocusAnnot() const {
730*3ac0a46fSAndroid Build Coastguard Worker return m_pFocusAnnot.Get();
731*3ac0a46fSAndroid Build Coastguard Worker }
732*3ac0a46fSAndroid Build Coastguard Worker
SetFocusAnnot(ObservedPtr<CPDFSDK_Annot> & pAnnot)733*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::SetFocusAnnot(
734*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot>& pAnnot) {
735*3ac0a46fSAndroid Build Coastguard Worker if (m_bBeingDestroyed)
736*3ac0a46fSAndroid Build Coastguard Worker return false;
737*3ac0a46fSAndroid Build Coastguard Worker if (m_pFocusAnnot == pAnnot)
738*3ac0a46fSAndroid Build Coastguard Worker return true;
739*3ac0a46fSAndroid Build Coastguard Worker if (m_pFocusAnnot && !KillFocusAnnot({}))
740*3ac0a46fSAndroid Build Coastguard Worker return false;
741*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
742*3ac0a46fSAndroid Build Coastguard Worker return false;
743*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot->GetPageView()->IsValid())
744*3ac0a46fSAndroid Build Coastguard Worker return false;
745*3ac0a46fSAndroid Build Coastguard Worker
746*3ac0a46fSAndroid Build Coastguard Worker if (m_pFocusAnnot)
747*3ac0a46fSAndroid Build Coastguard Worker return false;
748*3ac0a46fSAndroid Build Coastguard Worker
749*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
750*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Widget* pXFAWidget = pAnnot->AsXFAWidget();
751*3ac0a46fSAndroid Build Coastguard Worker if (pXFAWidget && pXFAWidget->OnChangedFocus())
752*3ac0a46fSAndroid Build Coastguard Worker return false;
753*3ac0a46fSAndroid Build Coastguard Worker
754*3ac0a46fSAndroid Build Coastguard Worker // `pAnnot` may be destroyed in `OnChangedFocus()`.
755*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
756*3ac0a46fSAndroid Build Coastguard Worker return false;
757*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
758*3ac0a46fSAndroid Build Coastguard Worker
759*3ac0a46fSAndroid Build Coastguard Worker if (!CPDFSDK_Annot::OnSetFocus(pAnnot, {}))
760*3ac0a46fSAndroid Build Coastguard Worker return false;
761*3ac0a46fSAndroid Build Coastguard Worker if (m_pFocusAnnot)
762*3ac0a46fSAndroid Build Coastguard Worker return false;
763*3ac0a46fSAndroid Build Coastguard Worker
764*3ac0a46fSAndroid Build Coastguard Worker m_pFocusAnnot.Reset(pAnnot.Get());
765*3ac0a46fSAndroid Build Coastguard Worker
766*3ac0a46fSAndroid Build Coastguard Worker // If we are not able to inform the client about the focus change, it
767*3ac0a46fSAndroid Build Coastguard Worker // shouldn't be considered as failure.
768*3ac0a46fSAndroid Build Coastguard Worker SendOnFocusChange(pAnnot);
769*3ac0a46fSAndroid Build Coastguard Worker return true;
770*3ac0a46fSAndroid Build Coastguard Worker }
771*3ac0a46fSAndroid Build Coastguard Worker
KillFocusAnnot(Mask<FWL_EVENTFLAG> nFlags)772*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::KillFocusAnnot(Mask<FWL_EVENTFLAG> nFlags) {
773*3ac0a46fSAndroid Build Coastguard Worker if (!m_pFocusAnnot)
774*3ac0a46fSAndroid Build Coastguard Worker return false;
775*3ac0a46fSAndroid Build Coastguard Worker
776*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pFocusAnnot(m_pFocusAnnot.Get());
777*3ac0a46fSAndroid Build Coastguard Worker m_pFocusAnnot.Reset();
778*3ac0a46fSAndroid Build Coastguard Worker
779*3ac0a46fSAndroid Build Coastguard Worker if (!CPDFSDK_Annot::OnKillFocus(pFocusAnnot, nFlags)) {
780*3ac0a46fSAndroid Build Coastguard Worker m_pFocusAnnot.Reset(pFocusAnnot.Get());
781*3ac0a46fSAndroid Build Coastguard Worker return false;
782*3ac0a46fSAndroid Build Coastguard Worker }
783*3ac0a46fSAndroid Build Coastguard Worker
784*3ac0a46fSAndroid Build Coastguard Worker // Might have been destroyed by OnKillFocus().
785*3ac0a46fSAndroid Build Coastguard Worker if (!pFocusAnnot)
786*3ac0a46fSAndroid Build Coastguard Worker return false;
787*3ac0a46fSAndroid Build Coastguard Worker
788*3ac0a46fSAndroid Build Coastguard Worker if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) {
789*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pFocusAnnot.Get());
790*3ac0a46fSAndroid Build Coastguard Worker FormFieldType fieldType = pWidget->GetFieldType();
791*3ac0a46fSAndroid Build Coastguard Worker if (fieldType == FormFieldType::kTextField ||
792*3ac0a46fSAndroid Build Coastguard Worker fieldType == FormFieldType::kComboBox) {
793*3ac0a46fSAndroid Build Coastguard Worker OnSetFieldInputFocusInternal(WideString(), false);
794*3ac0a46fSAndroid Build Coastguard Worker }
795*3ac0a46fSAndroid Build Coastguard Worker }
796*3ac0a46fSAndroid Build Coastguard Worker return !m_pFocusAnnot;
797*3ac0a46fSAndroid Build Coastguard Worker }
798*3ac0a46fSAndroid Build Coastguard Worker
GetPageCount() const799*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_FormFillEnvironment::GetPageCount() const {
800*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document::Extension* pExtension = m_pCPDFDoc->GetExtension();
801*3ac0a46fSAndroid Build Coastguard Worker return pExtension ? pExtension->GetPageCount() : m_pCPDFDoc->GetPageCount();
802*3ac0a46fSAndroid Build Coastguard Worker }
803*3ac0a46fSAndroid Build Coastguard Worker
HasPermissions(uint32_t flags) const804*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::HasPermissions(uint32_t flags) const {
805*3ac0a46fSAndroid Build Coastguard Worker return !!(m_pCPDFDoc->GetUserPermissions() & flags);
806*3ac0a46fSAndroid Build Coastguard Worker }
807*3ac0a46fSAndroid Build Coastguard Worker
SendOnFocusChange(ObservedPtr<CPDFSDK_Annot> & pAnnot)808*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::SendOnFocusChange(
809*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot>& pAnnot) {
810*3ac0a46fSAndroid Build Coastguard Worker if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_OnFocusChange)
811*3ac0a46fSAndroid Build Coastguard Worker return;
812*3ac0a46fSAndroid Build Coastguard Worker
813*3ac0a46fSAndroid Build Coastguard Worker // TODO(crbug.com/pdfium/1482): Handle XFA case.
814*3ac0a46fSAndroid Build Coastguard Worker if (pAnnot->AsXFAWidget())
815*3ac0a46fSAndroid Build Coastguard Worker return;
816*3ac0a46fSAndroid Build Coastguard Worker
817*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
818*3ac0a46fSAndroid Build Coastguard Worker if (!pPageView->IsValid())
819*3ac0a46fSAndroid Build Coastguard Worker return;
820*3ac0a46fSAndroid Build Coastguard Worker
821*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* page = pAnnot->GetPage();
822*3ac0a46fSAndroid Build Coastguard Worker if (!page)
823*3ac0a46fSAndroid Build Coastguard Worker return;
824*3ac0a46fSAndroid Build Coastguard Worker
825*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDF_Dictionary> annot_dict =
826*3ac0a46fSAndroid Build Coastguard Worker pAnnot->GetPDFAnnot()->GetMutableAnnotDict();
827*3ac0a46fSAndroid Build Coastguard Worker auto focused_annot = std::make_unique<CPDF_AnnotContext>(annot_dict, page);
828*3ac0a46fSAndroid Build Coastguard Worker FPDF_ANNOTATION fpdf_annot =
829*3ac0a46fSAndroid Build Coastguard Worker FPDFAnnotationFromCPDFAnnotContext(focused_annot.get());
830*3ac0a46fSAndroid Build Coastguard Worker
831*3ac0a46fSAndroid Build Coastguard Worker m_pInfo->FFI_OnFocusChange(m_pInfo, fpdf_annot, pPageView->GetPageIndex());
832*3ac0a46fSAndroid Build Coastguard Worker }
833*3ac0a46fSAndroid Build Coastguard Worker
DoActionDocOpen(const CPDF_Action & action)834*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionDocOpen(const CPDF_Action& action) {
835*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*> visited;
836*3ac0a46fSAndroid Build Coastguard Worker return ExecuteDocumentOpenAction(action, &visited);
837*3ac0a46fSAndroid Build Coastguard Worker }
838*3ac0a46fSAndroid Build Coastguard Worker
DoActionJavaScript(const CPDF_Action & JsAction,WideString csJSName)839*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionJavaScript(
840*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& JsAction,
841*3ac0a46fSAndroid Build Coastguard Worker WideString csJSName) {
842*3ac0a46fSAndroid Build Coastguard Worker if (JsAction.GetType() == CPDF_Action::Type::kJavaScript) {
843*3ac0a46fSAndroid Build Coastguard Worker WideString swJS = JsAction.GetJavaScript();
844*3ac0a46fSAndroid Build Coastguard Worker if (!swJS.IsEmpty()) {
845*3ac0a46fSAndroid Build Coastguard Worker RunDocumentOpenJavaScript(csJSName, swJS);
846*3ac0a46fSAndroid Build Coastguard Worker return true;
847*3ac0a46fSAndroid Build Coastguard Worker }
848*3ac0a46fSAndroid Build Coastguard Worker }
849*3ac0a46fSAndroid Build Coastguard Worker
850*3ac0a46fSAndroid Build Coastguard Worker return false;
851*3ac0a46fSAndroid Build Coastguard Worker }
852*3ac0a46fSAndroid Build Coastguard Worker
DoActionFieldJavaScript(const CPDF_Action & JsAction,CPDF_AAction::AActionType type,CPDF_FormField * pFormField,CFFL_FieldAction * data)853*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionFieldJavaScript(
854*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& JsAction,
855*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
856*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField,
857*3ac0a46fSAndroid Build Coastguard Worker CFFL_FieldAction* data) {
858*3ac0a46fSAndroid Build Coastguard Worker if (IsJSPlatformPresent() &&
859*3ac0a46fSAndroid Build Coastguard Worker JsAction.GetType() == CPDF_Action::Type::kJavaScript) {
860*3ac0a46fSAndroid Build Coastguard Worker WideString swJS = JsAction.GetJavaScript();
861*3ac0a46fSAndroid Build Coastguard Worker if (!swJS.IsEmpty()) {
862*3ac0a46fSAndroid Build Coastguard Worker RunFieldJavaScript(pFormField, type, data, swJS);
863*3ac0a46fSAndroid Build Coastguard Worker return true;
864*3ac0a46fSAndroid Build Coastguard Worker }
865*3ac0a46fSAndroid Build Coastguard Worker }
866*3ac0a46fSAndroid Build Coastguard Worker return false;
867*3ac0a46fSAndroid Build Coastguard Worker }
868*3ac0a46fSAndroid Build Coastguard Worker
DoActionLink(const CPDF_Action & action,CPDF_AAction::AActionType type,Mask<FWL_EVENTFLAG> modifiers)869*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionLink(const CPDF_Action& action,
870*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
871*3ac0a46fSAndroid Build Coastguard Worker Mask<FWL_EVENTFLAG> modifiers) {
872*3ac0a46fSAndroid Build Coastguard Worker if (!CPDF_AAction::IsUserInput(type))
873*3ac0a46fSAndroid Build Coastguard Worker return false;
874*3ac0a46fSAndroid Build Coastguard Worker
875*3ac0a46fSAndroid Build Coastguard Worker switch (action.GetType()) {
876*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoTo:
877*3ac0a46fSAndroid Build Coastguard Worker DoActionGoTo(action);
878*3ac0a46fSAndroid Build Coastguard Worker return true;
879*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kURI:
880*3ac0a46fSAndroid Build Coastguard Worker DoActionURI(action, modifiers);
881*3ac0a46fSAndroid Build Coastguard Worker return true;
882*3ac0a46fSAndroid Build Coastguard Worker default:
883*3ac0a46fSAndroid Build Coastguard Worker return false;
884*3ac0a46fSAndroid Build Coastguard Worker }
885*3ac0a46fSAndroid Build Coastguard Worker }
886*3ac0a46fSAndroid Build Coastguard Worker
DoActionDestination(const CPDF_Dest & dest)887*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionDestination(const CPDF_Dest& dest) {
888*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* document = GetPDFDocument();
889*3ac0a46fSAndroid Build Coastguard Worker DCHECK(document);
890*3ac0a46fSAndroid Build Coastguard Worker
891*3ac0a46fSAndroid Build Coastguard Worker std::vector<float> positions = dest.GetScrollPositionArray();
892*3ac0a46fSAndroid Build Coastguard Worker DoGoToAction(dest.GetDestPageIndex(document), dest.GetZoomMode(), positions);
893*3ac0a46fSAndroid Build Coastguard Worker return true;
894*3ac0a46fSAndroid Build Coastguard Worker }
895*3ac0a46fSAndroid Build Coastguard Worker
DoActionPage(const CPDF_Action & action,CPDF_AAction::AActionType eType)896*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionPage(
897*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& action,
898*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType eType) {
899*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*> visited;
900*3ac0a46fSAndroid Build Coastguard Worker return ExecuteDocumentPageAction(action, eType, &visited);
901*3ac0a46fSAndroid Build Coastguard Worker }
902*3ac0a46fSAndroid Build Coastguard Worker
DoActionDocument(const CPDF_Action & action,CPDF_AAction::AActionType eType)903*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionDocument(
904*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& action,
905*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType eType) {
906*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*> visited;
907*3ac0a46fSAndroid Build Coastguard Worker return ExecuteDocumentPageAction(action, eType, &visited);
908*3ac0a46fSAndroid Build Coastguard Worker }
909*3ac0a46fSAndroid Build Coastguard Worker
DoActionField(const CPDF_Action & action,CPDF_AAction::AActionType type,CPDF_FormField * pFormField,CFFL_FieldAction * data)910*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionField(const CPDF_Action& action,
911*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
912*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField,
913*3ac0a46fSAndroid Build Coastguard Worker CFFL_FieldAction* data) {
914*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*> visited;
915*3ac0a46fSAndroid Build Coastguard Worker return ExecuteFieldAction(action, type, pFormField, data, &visited);
916*3ac0a46fSAndroid Build Coastguard Worker }
917*3ac0a46fSAndroid Build Coastguard Worker
ExecuteDocumentOpenAction(const CPDF_Action & action,std::set<const CPDF_Dictionary * > * visited)918*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::ExecuteDocumentOpenAction(
919*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& action,
920*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*>* visited) {
921*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pDict = action.GetDict();
922*3ac0a46fSAndroid Build Coastguard Worker if (pdfium::Contains(*visited, pDict))
923*3ac0a46fSAndroid Build Coastguard Worker return false;
924*3ac0a46fSAndroid Build Coastguard Worker
925*3ac0a46fSAndroid Build Coastguard Worker visited->insert(pDict);
926*3ac0a46fSAndroid Build Coastguard Worker
927*3ac0a46fSAndroid Build Coastguard Worker if (action.GetType() == CPDF_Action::Type::kJavaScript) {
928*3ac0a46fSAndroid Build Coastguard Worker if (IsJSPlatformPresent()) {
929*3ac0a46fSAndroid Build Coastguard Worker WideString swJS = action.GetJavaScript();
930*3ac0a46fSAndroid Build Coastguard Worker if (!swJS.IsEmpty())
931*3ac0a46fSAndroid Build Coastguard Worker RunDocumentOpenJavaScript(WideString(), swJS);
932*3ac0a46fSAndroid Build Coastguard Worker }
933*3ac0a46fSAndroid Build Coastguard Worker } else {
934*3ac0a46fSAndroid Build Coastguard Worker DoActionNoJs(action, CPDF_AAction::AActionType::kDocumentOpen);
935*3ac0a46fSAndroid Build Coastguard Worker }
936*3ac0a46fSAndroid Build Coastguard Worker
937*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
938*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action subaction = action.GetSubAction(i);
939*3ac0a46fSAndroid Build Coastguard Worker if (!ExecuteDocumentOpenAction(subaction, visited))
940*3ac0a46fSAndroid Build Coastguard Worker return false;
941*3ac0a46fSAndroid Build Coastguard Worker }
942*3ac0a46fSAndroid Build Coastguard Worker
943*3ac0a46fSAndroid Build Coastguard Worker return true;
944*3ac0a46fSAndroid Build Coastguard Worker }
945*3ac0a46fSAndroid Build Coastguard Worker
ExecuteDocumentPageAction(const CPDF_Action & action,CPDF_AAction::AActionType type,std::set<const CPDF_Dictionary * > * visited)946*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::ExecuteDocumentPageAction(
947*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& action,
948*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
949*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*>* visited) {
950*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pDict = action.GetDict();
951*3ac0a46fSAndroid Build Coastguard Worker if (pdfium::Contains(*visited, pDict))
952*3ac0a46fSAndroid Build Coastguard Worker return false;
953*3ac0a46fSAndroid Build Coastguard Worker
954*3ac0a46fSAndroid Build Coastguard Worker visited->insert(pDict);
955*3ac0a46fSAndroid Build Coastguard Worker
956*3ac0a46fSAndroid Build Coastguard Worker if (action.GetType() == CPDF_Action::Type::kJavaScript) {
957*3ac0a46fSAndroid Build Coastguard Worker if (IsJSPlatformPresent()) {
958*3ac0a46fSAndroid Build Coastguard Worker WideString swJS = action.GetJavaScript();
959*3ac0a46fSAndroid Build Coastguard Worker if (!swJS.IsEmpty())
960*3ac0a46fSAndroid Build Coastguard Worker RunDocumentPageJavaScript(type, swJS);
961*3ac0a46fSAndroid Build Coastguard Worker }
962*3ac0a46fSAndroid Build Coastguard Worker } else {
963*3ac0a46fSAndroid Build Coastguard Worker DoActionNoJs(action, type);
964*3ac0a46fSAndroid Build Coastguard Worker }
965*3ac0a46fSAndroid Build Coastguard Worker
966*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
967*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action subaction = action.GetSubAction(i);
968*3ac0a46fSAndroid Build Coastguard Worker if (!ExecuteDocumentPageAction(subaction, type, visited))
969*3ac0a46fSAndroid Build Coastguard Worker return false;
970*3ac0a46fSAndroid Build Coastguard Worker }
971*3ac0a46fSAndroid Build Coastguard Worker
972*3ac0a46fSAndroid Build Coastguard Worker return true;
973*3ac0a46fSAndroid Build Coastguard Worker }
974*3ac0a46fSAndroid Build Coastguard Worker
IsValidField(const CPDF_Dictionary * pFieldDict)975*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::IsValidField(
976*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pFieldDict) {
977*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pFieldDict);
978*3ac0a46fSAndroid Build Coastguard Worker
979*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* pForm = GetInteractiveForm();
980*3ac0a46fSAndroid Build Coastguard Worker CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
981*3ac0a46fSAndroid Build Coastguard Worker return !!pPDFForm->GetFieldByDict(pFieldDict);
982*3ac0a46fSAndroid Build Coastguard Worker }
983*3ac0a46fSAndroid Build Coastguard Worker
ExecuteFieldAction(const CPDF_Action & action,CPDF_AAction::AActionType type,CPDF_FormField * pFormField,CFFL_FieldAction * data,std::set<const CPDF_Dictionary * > * visited)984*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::ExecuteFieldAction(
985*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& action,
986*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
987*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField,
988*3ac0a46fSAndroid Build Coastguard Worker CFFL_FieldAction* data,
989*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*>* visited) {
990*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pDict = action.GetDict();
991*3ac0a46fSAndroid Build Coastguard Worker if (pdfium::Contains(*visited, pDict))
992*3ac0a46fSAndroid Build Coastguard Worker return false;
993*3ac0a46fSAndroid Build Coastguard Worker
994*3ac0a46fSAndroid Build Coastguard Worker visited->insert(pDict);
995*3ac0a46fSAndroid Build Coastguard Worker
996*3ac0a46fSAndroid Build Coastguard Worker if (action.GetType() == CPDF_Action::Type::kJavaScript) {
997*3ac0a46fSAndroid Build Coastguard Worker if (IsJSPlatformPresent()) {
998*3ac0a46fSAndroid Build Coastguard Worker WideString swJS = action.GetJavaScript();
999*3ac0a46fSAndroid Build Coastguard Worker if (!swJS.IsEmpty()) {
1000*3ac0a46fSAndroid Build Coastguard Worker RunFieldJavaScript(pFormField, type, data, swJS);
1001*3ac0a46fSAndroid Build Coastguard Worker if (!IsValidField(pFormField->GetFieldDict()))
1002*3ac0a46fSAndroid Build Coastguard Worker return false;
1003*3ac0a46fSAndroid Build Coastguard Worker }
1004*3ac0a46fSAndroid Build Coastguard Worker }
1005*3ac0a46fSAndroid Build Coastguard Worker } else {
1006*3ac0a46fSAndroid Build Coastguard Worker DoActionNoJs(action, type);
1007*3ac0a46fSAndroid Build Coastguard Worker }
1008*3ac0a46fSAndroid Build Coastguard Worker
1009*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
1010*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action subaction = action.GetSubAction(i);
1011*3ac0a46fSAndroid Build Coastguard Worker if (!ExecuteFieldAction(subaction, type, pFormField, data, visited))
1012*3ac0a46fSAndroid Build Coastguard Worker return false;
1013*3ac0a46fSAndroid Build Coastguard Worker }
1014*3ac0a46fSAndroid Build Coastguard Worker
1015*3ac0a46fSAndroid Build Coastguard Worker return true;
1016*3ac0a46fSAndroid Build Coastguard Worker }
1017*3ac0a46fSAndroid Build Coastguard Worker
DoActionNoJs(const CPDF_Action & action,CPDF_AAction::AActionType type)1018*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoActionNoJs(const CPDF_Action& action,
1019*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type) {
1020*3ac0a46fSAndroid Build Coastguard Worker switch (action.GetType()) {
1021*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoTo:
1022*3ac0a46fSAndroid Build Coastguard Worker DoActionGoTo(action);
1023*3ac0a46fSAndroid Build Coastguard Worker break;
1024*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kURI:
1025*3ac0a46fSAndroid Build Coastguard Worker if (CPDF_AAction::IsUserInput(type))
1026*3ac0a46fSAndroid Build Coastguard Worker DoActionURI(action, Mask<FWL_EVENTFLAG>{});
1027*3ac0a46fSAndroid Build Coastguard Worker break;
1028*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kHide:
1029*3ac0a46fSAndroid Build Coastguard Worker DoActionHide(action);
1030*3ac0a46fSAndroid Build Coastguard Worker break;
1031*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kNamed:
1032*3ac0a46fSAndroid Build Coastguard Worker DoActionNamed(action);
1033*3ac0a46fSAndroid Build Coastguard Worker break;
1034*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kSubmitForm:
1035*3ac0a46fSAndroid Build Coastguard Worker if (CPDF_AAction::IsUserInput(type))
1036*3ac0a46fSAndroid Build Coastguard Worker DoActionSubmitForm(action);
1037*3ac0a46fSAndroid Build Coastguard Worker break;
1038*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kResetForm:
1039*3ac0a46fSAndroid Build Coastguard Worker DoActionResetForm(action);
1040*3ac0a46fSAndroid Build Coastguard Worker break;
1041*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kJavaScript:
1042*3ac0a46fSAndroid Build Coastguard Worker NOTREACHED_NORETURN();
1043*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kSetOCGState:
1044*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kThread:
1045*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kSound:
1046*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kMovie:
1047*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kRendition:
1048*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kTrans:
1049*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoTo3DView:
1050*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoToR:
1051*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoToE:
1052*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kLaunch:
1053*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kImportData:
1054*3ac0a46fSAndroid Build Coastguard Worker // Unimplemented
1055*3ac0a46fSAndroid Build Coastguard Worker break;
1056*3ac0a46fSAndroid Build Coastguard Worker default:
1057*3ac0a46fSAndroid Build Coastguard Worker break;
1058*3ac0a46fSAndroid Build Coastguard Worker }
1059*3ac0a46fSAndroid Build Coastguard Worker }
1060*3ac0a46fSAndroid Build Coastguard Worker
DoActionGoTo(const CPDF_Action & action)1061*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoActionGoTo(const CPDF_Action& action) {
1062*3ac0a46fSAndroid Build Coastguard Worker DCHECK(action.GetDict());
1063*3ac0a46fSAndroid Build Coastguard Worker
1064*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pPDFDocument = GetPDFDocument();
1065*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pPDFDocument);
1066*3ac0a46fSAndroid Build Coastguard Worker
1067*3ac0a46fSAndroid Build Coastguard Worker CPDF_Dest MyDest = action.GetDest(pPDFDocument);
1068*3ac0a46fSAndroid Build Coastguard Worker DoActionDestination(MyDest);
1069*3ac0a46fSAndroid Build Coastguard Worker }
1070*3ac0a46fSAndroid Build Coastguard Worker
DoActionURI(const CPDF_Action & action,Mask<FWL_EVENTFLAG> modifiers)1071*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoActionURI(const CPDF_Action& action,
1072*3ac0a46fSAndroid Build Coastguard Worker Mask<FWL_EVENTFLAG> modifiers) {
1073*3ac0a46fSAndroid Build Coastguard Worker DCHECK(action.GetDict());
1074*3ac0a46fSAndroid Build Coastguard Worker DoURIAction(action.GetURI(GetPDFDocument()), modifiers);
1075*3ac0a46fSAndroid Build Coastguard Worker }
1076*3ac0a46fSAndroid Build Coastguard Worker
DoActionNamed(const CPDF_Action & action)1077*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoActionNamed(const CPDF_Action& action) {
1078*3ac0a46fSAndroid Build Coastguard Worker DCHECK(action.GetDict());
1079*3ac0a46fSAndroid Build Coastguard Worker ExecuteNamedAction(action.GetNamedAction());
1080*3ac0a46fSAndroid Build Coastguard Worker }
1081*3ac0a46fSAndroid Build Coastguard Worker
RunFieldJavaScript(CPDF_FormField * pFormField,CPDF_AAction::AActionType type,CFFL_FieldAction * data,const WideString & script)1082*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::RunFieldJavaScript(
1083*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormField* pFormField,
1084*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
1085*3ac0a46fSAndroid Build Coastguard Worker CFFL_FieldAction* data,
1086*3ac0a46fSAndroid Build Coastguard Worker const WideString& script) {
1087*3ac0a46fSAndroid Build Coastguard Worker DCHECK(type != CPDF_AAction::kCalculate);
1088*3ac0a46fSAndroid Build Coastguard Worker DCHECK(type != CPDF_AAction::kFormat);
1089*3ac0a46fSAndroid Build Coastguard Worker
1090*3ac0a46fSAndroid Build Coastguard Worker RunScript(script, [type, data, pFormField](IJS_EventContext* context) {
1091*3ac0a46fSAndroid Build Coastguard Worker switch (type) {
1092*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kCursorEnter:
1093*3ac0a46fSAndroid Build Coastguard Worker context->OnField_MouseEnter(data->bModifier, data->bShift, pFormField);
1094*3ac0a46fSAndroid Build Coastguard Worker break;
1095*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kCursorExit:
1096*3ac0a46fSAndroid Build Coastguard Worker context->OnField_MouseExit(data->bModifier, data->bShift, pFormField);
1097*3ac0a46fSAndroid Build Coastguard Worker break;
1098*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kButtonDown:
1099*3ac0a46fSAndroid Build Coastguard Worker context->OnField_MouseDown(data->bModifier, data->bShift, pFormField);
1100*3ac0a46fSAndroid Build Coastguard Worker break;
1101*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kButtonUp:
1102*3ac0a46fSAndroid Build Coastguard Worker context->OnField_MouseUp(data->bModifier, data->bShift, pFormField);
1103*3ac0a46fSAndroid Build Coastguard Worker break;
1104*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kGetFocus:
1105*3ac0a46fSAndroid Build Coastguard Worker context->OnField_Focus(data->bModifier, data->bShift, pFormField,
1106*3ac0a46fSAndroid Build Coastguard Worker &data->sValue);
1107*3ac0a46fSAndroid Build Coastguard Worker break;
1108*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kLoseFocus:
1109*3ac0a46fSAndroid Build Coastguard Worker context->OnField_Blur(data->bModifier, data->bShift, pFormField,
1110*3ac0a46fSAndroid Build Coastguard Worker &data->sValue);
1111*3ac0a46fSAndroid Build Coastguard Worker break;
1112*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kKeyStroke:
1113*3ac0a46fSAndroid Build Coastguard Worker context->OnField_Keystroke(
1114*3ac0a46fSAndroid Build Coastguard Worker &data->sChange, data->sChangeEx, data->bKeyDown, data->bModifier,
1115*3ac0a46fSAndroid Build Coastguard Worker &data->nSelEnd, &data->nSelStart, data->bShift, pFormField,
1116*3ac0a46fSAndroid Build Coastguard Worker &data->sValue, data->bWillCommit, data->bFieldFull, &data->bRC);
1117*3ac0a46fSAndroid Build Coastguard Worker break;
1118*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kValidate:
1119*3ac0a46fSAndroid Build Coastguard Worker context->OnField_Validate(&data->sChange, data->sChangeEx,
1120*3ac0a46fSAndroid Build Coastguard Worker data->bKeyDown, data->bModifier, data->bShift,
1121*3ac0a46fSAndroid Build Coastguard Worker pFormField, &data->sValue, &data->bRC);
1122*3ac0a46fSAndroid Build Coastguard Worker break;
1123*3ac0a46fSAndroid Build Coastguard Worker default:
1124*3ac0a46fSAndroid Build Coastguard Worker NOTREACHED_NORETURN();
1125*3ac0a46fSAndroid Build Coastguard Worker }
1126*3ac0a46fSAndroid Build Coastguard Worker });
1127*3ac0a46fSAndroid Build Coastguard Worker }
1128*3ac0a46fSAndroid Build Coastguard Worker
RunDocumentOpenJavaScript(const WideString & sScriptName,const WideString & script)1129*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::RunDocumentOpenJavaScript(
1130*3ac0a46fSAndroid Build Coastguard Worker const WideString& sScriptName,
1131*3ac0a46fSAndroid Build Coastguard Worker const WideString& script) {
1132*3ac0a46fSAndroid Build Coastguard Worker RunScript(script, [sScriptName](IJS_EventContext* context) {
1133*3ac0a46fSAndroid Build Coastguard Worker context->OnDoc_Open(sScriptName);
1134*3ac0a46fSAndroid Build Coastguard Worker });
1135*3ac0a46fSAndroid Build Coastguard Worker }
1136*3ac0a46fSAndroid Build Coastguard Worker
RunDocumentPageJavaScript(CPDF_AAction::AActionType type,const WideString & script)1137*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::RunDocumentPageJavaScript(
1138*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type,
1139*3ac0a46fSAndroid Build Coastguard Worker const WideString& script) {
1140*3ac0a46fSAndroid Build Coastguard Worker RunScript(script, [type](IJS_EventContext* context) {
1141*3ac0a46fSAndroid Build Coastguard Worker switch (type) {
1142*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kOpenPage:
1143*3ac0a46fSAndroid Build Coastguard Worker context->OnPage_Open();
1144*3ac0a46fSAndroid Build Coastguard Worker break;
1145*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kClosePage:
1146*3ac0a46fSAndroid Build Coastguard Worker context->OnPage_Close();
1147*3ac0a46fSAndroid Build Coastguard Worker break;
1148*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kCloseDocument:
1149*3ac0a46fSAndroid Build Coastguard Worker context->OnDoc_WillClose();
1150*3ac0a46fSAndroid Build Coastguard Worker break;
1151*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kSaveDocument:
1152*3ac0a46fSAndroid Build Coastguard Worker context->OnDoc_WillSave();
1153*3ac0a46fSAndroid Build Coastguard Worker break;
1154*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kDocumentSaved:
1155*3ac0a46fSAndroid Build Coastguard Worker context->OnDoc_DidSave();
1156*3ac0a46fSAndroid Build Coastguard Worker break;
1157*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kPrintDocument:
1158*3ac0a46fSAndroid Build Coastguard Worker context->OnDoc_WillPrint();
1159*3ac0a46fSAndroid Build Coastguard Worker break;
1160*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kDocumentPrinted:
1161*3ac0a46fSAndroid Build Coastguard Worker context->OnDoc_DidPrint();
1162*3ac0a46fSAndroid Build Coastguard Worker break;
1163*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kPageVisible:
1164*3ac0a46fSAndroid Build Coastguard Worker context->OnPage_InView();
1165*3ac0a46fSAndroid Build Coastguard Worker break;
1166*3ac0a46fSAndroid Build Coastguard Worker case CPDF_AAction::kPageInvisible:
1167*3ac0a46fSAndroid Build Coastguard Worker context->OnPage_OutView();
1168*3ac0a46fSAndroid Build Coastguard Worker break;
1169*3ac0a46fSAndroid Build Coastguard Worker default:
1170*3ac0a46fSAndroid Build Coastguard Worker NOTREACHED_NORETURN();
1171*3ac0a46fSAndroid Build Coastguard Worker }
1172*3ac0a46fSAndroid Build Coastguard Worker });
1173*3ac0a46fSAndroid Build Coastguard Worker }
1174*3ac0a46fSAndroid Build Coastguard Worker
DoActionHide(const CPDF_Action & action)1175*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionHide(const CPDF_Action& action) {
1176*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* pForm = GetInteractiveForm();
1177*3ac0a46fSAndroid Build Coastguard Worker if (pForm->DoAction_Hide(action)) {
1178*3ac0a46fSAndroid Build Coastguard Worker SetChangeMark();
1179*3ac0a46fSAndroid Build Coastguard Worker return true;
1180*3ac0a46fSAndroid Build Coastguard Worker }
1181*3ac0a46fSAndroid Build Coastguard Worker return false;
1182*3ac0a46fSAndroid Build Coastguard Worker }
1183*3ac0a46fSAndroid Build Coastguard Worker
DoActionSubmitForm(const CPDF_Action & action)1184*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_FormFillEnvironment::DoActionSubmitForm(
1185*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Action& action) {
1186*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* pForm = GetInteractiveForm();
1187*3ac0a46fSAndroid Build Coastguard Worker return pForm->DoAction_SubmitForm(action);
1188*3ac0a46fSAndroid Build Coastguard Worker }
1189*3ac0a46fSAndroid Build Coastguard Worker
DoActionResetForm(const CPDF_Action & action)1190*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::DoActionResetForm(const CPDF_Action& action) {
1191*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* pForm = GetInteractiveForm();
1192*3ac0a46fSAndroid Build Coastguard Worker pForm->DoAction_ResetForm(action);
1193*3ac0a46fSAndroid Build Coastguard Worker }
1194*3ac0a46fSAndroid Build Coastguard Worker
RunScript(const WideString & script,const RunScriptCallback & cb)1195*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_FormFillEnvironment::RunScript(const WideString& script,
1196*3ac0a46fSAndroid Build Coastguard Worker const RunScriptCallback& cb) {
1197*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime::ScopedEventContext pContext(GetIJSRuntime());
1198*3ac0a46fSAndroid Build Coastguard Worker cb(pContext.Get());
1199*3ac0a46fSAndroid Build Coastguard Worker pContext->RunScript(script);
1200*3ac0a46fSAndroid Build Coastguard Worker // TODO(dsinclair): Return error if RunScript returns a IJS_Runtime::JS_Error.
1201*3ac0a46fSAndroid Build Coastguard Worker }
1202