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