• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "fxjs/cjs_event_context.h"
8 
9 #include "core/fpdfdoc/cpdf_formfield.h"
10 #include "core/fxcrt/autorestorer.h"
11 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
12 #include "fxjs/cjs_field.h"
13 #include "fxjs/cjs_runtime.h"
14 #include "fxjs/js_define.h"
15 #include "fxjs/js_resources.h"
16 #include "third_party/base/check.h"
17 #include "v8/include/v8-context.h"
18 #include "v8/include/v8-isolate.h"
19 
CJS_EventContext(CJS_Runtime * pRuntime)20 CJS_EventContext::CJS_EventContext(CJS_Runtime* pRuntime)
21     : m_pRuntime(pRuntime), m_pFormFillEnv(pRuntime->GetFormFillEnv()) {}
22 
23 CJS_EventContext::~CJS_EventContext() = default;
24 
RunScript(const WideString & script)25 absl::optional<IJS_Runtime::JS_Error> CJS_EventContext::RunScript(
26     const WideString& script) {
27   v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
28   v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
29   v8::Local<v8::Context> context = m_pRuntime->GetV8Context();
30   v8::Context::Scope context_scope(context);
31 
32   if (m_bBusy) {
33     return IJS_Runtime::JS_Error(1, 1,
34                                  JSGetStringFromID(JSMessage::kBusyError));
35   }
36 
37   AutoRestorer<bool> restorer(&m_bBusy);
38   m_bBusy = true;
39 
40   DCHECK(IsValid());
41   CJS_Runtime::FieldEvent event(TargetName(), EventKind());
42   if (!m_pRuntime->AddEventToSet(event)) {
43     return IJS_Runtime::JS_Error(
44         1, 1, JSGetStringFromID(JSMessage::kDuplicateEventError));
45   }
46 
47   absl::optional<IJS_Runtime::JS_Error> err;
48   if (script.GetLength() > 0)
49     err = m_pRuntime->ExecuteScript(script);
50 
51   m_pRuntime->RemoveEventFromSet(event);
52   Destroy();
53   return err;
54 }
55 
SourceField()56 CJS_Field* CJS_EventContext::SourceField() {
57   v8::Local<v8::Object> pDocObj = m_pRuntime->NewFXJSBoundObject(
58       CJS_Document::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC);
59   if (pDocObj.IsEmpty())
60     return nullptr;
61 
62   v8::Local<v8::Object> pFieldObj = m_pRuntime->NewFXJSBoundObject(
63       CJS_Field::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC);
64   if (pFieldObj.IsEmpty())
65     return nullptr;
66 
67   auto* pFormFillEnv = GetFormFillEnv();
68   auto* pJSDocument = static_cast<CJS_Document*>(
69       CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pDocObj));
70   pJSDocument->SetFormFillEnv(pFormFillEnv);
71 
72   auto* pJSField = static_cast<CJS_Field*>(
73       CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pFieldObj));
74   pJSField->AttachField(pJSDocument, SourceName());
75   return pJSField;
76 }
77 
TargetField()78 CJS_Field* CJS_EventContext::TargetField() {
79   v8::Local<v8::Object> pDocObj = m_pRuntime->NewFXJSBoundObject(
80       CJS_Document::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC);
81   if (pDocObj.IsEmpty())
82     return nullptr;
83 
84   v8::Local<v8::Object> pFieldObj = m_pRuntime->NewFXJSBoundObject(
85       CJS_Field::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC);
86   if (pFieldObj.IsEmpty())
87     return nullptr;
88 
89   auto* pFormFillEnv = GetFormFillEnv();
90   auto* pJSDocument = static_cast<CJS_Document*>(
91       CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pDocObj));
92   pJSDocument->SetFormFillEnv(pFormFillEnv);
93 
94   auto* pJSField = static_cast<CJS_Field*>(
95       CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pFieldObj));
96   pJSField->AttachField(pJSDocument, TargetName());
97   return pJSField;
98 }
99 
OnDoc_Open(const WideString & strTargetName)100 void CJS_EventContext::OnDoc_Open(const WideString& strTargetName) {
101   Initialize(Kind::kDocOpen);
102   m_strTargetName = strTargetName;
103 }
104 
OnDoc_WillPrint()105 void CJS_EventContext::OnDoc_WillPrint() {
106   Initialize(Kind::kDocWillPrint);
107 }
108 
OnDoc_DidPrint()109 void CJS_EventContext::OnDoc_DidPrint() {
110   Initialize(Kind::kDocDidPrint);
111 }
112 
OnDoc_WillSave()113 void CJS_EventContext::OnDoc_WillSave() {
114   Initialize(Kind::kDocWillSave);
115 }
116 
OnDoc_DidSave()117 void CJS_EventContext::OnDoc_DidSave() {
118   Initialize(Kind::kDocDidSave);
119 }
120 
OnDoc_WillClose()121 void CJS_EventContext::OnDoc_WillClose() {
122   Initialize(Kind::kDocWillClose);
123 }
124 
OnPage_Open()125 void CJS_EventContext::OnPage_Open() {
126   Initialize(Kind::kPageOpen);
127 }
128 
OnPage_Close()129 void CJS_EventContext::OnPage_Close() {
130   Initialize(Kind::kPageClose);
131 }
132 
OnPage_InView()133 void CJS_EventContext::OnPage_InView() {
134   Initialize(Kind::kPageInView);
135 }
136 
OnPage_OutView()137 void CJS_EventContext::OnPage_OutView() {
138   Initialize(Kind::kPageOutView);
139 }
140 
OnField_MouseEnter(bool bModifier,bool bShift,CPDF_FormField * pTarget)141 void CJS_EventContext::OnField_MouseEnter(bool bModifier,
142                                           bool bShift,
143                                           CPDF_FormField* pTarget) {
144   Initialize(Kind::kFieldMouseEnter);
145   m_bModifier = bModifier;
146   m_bShift = bShift;
147   m_strTargetName = pTarget->GetFullName();
148 }
149 
OnField_MouseExit(bool bModifier,bool bShift,CPDF_FormField * pTarget)150 void CJS_EventContext::OnField_MouseExit(bool bModifier,
151                                          bool bShift,
152                                          CPDF_FormField* pTarget) {
153   Initialize(Kind::kFieldMouseExit);
154   m_bModifier = bModifier;
155   m_bShift = bShift;
156   m_strTargetName = pTarget->GetFullName();
157 }
158 
OnField_MouseDown(bool bModifier,bool bShift,CPDF_FormField * pTarget)159 void CJS_EventContext::OnField_MouseDown(bool bModifier,
160                                          bool bShift,
161                                          CPDF_FormField* pTarget) {
162   Initialize(Kind::kFieldMouseDown);
163   m_bModifier = bModifier;
164   m_bShift = bShift;
165   m_strTargetName = pTarget->GetFullName();
166 }
167 
OnField_MouseUp(bool bModifier,bool bShift,CPDF_FormField * pTarget)168 void CJS_EventContext::OnField_MouseUp(bool bModifier,
169                                        bool bShift,
170                                        CPDF_FormField* pTarget) {
171   Initialize(Kind::kFieldMouseUp);
172   m_bModifier = bModifier;
173   m_bShift = bShift;
174   m_strTargetName = pTarget->GetFullName();
175 }
176 
OnField_Focus(bool bModifier,bool bShift,CPDF_FormField * pTarget,WideString * pValue)177 void CJS_EventContext::OnField_Focus(bool bModifier,
178                                      bool bShift,
179                                      CPDF_FormField* pTarget,
180                                      WideString* pValue) {
181   DCHECK(pValue);
182   Initialize(Kind::kFieldFocus);
183   m_bModifier = bModifier;
184   m_bShift = bShift;
185   m_strTargetName = pTarget->GetFullName();
186   m_pValue = pValue;
187 }
188 
OnField_Blur(bool bModifier,bool bShift,CPDF_FormField * pTarget,WideString * pValue)189 void CJS_EventContext::OnField_Blur(bool bModifier,
190                                     bool bShift,
191                                     CPDF_FormField* pTarget,
192                                     WideString* pValue) {
193   DCHECK(pValue);
194   Initialize(Kind::kFieldBlur);
195   m_bModifier = bModifier;
196   m_bShift = bShift;
197   m_strTargetName = pTarget->GetFullName();
198   m_pValue = pValue;
199 }
200 
OnField_Keystroke(WideString * strChange,const WideString & strChangeEx,bool KeyDown,bool bModifier,int * pSelEnd,int * pSelStart,bool bShift,CPDF_FormField * pTarget,WideString * pValue,bool bWillCommit,bool bFieldFull,bool * pbRc)201 void CJS_EventContext::OnField_Keystroke(WideString* strChange,
202                                          const WideString& strChangeEx,
203                                          bool KeyDown,
204                                          bool bModifier,
205                                          int* pSelEnd,
206                                          int* pSelStart,
207                                          bool bShift,
208                                          CPDF_FormField* pTarget,
209                                          WideString* pValue,
210                                          bool bWillCommit,
211                                          bool bFieldFull,
212                                          bool* pbRc) {
213   DCHECK(pValue);
214   DCHECK(pbRc);
215   DCHECK(pSelStart);
216   DCHECK(pSelEnd);
217 
218   Initialize(Kind::kFieldKeystroke);
219   m_nCommitKey = 0;
220   m_pWideStrChange = strChange;
221   m_WideStrChangeEx = strChangeEx;
222   m_bKeyDown = KeyDown;
223   m_bModifier = bModifier;
224   m_pISelEnd = pSelEnd;
225   m_pISelStart = pSelStart;
226   m_bShift = bShift;
227   m_strTargetName = pTarget->GetFullName();
228   m_pValue = pValue;
229   m_bWillCommit = bWillCommit;
230   m_pbRc = pbRc;
231   m_bFieldFull = bFieldFull;
232 }
233 
OnField_Validate(WideString * strChange,const WideString & strChangeEx,bool bKeyDown,bool bModifier,bool bShift,CPDF_FormField * pTarget,WideString * pValue,bool * pbRc)234 void CJS_EventContext::OnField_Validate(WideString* strChange,
235                                         const WideString& strChangeEx,
236                                         bool bKeyDown,
237                                         bool bModifier,
238                                         bool bShift,
239                                         CPDF_FormField* pTarget,
240                                         WideString* pValue,
241                                         bool* pbRc) {
242   DCHECK(pValue);
243   DCHECK(pbRc);
244   Initialize(Kind::kFieldValidate);
245   m_pWideStrChange = strChange;
246   m_WideStrChangeEx = strChangeEx;
247   m_bKeyDown = bKeyDown;
248   m_bModifier = bModifier;
249   m_bShift = bShift;
250   m_strTargetName = pTarget->GetFullName();
251   m_pValue = pValue;
252   m_pbRc = pbRc;
253 }
254 
OnField_Calculate(CPDF_FormField * pSource,CPDF_FormField * pTarget,WideString * pValue,bool * pRc)255 void CJS_EventContext::OnField_Calculate(CPDF_FormField* pSource,
256                                          CPDF_FormField* pTarget,
257                                          WideString* pValue,
258                                          bool* pRc) {
259   DCHECK(pValue);
260   DCHECK(pRc);
261   Initialize(Kind::kFieldCalculate);
262   if (pSource)
263     m_strSourceName = pSource->GetFullName();
264   m_strTargetName = pTarget->GetFullName();
265   m_pValue = pValue;
266   m_pbRc = pRc;
267 }
268 
OnField_Format(CPDF_FormField * pTarget,WideString * pValue)269 void CJS_EventContext::OnField_Format(CPDF_FormField* pTarget,
270                                       WideString* pValue) {
271   DCHECK(pValue);
272   Initialize(Kind::kFieldFormat);
273   m_nCommitKey = 0;
274   m_strTargetName = pTarget->GetFullName();
275   m_pValue = pValue;
276   m_bWillCommit = true;
277 }
278 
OnExternal_Exec()279 void CJS_EventContext::OnExternal_Exec() {
280   Initialize(Kind::kExternalExec);
281 }
282 
Initialize(Kind kind)283 void CJS_EventContext::Initialize(Kind kind) {
284   m_eKind = kind;
285   m_strTargetName.clear();
286   m_strSourceName.clear();
287   m_pWideStrChange = nullptr;
288   m_WideStrChangeDu.clear();
289   m_WideStrChangeEx.clear();
290   m_nCommitKey = -1;
291   m_bKeyDown = false;
292   m_bModifier = false;
293   m_bShift = false;
294   m_pISelEnd = nullptr;
295   m_nSelEndDu = 0;
296   m_pISelStart = nullptr;
297   m_nSelStartDu = 0;
298   m_bWillCommit = false;
299   m_pValue = nullptr;
300   m_bFieldFull = false;
301   m_pbRc = nullptr;
302   m_bRcDu = false;
303   m_bValid = true;
304 }
305 
Destroy()306 void CJS_EventContext::Destroy() {
307   m_bValid = false;
308 }
309 
IsUserGesture() const310 bool CJS_EventContext::IsUserGesture() const {
311   switch (m_eKind) {
312     case Kind::kFieldMouseDown:
313     case Kind::kFieldMouseUp:
314     case Kind::kFieldKeystroke:
315       return true;
316     default:
317       return false;
318   }
319 }
320 
Change()321 WideString& CJS_EventContext::Change() {
322   return m_pWideStrChange ? *m_pWideStrChange : m_WideStrChangeDu;
323 }
324 
Name() const325 ByteStringView CJS_EventContext::Name() const {
326   switch (m_eKind) {
327     case Kind::kDocDidPrint:
328       return "DidPrint";
329     case Kind::kDocDidSave:
330       return "DidSave";
331     case Kind::kDocOpen:
332       return "Open";
333     case Kind::kDocWillClose:
334       return "WillClose";
335     case Kind::kDocWillPrint:
336       return "WillPrint";
337     case Kind::kDocWillSave:
338       return "WillSave";
339     case Kind::kExternalExec:
340       return "Exec";
341     case Kind::kFieldFocus:
342       return "Focus";
343     case Kind::kFieldBlur:
344       return "Blur";
345     case Kind::kFieldMouseDown:
346       return "Mouse Down";
347     case Kind::kFieldMouseUp:
348       return "Mouse Up";
349     case Kind::kFieldMouseEnter:
350       return "Mouse Enter";
351     case Kind::kFieldMouseExit:
352       return "Mouse Exit";
353     case Kind::kFieldCalculate:
354       return "Calculate";
355     case Kind::kFieldFormat:
356       return "Format";
357     case Kind::kFieldKeystroke:
358       return "Keystroke";
359     case Kind::kFieldValidate:
360       return "Validate";
361     case Kind::kPageOpen:
362       return "Open";
363     case Kind::kPageClose:
364       return "Close";
365     case Kind::kPageInView:
366       return "InView";
367     case Kind::kPageOutView:
368       return "OutView";
369     default:
370       return "";
371   }
372 }
373 
Type() const374 ByteStringView CJS_EventContext::Type() const {
375   switch (m_eKind) {
376     case Kind::kDocDidPrint:
377     case Kind::kDocDidSave:
378     case Kind::kDocOpen:
379     case Kind::kDocWillClose:
380     case Kind::kDocWillPrint:
381     case Kind::kDocWillSave:
382       return "Doc";
383     case Kind::kExternalExec:
384       return "External";
385     case Kind::kFieldBlur:
386     case Kind::kFieldFocus:
387     case Kind::kFieldMouseDown:
388     case Kind::kFieldMouseUp:
389     case Kind::kFieldMouseEnter:
390     case Kind::kFieldMouseExit:
391     case Kind::kFieldCalculate:
392     case Kind::kFieldFormat:
393     case Kind::kFieldKeystroke:
394     case Kind::kFieldValidate:
395       return "Field";
396     case Kind::kPageOpen:
397     case Kind::kPageClose:
398     case Kind::kPageInView:
399     case Kind::kPageOutView:
400       return "Page";
401     default:
402       return "";
403   }
404 }
405 
Rc()406 bool& CJS_EventContext::Rc() {
407   return m_pbRc ? *m_pbRc : m_bRcDu;
408 }
409 
SelEnd() const410 int CJS_EventContext::SelEnd() const {
411   return m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
412 }
413 
SelStart() const414 int CJS_EventContext::SelStart() const {
415   return m_pISelStart ? *m_pISelStart : m_nSelStartDu;
416 }
417 
SetSelEnd(int value)418 void CJS_EventContext::SetSelEnd(int value) {
419   int& target = m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
420   target = value;
421 }
422 
SetSelStart(int value)423 void CJS_EventContext::SetSelStart(int value) {
424   int& target = m_pISelStart ? *m_pISelStart : m_nSelStartDu;
425   target = value;
426 }
427