1// Copyright 2014 PDFium Authors. All rights reserved.
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 "JS_EventHandler.h"
8
9#include "Document.h"
10#include "Field.h"
11#include "JS_Context.h"
12#include "JS_Define.h"
13#include "JS_Object.h"
14#include "JS_Runtime.h"
15#include "JS_Value.h"
16#include "fpdfsdk/include/javascript/IJavaScript.h"
17
18/* ---------------------------- CJS_EventHandler ---------------------------- */
19
20CJS_EventHandler::CJS_EventHandler(CJS_Context* pContext)
21    : m_pJSContext(pContext),
22      m_eEventType(JET_UNKNOWN),
23      m_bValid(FALSE),
24      m_pWideStrChange(NULL),
25      m_nCommitKey(-1),
26      m_bKeyDown(FALSE),
27      m_bModifier(FALSE),
28      m_bShift(FALSE),
29      m_pISelEnd(NULL),
30      m_nSelEndDu(0),
31      m_pISelStart(NULL),
32      m_nSelStartDu(0),
33      m_bWillCommit(FALSE),
34      m_pValue(NULL),
35      m_bFieldFull(FALSE),
36      m_pbRc(NULL),
37      m_bRcDu(FALSE),
38      m_pSourceDoc(NULL),
39      m_pTargetBookMark(NULL),
40      m_pTargetDoc(NULL),
41      m_pTargetAnnot(NULL) {}
42
43CJS_EventHandler::~CJS_EventHandler() {}
44
45void CJS_EventHandler::OnApp_Init() {
46  Initial(JET_APP_INIT);
47}
48
49void CJS_EventHandler::OnDoc_Open(CPDFSDK_Document* pDoc,
50                                  const CFX_WideString& strTargetName) {
51  Initial(JET_DOC_OPEN);
52
53  m_pTargetDoc = pDoc;
54  m_strTargetName = strTargetName;
55}
56
57void CJS_EventHandler::OnDoc_WillPrint(CPDFSDK_Document* pDoc) {
58  Initial(JET_DOC_WILLPRINT);
59
60  m_pTargetDoc = pDoc;
61}
62
63void CJS_EventHandler::OnDoc_DidPrint(CPDFSDK_Document* pDoc) {
64  Initial(JET_DOC_DIDPRINT);
65
66  m_pTargetDoc = pDoc;
67}
68
69void CJS_EventHandler::OnDoc_WillSave(CPDFSDK_Document* pDoc) {
70  Initial(JET_DOC_WILLSAVE);
71  m_pTargetDoc = pDoc;
72}
73
74void CJS_EventHandler::OnDoc_DidSave(CPDFSDK_Document* pDoc) {
75  Initial(JET_DOC_DIDSAVE);
76
77  m_pTargetDoc = pDoc;
78}
79
80void CJS_EventHandler::OnDoc_WillClose(CPDFSDK_Document* pDoc) {
81  Initial(JET_DOC_WILLCLOSE);
82
83  m_pTargetDoc = pDoc;
84}
85
86void CJS_EventHandler::OnPage_Open(CPDFSDK_Document* pDoc) {
87  Initial(JET_PAGE_OPEN);
88
89  m_pTargetDoc = pDoc;
90}
91
92void CJS_EventHandler::OnPage_Close(CPDFSDK_Document* pDoc) {
93  Initial(JET_PAGE_CLOSE);
94
95  m_pTargetDoc = pDoc;
96}
97
98void CJS_EventHandler::OnPage_InView(CPDFSDK_Document* pDoc) {
99  Initial(JET_PAGE_INVIEW);
100
101  m_pTargetDoc = pDoc;
102}
103
104void CJS_EventHandler::OnPage_OutView(CPDFSDK_Document* pDoc) {
105  Initial(JET_PAGE_OUTVIEW);
106
107  m_pTargetDoc = pDoc;
108}
109
110void CJS_EventHandler::OnField_MouseEnter(FX_BOOL bModifier,
111                                          FX_BOOL bShift,
112                                          CPDF_FormField* pTarget) {
113  Initial(JET_FIELD_MOUSEENTER);
114
115  m_bModifier = bModifier;
116  m_bShift = bShift;
117
118  m_strTargetName = pTarget->GetFullName();
119}
120
121void CJS_EventHandler::OnField_MouseExit(FX_BOOL bModifier,
122                                         FX_BOOL bShift,
123                                         CPDF_FormField* pTarget) {
124  Initial(JET_FIELD_MOUSEEXIT);
125
126  m_bModifier = bModifier;
127  m_bShift = bShift;
128  m_strTargetName = pTarget->GetFullName();
129}
130
131void CJS_EventHandler::OnField_MouseDown(FX_BOOL bModifier,
132                                         FX_BOOL bShift,
133                                         CPDF_FormField* pTarget) {
134  Initial(JET_FIELD_MOUSEDOWN);
135  m_eEventType = JET_FIELD_MOUSEDOWN;
136
137  m_bModifier = bModifier;
138  m_bShift = bShift;
139  m_strTargetName = pTarget->GetFullName();
140}
141
142void CJS_EventHandler::OnField_MouseUp(FX_BOOL bModifier,
143                                       FX_BOOL bShift,
144                                       CPDF_FormField* pTarget) {
145  Initial(JET_FIELD_MOUSEUP);
146
147  m_bModifier = bModifier;
148  m_bShift = bShift;
149  m_strTargetName = pTarget->GetFullName();
150}
151
152void CJS_EventHandler::OnField_Focus(FX_BOOL bModifier,
153                                     FX_BOOL bShift,
154                                     CPDF_FormField* pTarget,
155                                     const CFX_WideString& Value) {
156  Initial(JET_FIELD_FOCUS);
157
158  m_bModifier = bModifier;
159  m_bShift = bShift;
160  m_strTargetName = pTarget->GetFullName();
161  m_pValue = (CFX_WideString*)&Value;
162}
163
164void CJS_EventHandler::OnField_Blur(FX_BOOL bModifier,
165                                    FX_BOOL bShift,
166                                    CPDF_FormField* pTarget,
167                                    const CFX_WideString& Value) {
168  Initial(JET_FIELD_BLUR);
169
170  m_bModifier = bModifier;
171  m_bShift = bShift;
172  m_strTargetName = pTarget->GetFullName();
173  m_pValue = (CFX_WideString*)&Value;
174}
175
176void CJS_EventHandler::OnField_Keystroke(CFX_WideString& strChange,
177                                         const CFX_WideString& strChangeEx,
178                                         FX_BOOL KeyDown,
179                                         FX_BOOL bModifier,
180                                         int& nSelEnd,
181                                         int& nSelStart,
182                                         FX_BOOL bShift,
183                                         CPDF_FormField* pTarget,
184                                         CFX_WideString& Value,
185                                         FX_BOOL bWillCommit,
186                                         FX_BOOL bFieldFull,
187                                         FX_BOOL& bRc) {
188  Initial(JET_FIELD_KEYSTROKE);
189
190  m_nCommitKey = 0;
191  m_pWideStrChange = &strChange;
192  m_WideStrChangeEx = strChangeEx;
193  m_bKeyDown = KeyDown;
194  m_bModifier = bModifier;
195  m_pISelEnd = &nSelEnd;
196  m_pISelStart = &nSelStart;
197  m_bShift = bShift;
198  m_strTargetName = pTarget->GetFullName();
199  m_pValue = &Value;
200  m_bWillCommit = bWillCommit;
201  m_pbRc = &bRc;
202  m_bFieldFull = bFieldFull;
203}
204
205void CJS_EventHandler::OnField_Validate(CFX_WideString& strChange,
206                                        const CFX_WideString& strChangeEx,
207                                        FX_BOOL bKeyDown,
208                                        FX_BOOL bModifier,
209                                        FX_BOOL bShift,
210                                        CPDF_FormField* pTarget,
211                                        CFX_WideString& Value,
212                                        FX_BOOL& bRc) {
213  Initial(JET_FIELD_VALIDATE);
214
215  m_pWideStrChange = &strChange;
216  m_WideStrChangeEx = strChangeEx;
217  m_bKeyDown = bKeyDown;
218  m_bModifier = bModifier;
219  m_bShift = bShift;
220  m_strTargetName = pTarget->GetFullName();
221  m_pValue = &Value;
222  m_pbRc = &bRc;
223}
224
225void CJS_EventHandler::OnField_Calculate(CPDF_FormField* pSource,
226                                         CPDF_FormField* pTarget,
227                                         CFX_WideString& Value,
228                                         FX_BOOL& bRc) {
229  Initial(JET_FIELD_CALCULATE);
230
231  if (pSource)
232    m_strSourceName = pSource->GetFullName();
233  m_strTargetName = pTarget->GetFullName();
234  m_pValue = &Value;
235  m_pbRc = &bRc;
236}
237
238void CJS_EventHandler::OnField_Format(CPDF_FormField* pTarget,
239                                      CFX_WideString& Value,
240                                      FX_BOOL bWillCommit) {
241  Initial(JET_FIELD_FORMAT);
242
243  m_nCommitKey = 0;
244  m_strTargetName = pTarget->GetFullName();
245  m_pValue = &Value;
246  m_bWillCommit = bWillCommit;
247}
248
249void CJS_EventHandler::OnScreen_Focus(FX_BOOL bModifier,
250                                      FX_BOOL bShift,
251                                      CPDFSDK_Annot* pScreen) {
252  Initial(JET_SCREEN_FOCUS);
253
254  m_bModifier = bModifier;
255  m_bShift = bShift;
256  m_pTargetAnnot = pScreen;
257}
258
259void CJS_EventHandler::OnScreen_Blur(FX_BOOL bModifier,
260                                     FX_BOOL bShift,
261                                     CPDFSDK_Annot* pScreen) {
262  Initial(JET_SCREEN_BLUR);
263
264  m_bModifier = bModifier;
265  m_bShift = bShift;
266  m_pTargetAnnot = pScreen;
267}
268
269void CJS_EventHandler::OnScreen_Open(FX_BOOL bModifier,
270                                     FX_BOOL bShift,
271                                     CPDFSDK_Annot* pScreen) {
272  Initial(JET_SCREEN_OPEN);
273
274  m_bModifier = bModifier;
275  m_bShift = bShift;
276  m_pTargetAnnot = pScreen;
277}
278
279void CJS_EventHandler::OnScreen_Close(FX_BOOL bModifier,
280                                      FX_BOOL bShift,
281                                      CPDFSDK_Annot* pScreen) {
282  Initial(JET_SCREEN_CLOSE);
283
284  m_bModifier = bModifier;
285  m_bShift = bShift;
286  m_pTargetAnnot = pScreen;
287}
288
289void CJS_EventHandler::OnScreen_MouseDown(FX_BOOL bModifier,
290                                          FX_BOOL bShift,
291                                          CPDFSDK_Annot* pScreen) {
292  Initial(JET_SCREEN_MOUSEDOWN);
293
294  m_bModifier = bModifier;
295  m_bShift = bShift;
296  m_pTargetAnnot = pScreen;
297}
298
299void CJS_EventHandler::OnScreen_MouseUp(FX_BOOL bModifier,
300                                        FX_BOOL bShift,
301                                        CPDFSDK_Annot* pScreen) {
302  Initial(JET_SCREEN_MOUSEUP);
303
304  m_bModifier = bModifier;
305  m_bShift = bShift;
306  m_pTargetAnnot = pScreen;
307}
308
309void CJS_EventHandler::OnScreen_MouseEnter(FX_BOOL bModifier,
310                                           FX_BOOL bShift,
311                                           CPDFSDK_Annot* pScreen) {
312  Initial(JET_SCREEN_MOUSEENTER);
313
314  m_bModifier = bModifier;
315  m_bShift = bShift;
316  m_pTargetAnnot = pScreen;
317}
318
319void CJS_EventHandler::OnScreen_MouseExit(FX_BOOL bModifier,
320                                          FX_BOOL bShift,
321                                          CPDFSDK_Annot* pScreen) {
322  Initial(JET_SCREEN_MOUSEEXIT);
323
324  m_bModifier = bModifier;
325  m_bShift = bShift;
326  m_pTargetAnnot = pScreen;
327}
328
329void CJS_EventHandler::OnScreen_InView(FX_BOOL bModifier,
330                                       FX_BOOL bShift,
331                                       CPDFSDK_Annot* pScreen) {
332  Initial(JET_SCREEN_INVIEW);
333
334  m_bModifier = bModifier;
335  m_bShift = bShift;
336  m_pTargetAnnot = pScreen;
337}
338
339void CJS_EventHandler::OnScreen_OutView(FX_BOOL bModifier,
340                                        FX_BOOL bShift,
341                                        CPDFSDK_Annot* pScreen) {
342  Initial(JET_SCREEN_OUTVIEW);
343
344  m_bModifier = bModifier;
345  m_bShift = bShift;
346  m_pTargetAnnot = pScreen;
347}
348
349void CJS_EventHandler::OnLink_MouseUp(CPDFSDK_Document* pTarget) {
350  Initial(JET_LINK_MOUSEUP);
351
352  m_pTargetDoc = pTarget;
353}
354
355void CJS_EventHandler::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
356  Initial(JET_BOOKMARK_MOUSEUP);
357
358  m_pTargetBookMark = pBookMark;
359}
360
361void CJS_EventHandler::OnMenu_Exec(CPDFSDK_Document* pTarget,
362                                   const CFX_WideString& strTargetName) {
363  Initial(JET_MENU_EXEC);
364
365  m_pTargetDoc = pTarget;
366  m_strTargetName = strTargetName;
367}
368
369void CJS_EventHandler::OnExternal_Exec() {
370  Initial(JET_EXTERNAL_EXEC);
371}
372
373void CJS_EventHandler::OnBatchExec(CPDFSDK_Document* pTarget) {
374  Initial(JET_BATCH_EXEC);
375
376  m_pTargetDoc = pTarget;
377}
378
379void CJS_EventHandler::OnConsole_Exec() {
380  Initial(JET_CONSOLE_EXEC);
381}
382
383void CJS_EventHandler::Initial(JS_EVENT_T type) {
384  m_eEventType = type;
385
386  m_strTargetName = L"";
387  m_strSourceName = L"";
388  m_pWideStrChange = NULL;
389  m_WideStrChangeDu = L"";
390  m_WideStrChangeEx = L"";
391  m_nCommitKey = -1;
392  m_bKeyDown = FALSE;
393  m_bModifier = FALSE;
394  m_bShift = FALSE;
395  m_pISelEnd = NULL;
396  m_nSelEndDu = 0;
397  m_pISelStart = NULL;
398  m_nSelStartDu = 0;
399  m_bWillCommit = FALSE;
400  m_pValue = NULL;
401  m_bFieldFull = FALSE;
402  m_pbRc = NULL;
403  m_bRcDu = FALSE;
404
405  m_pSourceDoc = NULL;
406  m_pTargetBookMark = NULL;
407  m_pTargetDoc = NULL;
408  m_pTargetAnnot = NULL;
409
410  m_bValid = TRUE;
411}
412
413void CJS_EventHandler::Destroy() {
414  m_bValid = FALSE;
415}
416
417FX_BOOL CJS_EventHandler::IsValid() {
418  return m_bValid;
419}
420
421CFX_WideString& CJS_EventHandler::Change() {
422  if (m_pWideStrChange) {
423    return *m_pWideStrChange;
424  }
425  return m_WideStrChangeDu;
426}
427
428CFX_WideString CJS_EventHandler::ChangeEx() {
429  return m_WideStrChangeEx;
430}
431
432int CJS_EventHandler::CommitKey() {
433  return m_nCommitKey;
434}
435
436FX_BOOL CJS_EventHandler::FieldFull() {
437  return m_bFieldFull;
438}
439
440FX_BOOL CJS_EventHandler::KeyDown() {
441  return m_bKeyDown;
442}
443
444FX_BOOL CJS_EventHandler::Modifier() {
445  return m_bModifier;
446}
447
448const FX_WCHAR* CJS_EventHandler::Name() {
449  switch (m_eEventType) {
450    case JET_APP_INIT:
451      return L"Init";
452    case JET_BATCH_EXEC:
453      return L"Exec";
454    case JET_BOOKMARK_MOUSEUP:
455      return L"Mouse Up";
456    case JET_CONSOLE_EXEC:
457      return L"Exec";
458    case JET_DOC_DIDPRINT:
459      return L"DidPrint";
460    case JET_DOC_DIDSAVE:
461      return L"DidSave";
462    case JET_DOC_OPEN:
463      return L"Open";
464    case JET_DOC_WILLCLOSE:
465      return L"WillClose";
466    case JET_DOC_WILLPRINT:
467      return L"WillPrint";
468    case JET_DOC_WILLSAVE:
469      return L"WillSave";
470    case JET_EXTERNAL_EXEC:
471      return L"Exec";
472    case JET_FIELD_FOCUS:
473    case JET_SCREEN_FOCUS:
474      return L"Focus";
475    case JET_FIELD_BLUR:
476    case JET_SCREEN_BLUR:
477      return L"Blur";
478    case JET_FIELD_MOUSEDOWN:
479    case JET_SCREEN_MOUSEDOWN:
480      return L"Mouse Down";
481    case JET_FIELD_MOUSEUP:
482    case JET_SCREEN_MOUSEUP:
483      return L"Mouse Up";
484    case JET_FIELD_MOUSEENTER:
485    case JET_SCREEN_MOUSEENTER:
486      return L"Mouse Enter";
487    case JET_FIELD_MOUSEEXIT:
488    case JET_SCREEN_MOUSEEXIT:
489      return L"Mouse Exit";
490    case JET_FIELD_CALCULATE:
491      return L"Calculate";
492    case JET_FIELD_FORMAT:
493      return L"Format";
494    case JET_FIELD_KEYSTROKE:
495      return L"Keystroke";
496    case JET_FIELD_VALIDATE:
497      return L"Validate";
498    case JET_LINK_MOUSEUP:
499      return L"Mouse Up";
500    case JET_MENU_EXEC:
501      return L"Exec";
502    case JET_PAGE_OPEN:
503    case JET_SCREEN_OPEN:
504      return L"Open";
505    case JET_PAGE_CLOSE:
506    case JET_SCREEN_CLOSE:
507      return L"Close";
508    case JET_SCREEN_INVIEW:
509    case JET_PAGE_INVIEW:
510      return L"InView";
511    case JET_PAGE_OUTVIEW:
512    case JET_SCREEN_OUTVIEW:
513      return L"OutView";
514    default:
515      return L"";
516  }
517
518  return L"";
519}
520
521const FX_WCHAR* CJS_EventHandler::Type() {
522  switch (m_eEventType) {
523    case JET_APP_INIT:
524      return L"App";
525    case JET_BATCH_EXEC:
526      return L"Batch";
527    case JET_BOOKMARK_MOUSEUP:
528      return L"BookMark";
529    case JET_CONSOLE_EXEC:
530      return L"Console";
531    case JET_DOC_DIDPRINT:
532    case JET_DOC_DIDSAVE:
533    case JET_DOC_OPEN:
534    case JET_DOC_WILLCLOSE:
535    case JET_DOC_WILLPRINT:
536    case JET_DOC_WILLSAVE:
537      return L"Doc";
538    case JET_EXTERNAL_EXEC:
539      return L"External";
540    case JET_FIELD_BLUR:
541    case JET_FIELD_FOCUS:
542    case JET_FIELD_MOUSEDOWN:
543    case JET_FIELD_MOUSEENTER:
544    case JET_FIELD_MOUSEEXIT:
545    case JET_FIELD_MOUSEUP:
546    case JET_FIELD_CALCULATE:
547    case JET_FIELD_FORMAT:
548    case JET_FIELD_KEYSTROKE:
549    case JET_FIELD_VALIDATE:
550      return L"Field";
551    case JET_SCREEN_FOCUS:
552    case JET_SCREEN_BLUR:
553    case JET_SCREEN_OPEN:
554    case JET_SCREEN_CLOSE:
555    case JET_SCREEN_MOUSEDOWN:
556    case JET_SCREEN_MOUSEUP:
557    case JET_SCREEN_MOUSEENTER:
558    case JET_SCREEN_MOUSEEXIT:
559    case JET_SCREEN_INVIEW:
560    case JET_SCREEN_OUTVIEW:
561      return L"Screen";
562    case JET_LINK_MOUSEUP:
563      return L"Link";
564    case JET_MENU_EXEC:
565      return L"Menu";
566    case JET_PAGE_OPEN:
567    case JET_PAGE_CLOSE:
568    case JET_PAGE_INVIEW:
569    case JET_PAGE_OUTVIEW:
570      return L"Page";
571    default:
572      return L"";
573  }
574
575  return L"";
576}
577
578FX_BOOL& CJS_EventHandler::Rc() {
579  if (m_pbRc) {
580    return *m_pbRc;
581  }
582  return m_bRcDu;
583}
584
585int& CJS_EventHandler::SelEnd() {
586  if (m_pISelEnd) {
587    return *m_pISelEnd;
588  }
589  return m_nSelEndDu;
590}
591
592int& CJS_EventHandler::SelStart() {
593  if (m_pISelStart) {
594    return *m_pISelStart;
595  }
596  return m_nSelStartDu;
597}
598
599FX_BOOL CJS_EventHandler::Shift() {
600  return m_bShift;
601}
602
603Field* CJS_EventHandler::Source() {
604  CJS_Runtime* pRuntime = m_pJSContext->GetJSRuntime();
605  v8::Local<v8::Object> pDocObj = FXJS_NewFxDynamicObj(
606      pRuntime->GetIsolate(), pRuntime, CJS_Document::g_nObjDefnID);
607  ASSERT(!pDocObj.IsEmpty());
608
609  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
610      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
611  ASSERT(!pFieldObj.IsEmpty());
612
613  CJS_Document* pJSDocument =
614      (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pDocObj);
615  Document* pDocument = (Document*)pJSDocument->GetEmbedObject();
616  pDocument->AttachDoc(m_pTargetDoc ? m_pTargetDoc
617                                    : m_pJSContext->GetReaderDocument());
618
619  CJS_Field* pJSField =
620      (CJS_Field*)FXJS_GetPrivate(pRuntime->GetIsolate(), pFieldObj);
621  Field* pField = (Field*)pJSField->GetEmbedObject();
622  pField->AttachField(pDocument, m_strSourceName);
623  return pField;
624}
625
626Field* CJS_EventHandler::Target_Field() {
627  CJS_Runtime* pRuntime = m_pJSContext->GetJSRuntime();
628  v8::Local<v8::Object> pDocObj = FXJS_NewFxDynamicObj(
629      pRuntime->GetIsolate(), pRuntime, CJS_Document::g_nObjDefnID);
630  ASSERT(!pDocObj.IsEmpty());
631
632  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
633      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
634  ASSERT(!pFieldObj.IsEmpty());
635
636  CJS_Document* pJSDocument =
637      (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pDocObj);
638  Document* pDocument = (Document*)pJSDocument->GetEmbedObject();
639  pDocument->AttachDoc(m_pTargetDoc ? m_pTargetDoc
640                                    : m_pJSContext->GetReaderDocument());
641
642  CJS_Field* pJSField =
643      (CJS_Field*)FXJS_GetPrivate(pRuntime->GetIsolate(), pFieldObj);
644  Field* pField = (Field*)pJSField->GetEmbedObject();
645  pField->AttachField(pDocument, m_strTargetName);
646  return pField;
647}
648
649CFX_WideString& CJS_EventHandler::Value() {
650  return *m_pValue;
651}
652
653FX_BOOL CJS_EventHandler::WillCommit() {
654  return m_bWillCommit;
655}
656
657CFX_WideString CJS_EventHandler::TargetName() {
658  return m_strTargetName;
659}
660