• 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/xfa/cjx_eventpseudomodel.h"
8 
9 #include <algorithm>
10 #include <vector>
11 
12 #include "fxjs/fxv8.h"
13 #include "fxjs/xfa/cfxjse_engine.h"
14 #include "third_party/base/notreached.h"
15 #include "third_party/base/numerics/safe_conversions.h"
16 #include "v8/include/v8-primitive.h"
17 #include "xfa/fxfa/cxfa_eventparam.h"
18 #include "xfa/fxfa/cxfa_ffnotify.h"
19 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
20 
21 namespace {
22 
StringProperty(v8::Isolate * pIsolate,v8::Local<v8::Value> * pReturn,WideString * wsValue,bool bSetting)23 void StringProperty(v8::Isolate* pIsolate,
24                     v8::Local<v8::Value>* pReturn,
25                     WideString* wsValue,
26                     bool bSetting) {
27   if (bSetting) {
28     *wsValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pReturn);
29     return;
30   }
31   *pReturn = fxv8::NewStringHelper(pIsolate, wsValue->ToUTF8().AsStringView());
32 }
33 
IntegerProperty(v8::Isolate * pIsolate,v8::Local<v8::Value> * pReturn,int32_t * iValue,bool bSetting)34 void IntegerProperty(v8::Isolate* pIsolate,
35                      v8::Local<v8::Value>* pReturn,
36                      int32_t* iValue,
37                      bool bSetting) {
38   if (bSetting) {
39     *iValue = fxv8::ReentrantToInt32Helper(pIsolate, *pReturn);
40     return;
41   }
42   *pReturn = fxv8::NewNumberHelper(pIsolate, *iValue);
43 }
44 
BooleanProperty(v8::Isolate * pIsolate,v8::Local<v8::Value> * pReturn,bool * bValue,bool bSetting)45 void BooleanProperty(v8::Isolate* pIsolate,
46                      v8::Local<v8::Value>* pReturn,
47                      bool* bValue,
48                      bool bSetting) {
49   if (bSetting) {
50     *bValue = fxv8::ReentrantToBooleanHelper(pIsolate, *pReturn);
51     return;
52   }
53   *pReturn = fxv8::NewBooleanHelper(pIsolate, *bValue);
54 }
55 
56 }  // namespace
57 
58 const CJX_MethodSpec CJX_EventPseudoModel::MethodSpecs[] = {
59     {"emit", emit_static},
60     {"reset", reset_static}};
61 
CJX_EventPseudoModel(CScript_EventPseudoModel * model)62 CJX_EventPseudoModel::CJX_EventPseudoModel(CScript_EventPseudoModel* model)
63     : CJX_Object(model) {
64   DefineMethods(MethodSpecs);
65 }
66 
67 CJX_EventPseudoModel::~CJX_EventPseudoModel() = default;
68 
DynamicTypeIs(TypeTag eType) const69 bool CJX_EventPseudoModel::DynamicTypeIs(TypeTag eType) const {
70   return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
71 }
72 
cancelAction(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)73 void CJX_EventPseudoModel::cancelAction(v8::Isolate* pIsolate,
74                                         v8::Local<v8::Value>* pValue,
75                                         bool bSetting,
76                                         XFA_Attribute eAttribute) {
77   Property(pIsolate, pValue, XFA_Event::CancelAction, bSetting);
78 }
79 
change(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)80 void CJX_EventPseudoModel::change(v8::Isolate* pIsolate,
81                                   v8::Local<v8::Value>* pValue,
82                                   bool bSetting,
83                                   XFA_Attribute eAttribute) {
84   Property(pIsolate, pValue, XFA_Event::Change, bSetting);
85 }
86 
commitKey(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)87 void CJX_EventPseudoModel::commitKey(v8::Isolate* pIsolate,
88                                      v8::Local<v8::Value>* pValue,
89                                      bool bSetting,
90                                      XFA_Attribute eAttribute) {
91   Property(pIsolate, pValue, XFA_Event::CommitKey, bSetting);
92 }
93 
fullText(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)94 void CJX_EventPseudoModel::fullText(v8::Isolate* pIsolate,
95                                     v8::Local<v8::Value>* pValue,
96                                     bool bSetting,
97                                     XFA_Attribute eAttribute) {
98   Property(pIsolate, pValue, XFA_Event::FullText, bSetting);
99 }
100 
keyDown(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)101 void CJX_EventPseudoModel::keyDown(v8::Isolate* pIsolate,
102                                    v8::Local<v8::Value>* pValue,
103                                    bool bSetting,
104                                    XFA_Attribute eAttribute) {
105   Property(pIsolate, pValue, XFA_Event::Keydown, bSetting);
106 }
107 
modifier(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)108 void CJX_EventPseudoModel::modifier(v8::Isolate* pIsolate,
109                                     v8::Local<v8::Value>* pValue,
110                                     bool bSetting,
111                                     XFA_Attribute eAttribute) {
112   Property(pIsolate, pValue, XFA_Event::Modifier, bSetting);
113 }
114 
newContentType(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)115 void CJX_EventPseudoModel::newContentType(v8::Isolate* pIsolate,
116                                           v8::Local<v8::Value>* pValue,
117                                           bool bSetting,
118                                           XFA_Attribute eAttribute) {
119   Property(pIsolate, pValue, XFA_Event::NewContentType, bSetting);
120 }
121 
newText(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)122 void CJX_EventPseudoModel::newText(v8::Isolate* pIsolate,
123                                    v8::Local<v8::Value>* pValue,
124                                    bool bSetting,
125                                    XFA_Attribute eAttribute) {
126   if (bSetting)
127     return;
128 
129   CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
130   CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
131   if (!pEventParam)
132     return;
133 
134   *pValue = fxv8::NewStringHelper(
135       pIsolate, pEventParam->GetNewText().ToUTF8().AsStringView());
136 }
137 
prevContentType(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)138 void CJX_EventPseudoModel::prevContentType(v8::Isolate* pIsolate,
139                                            v8::Local<v8::Value>* pValue,
140                                            bool bSetting,
141                                            XFA_Attribute eAttribute) {
142   Property(pIsolate, pValue, XFA_Event::PreviousContentType, bSetting);
143 }
144 
prevText(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)145 void CJX_EventPseudoModel::prevText(v8::Isolate* pIsolate,
146                                     v8::Local<v8::Value>* pValue,
147                                     bool bSetting,
148                                     XFA_Attribute eAttribute) {
149   Property(pIsolate, pValue, XFA_Event::PreviousText, bSetting);
150 }
151 
reenter(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)152 void CJX_EventPseudoModel::reenter(v8::Isolate* pIsolate,
153                                    v8::Local<v8::Value>* pValue,
154                                    bool bSetting,
155                                    XFA_Attribute eAttribute) {
156   Property(pIsolate, pValue, XFA_Event::Reenter, bSetting);
157 }
158 
selEnd(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)159 void CJX_EventPseudoModel::selEnd(v8::Isolate* pIsolate,
160                                   v8::Local<v8::Value>* pValue,
161                                   bool bSetting,
162                                   XFA_Attribute eAttribute) {
163   Property(pIsolate, pValue, XFA_Event::SelectionEnd, bSetting);
164 }
165 
selStart(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)166 void CJX_EventPseudoModel::selStart(v8::Isolate* pIsolate,
167                                     v8::Local<v8::Value>* pValue,
168                                     bool bSetting,
169                                     XFA_Attribute eAttribute) {
170   Property(pIsolate, pValue, XFA_Event::SelectionStart, bSetting);
171 }
172 
shift(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)173 void CJX_EventPseudoModel::shift(v8::Isolate* pIsolate,
174                                  v8::Local<v8::Value>* pValue,
175                                  bool bSetting,
176                                  XFA_Attribute eAttribute) {
177   Property(pIsolate, pValue, XFA_Event::Shift, bSetting);
178 }
179 
soapFaultCode(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)180 void CJX_EventPseudoModel::soapFaultCode(v8::Isolate* pIsolate,
181                                          v8::Local<v8::Value>* pValue,
182                                          bool bSetting,
183                                          XFA_Attribute eAttribute) {
184   Property(pIsolate, pValue, XFA_Event::SoapFaultCode, bSetting);
185 }
186 
soapFaultString(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)187 void CJX_EventPseudoModel::soapFaultString(v8::Isolate* pIsolate,
188                                            v8::Local<v8::Value>* pValue,
189                                            bool bSetting,
190                                            XFA_Attribute eAttribute) {
191   Property(pIsolate, pValue, XFA_Event::SoapFaultString, bSetting);
192 }
193 
target(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,bool bSetting,XFA_Attribute eAttribute)194 void CJX_EventPseudoModel::target(v8::Isolate* pIsolate,
195                                   v8::Local<v8::Value>* pValue,
196                                   bool bSetting,
197                                   XFA_Attribute eAttribute) {
198   Property(pIsolate, pValue, XFA_Event::Target, bSetting);
199 }
200 
emit(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)201 CJS_Result CJX_EventPseudoModel::emit(
202     CFXJSE_Engine* runtime,
203     const std::vector<v8::Local<v8::Value>>& params) {
204   CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
205   CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
206   if (!pEventParam)
207     return CJS_Result::Success();
208 
209   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
210   if (!pNotify)
211     return CJS_Result::Success();
212 
213   pNotify->HandleWidgetEvent(pScriptContext->GetEventTarget(), pEventParam);
214   return CJS_Result::Success();
215 }
216 
reset(CFXJSE_Engine * runtime,const std::vector<v8::Local<v8::Value>> & params)217 CJS_Result CJX_EventPseudoModel::reset(
218     CFXJSE_Engine* runtime,
219     const std::vector<v8::Local<v8::Value>>& params) {
220   CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
221   CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
222   if (pEventParam)
223     *pEventParam = CXFA_EventParam();
224 
225   return CJS_Result::Success();
226 }
227 
Property(v8::Isolate * pIsolate,v8::Local<v8::Value> * pValue,XFA_Event dwFlag,bool bSetting)228 void CJX_EventPseudoModel::Property(v8::Isolate* pIsolate,
229                                     v8::Local<v8::Value>* pValue,
230                                     XFA_Event dwFlag,
231                                     bool bSetting) {
232   // Only the cancelAction, selStart, selEnd and change properties are writable.
233   if (bSetting && dwFlag != XFA_Event::CancelAction &&
234       dwFlag != XFA_Event::SelectionStart &&
235       dwFlag != XFA_Event::SelectionEnd && dwFlag != XFA_Event::Change) {
236     return;
237   }
238 
239   CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
240   CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
241   if (!pEventParam)
242     return;
243 
244   switch (dwFlag) {
245     case XFA_Event::CancelAction:
246       BooleanProperty(pIsolate, pValue, &pEventParam->m_bCancelAction,
247                       bSetting);
248       break;
249     case XFA_Event::Change:
250       StringProperty(pIsolate, pValue, &pEventParam->m_wsChange, bSetting);
251       break;
252     case XFA_Event::CommitKey:
253       IntegerProperty(pIsolate, pValue, &pEventParam->m_iCommitKey, bSetting);
254       break;
255     case XFA_Event::FullText:
256       StringProperty(pIsolate, pValue, &pEventParam->m_wsFullText, bSetting);
257       break;
258     case XFA_Event::Keydown:
259       BooleanProperty(pIsolate, pValue, &pEventParam->m_bKeyDown, bSetting);
260       break;
261     case XFA_Event::Modifier:
262       BooleanProperty(pIsolate, pValue, &pEventParam->m_bModifier, bSetting);
263       break;
264     case XFA_Event::NewContentType:
265       StringProperty(pIsolate, pValue, &pEventParam->m_wsNewContentType,
266                      bSetting);
267       break;
268     case XFA_Event::NewText:
269       NOTREACHED();
270       break;
271     case XFA_Event::PreviousContentType:
272       StringProperty(pIsolate, pValue, &pEventParam->m_wsPrevContentType,
273                      bSetting);
274       break;
275     case XFA_Event::PreviousText:
276       StringProperty(pIsolate, pValue, &pEventParam->m_wsPrevText, bSetting);
277       break;
278     case XFA_Event::Reenter:
279       BooleanProperty(pIsolate, pValue, &pEventParam->m_bReenter, bSetting);
280       break;
281     case XFA_Event::SelectionEnd:
282       IntegerProperty(pIsolate, pValue, &pEventParam->m_iSelEnd, bSetting);
283 
284       pEventParam->m_iSelEnd = std::max(0, pEventParam->m_iSelEnd);
285       pEventParam->m_iSelEnd = std::min(
286           pEventParam->m_iSelEnd, pdfium::base::checked_cast<int32_t>(
287                                       pEventParam->m_wsPrevText.GetLength()));
288       pEventParam->m_iSelStart =
289           std::min(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
290       break;
291     case XFA_Event::SelectionStart:
292       IntegerProperty(pIsolate, pValue, &pEventParam->m_iSelStart, bSetting);
293       pEventParam->m_iSelStart = std::max(0, pEventParam->m_iSelStart);
294       pEventParam->m_iSelStart = std::min(
295           pEventParam->m_iSelStart, pdfium::base::checked_cast<int32_t>(
296                                         pEventParam->m_wsPrevText.GetLength()));
297       pEventParam->m_iSelEnd =
298           std::max(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
299       break;
300     case XFA_Event::Shift:
301       BooleanProperty(pIsolate, pValue, &pEventParam->m_bShift, bSetting);
302       break;
303     case XFA_Event::SoapFaultCode:
304       StringProperty(pIsolate, pValue, &pEventParam->m_wsSoapFaultCode,
305                      bSetting);
306       break;
307     case XFA_Event::SoapFaultString:
308       StringProperty(pIsolate, pValue, &pEventParam->m_wsSoapFaultString,
309                      bSetting);
310       break;
311     case XFA_Event::Target:
312     default:
313       break;
314   }
315 }
316