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 "fxjs/cjs_event.h"
8 
9 #include "fxjs/cjs_event_context.h"
10 #include "fxjs/cjs_eventrecorder.h"
11 #include "fxjs/cjs_field.h"
12 #include "fxjs/cjs_object.h"
13 #include "fxjs/js_define.h"
14 
15 const JSPropertySpec CJS_Event::PropertySpecs[] = {
16     {"change", get_change_static, set_change_static},
17     {"changeEx", get_change_ex_static, set_change_ex_static},
18     {"commitKey", get_commit_key_static, set_commit_key_static},
19     {"fieldFull", get_field_full_static, set_field_full_static},
20     {"keyDown", get_key_down_static, set_key_down_static},
21     {"modifier", get_modifier_static, set_modifier_static},
22     {"name", get_name_static, set_name_static},
23     {"rc", get_rc_static, set_rc_static},
24     {"richChange", get_rich_change_static, set_rich_change_static},
25     {"richChangeEx", get_rich_change_ex_static, set_rich_change_ex_static},
26     {"richValue", get_rich_value_static, set_rich_value_static},
27     {"selEnd", get_sel_end_static, set_sel_end_static},
28     {"selStart", get_sel_start_static, set_sel_start_static},
29     {"shift", get_shift_static, set_shift_static},
30     {"source", get_source_static, set_source_static},
31     {"target", get_target_static, set_target_static},
32     {"targetName", get_target_name_static, set_target_name_static},
33     {"type", get_type_static, set_type_static},
34     {"value", get_value_static, set_value_static},
35     {"willCommit", get_will_commit_static, set_will_commit_static}};
36 
37 uint32_t CJS_Event::ObjDefnID = 0;
38 const char CJS_Event::kName[] = "event";
39 
40 // static
GetObjDefnID()41 uint32_t CJS_Event::GetObjDefnID() {
42   return ObjDefnID;
43 }
44 
45 // static
DefineJSObjects(CFXJS_Engine * pEngine)46 void CJS_Event::DefineJSObjects(CFXJS_Engine* pEngine) {
47   ObjDefnID = pEngine->DefineObj(CJS_Event::kName, FXJSOBJTYPE_STATIC,
48                                  JSConstructor<CJS_Event>, JSDestructor);
49   DefineProps(pEngine, ObjDefnID, PropertySpecs);
50 }
51 
CJS_Event(v8::Local<v8::Object> pObject,CJS_Runtime * pRuntime)52 CJS_Event::CJS_Event(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime)
53     : CJS_Object(pObject, pRuntime) {}
54 
55 CJS_Event::~CJS_Event() = default;
56 
get_change(CJS_Runtime * pRuntime)57 CJS_Result CJS_Event::get_change(CJS_Runtime* pRuntime) {
58   CJS_EventRecorder* pEvent =
59       pRuntime->GetCurrentEventContext()->GetEventRecorder();
60   return CJS_Result::Success(
61       pRuntime->NewString(pEvent->Change().AsStringView()));
62 }
63 
set_change(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)64 CJS_Result CJS_Event::set_change(CJS_Runtime* pRuntime,
65                                  v8::Local<v8::Value> vp) {
66   CJS_EventRecorder* pEvent =
67       pRuntime->GetCurrentEventContext()->GetEventRecorder();
68 
69   if (vp->IsString()) {
70     WideString& wChange = pEvent->Change();
71     wChange = pRuntime->ToWideString(vp);
72   }
73   return CJS_Result::Success();
74 }
75 
get_change_ex(CJS_Runtime * pRuntime)76 CJS_Result CJS_Event::get_change_ex(CJS_Runtime* pRuntime) {
77   CJS_EventRecorder* pEvent =
78       pRuntime->GetCurrentEventContext()->GetEventRecorder();
79   return CJS_Result::Success(
80       pRuntime->NewString(pEvent->ChangeEx().AsStringView()));
81 }
82 
set_change_ex(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)83 CJS_Result CJS_Event::set_change_ex(CJS_Runtime* pRuntime,
84                                     v8::Local<v8::Value> vp) {
85   return CJS_Result::Failure(JSMessage::kNotSupportedError);
86 }
87 
get_commit_key(CJS_Runtime * pRuntime)88 CJS_Result CJS_Event::get_commit_key(CJS_Runtime* pRuntime) {
89   CJS_EventRecorder* pEvent =
90       pRuntime->GetCurrentEventContext()->GetEventRecorder();
91   return CJS_Result::Success(pRuntime->NewNumber(pEvent->CommitKey()));
92 }
93 
set_commit_key(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)94 CJS_Result CJS_Event::set_commit_key(CJS_Runtime* pRuntime,
95                                      v8::Local<v8::Value> vp) {
96   return CJS_Result::Failure(JSMessage::kNotSupportedError);
97 }
98 
get_field_full(CJS_Runtime * pRuntime)99 CJS_Result CJS_Event::get_field_full(CJS_Runtime* pRuntime) {
100   CJS_EventRecorder* pEvent =
101       pRuntime->GetCurrentEventContext()->GetEventRecorder();
102   if (pEvent->Name() != "Keystroke")
103     return CJS_Result::Failure(L"unrecognized event");
104 
105   return CJS_Result::Success(pRuntime->NewBoolean(pEvent->FieldFull()));
106 }
107 
set_field_full(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)108 CJS_Result CJS_Event::set_field_full(CJS_Runtime* pRuntime,
109                                      v8::Local<v8::Value> vp) {
110   return CJS_Result::Failure(JSMessage::kNotSupportedError);
111 }
112 
get_key_down(CJS_Runtime * pRuntime)113 CJS_Result CJS_Event::get_key_down(CJS_Runtime* pRuntime) {
114   CJS_EventRecorder* pEvent =
115       pRuntime->GetCurrentEventContext()->GetEventRecorder();
116   return CJS_Result::Success(pRuntime->NewBoolean(pEvent->KeyDown()));
117 }
118 
set_key_down(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)119 CJS_Result CJS_Event::set_key_down(CJS_Runtime* pRuntime,
120                                    v8::Local<v8::Value> vp) {
121   return CJS_Result::Failure(JSMessage::kNotSupportedError);
122 }
123 
get_modifier(CJS_Runtime * pRuntime)124 CJS_Result CJS_Event::get_modifier(CJS_Runtime* pRuntime) {
125   CJS_EventRecorder* pEvent =
126       pRuntime->GetCurrentEventContext()->GetEventRecorder();
127   return CJS_Result::Success(pRuntime->NewBoolean(pEvent->Modifier()));
128 }
129 
set_modifier(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)130 CJS_Result CJS_Event::set_modifier(CJS_Runtime* pRuntime,
131                                    v8::Local<v8::Value> vp) {
132   return CJS_Result::Failure(JSMessage::kNotSupportedError);
133 }
134 
get_name(CJS_Runtime * pRuntime)135 CJS_Result CJS_Event::get_name(CJS_Runtime* pRuntime) {
136   CJS_EventRecorder* pEvent =
137       pRuntime->GetCurrentEventContext()->GetEventRecorder();
138   return CJS_Result::Success(pRuntime->NewString(pEvent->Name()));
139 }
140 
set_name(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)141 CJS_Result CJS_Event::set_name(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
142   return CJS_Result::Failure(JSMessage::kNotSupportedError);
143 }
144 
get_rc(CJS_Runtime * pRuntime)145 CJS_Result CJS_Event::get_rc(CJS_Runtime* pRuntime) {
146   CJS_EventRecorder* pEvent =
147       pRuntime->GetCurrentEventContext()->GetEventRecorder();
148   return CJS_Result::Success(pRuntime->NewBoolean(pEvent->Rc()));
149 }
150 
set_rc(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)151 CJS_Result CJS_Event::set_rc(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
152   CJS_EventRecorder* pEvent =
153       pRuntime->GetCurrentEventContext()->GetEventRecorder();
154   pEvent->Rc() = pRuntime->ToBoolean(vp);
155   return CJS_Result::Success();
156 }
157 
get_rich_change(CJS_Runtime * pRuntime)158 CJS_Result CJS_Event::get_rich_change(CJS_Runtime* pRuntime) {
159   return CJS_Result::Success();
160 }
161 
set_rich_change(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)162 CJS_Result CJS_Event::set_rich_change(CJS_Runtime* pRuntime,
163                                       v8::Local<v8::Value> vp) {
164   return CJS_Result::Success();
165 }
166 
get_rich_change_ex(CJS_Runtime * pRuntime)167 CJS_Result CJS_Event::get_rich_change_ex(CJS_Runtime* pRuntime) {
168   return CJS_Result::Success();
169 }
170 
set_rich_change_ex(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)171 CJS_Result CJS_Event::set_rich_change_ex(CJS_Runtime* pRuntime,
172                                          v8::Local<v8::Value> vp) {
173   return CJS_Result::Success();
174 }
175 
get_rich_value(CJS_Runtime * pRuntime)176 CJS_Result CJS_Event::get_rich_value(CJS_Runtime* pRuntime) {
177   return CJS_Result::Success();
178 }
179 
set_rich_value(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)180 CJS_Result CJS_Event::set_rich_value(CJS_Runtime* pRuntime,
181                                      v8::Local<v8::Value> vp) {
182   return CJS_Result::Success();
183 }
184 
get_sel_end(CJS_Runtime * pRuntime)185 CJS_Result CJS_Event::get_sel_end(CJS_Runtime* pRuntime) {
186   CJS_EventRecorder* pEvent =
187       pRuntime->GetCurrentEventContext()->GetEventRecorder();
188   if (pEvent->Name() != "Keystroke")
189     return CJS_Result::Success();
190 
191   return CJS_Result::Success(pRuntime->NewNumber(pEvent->SelEnd()));
192 }
193 
set_sel_end(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)194 CJS_Result CJS_Event::set_sel_end(CJS_Runtime* pRuntime,
195                                   v8::Local<v8::Value> vp) {
196   CJS_EventRecorder* pEvent =
197       pRuntime->GetCurrentEventContext()->GetEventRecorder();
198   if (pEvent->Name() == "Keystroke")
199     pEvent->SetSelEnd(pRuntime->ToInt32(vp));
200 
201   return CJS_Result::Success();
202 }
203 
get_sel_start(CJS_Runtime * pRuntime)204 CJS_Result CJS_Event::get_sel_start(CJS_Runtime* pRuntime) {
205   CJS_EventRecorder* pEvent =
206       pRuntime->GetCurrentEventContext()->GetEventRecorder();
207   if (pEvent->Name() != "Keystroke")
208     return CJS_Result::Success();
209 
210   return CJS_Result::Success(pRuntime->NewNumber(pEvent->SelStart()));
211 }
212 
set_sel_start(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)213 CJS_Result CJS_Event::set_sel_start(CJS_Runtime* pRuntime,
214                                     v8::Local<v8::Value> vp) {
215   CJS_EventRecorder* pEvent =
216       pRuntime->GetCurrentEventContext()->GetEventRecorder();
217   if (pEvent->Name() == "Keystroke")
218     pEvent->SetSelStart(pRuntime->ToInt32(vp));
219 
220   return CJS_Result::Success();
221 }
222 
get_shift(CJS_Runtime * pRuntime)223 CJS_Result CJS_Event::get_shift(CJS_Runtime* pRuntime) {
224   CJS_EventRecorder* pEvent =
225       pRuntime->GetCurrentEventContext()->GetEventRecorder();
226   return CJS_Result::Success(pRuntime->NewBoolean(pEvent->Shift()));
227 }
228 
set_shift(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)229 CJS_Result CJS_Event::set_shift(CJS_Runtime* pRuntime,
230                                 v8::Local<v8::Value> vp) {
231   return CJS_Result::Failure(JSMessage::kNotSupportedError);
232 }
233 
get_source(CJS_Runtime * pRuntime)234 CJS_Result CJS_Event::get_source(CJS_Runtime* pRuntime) {
235   CJS_Field* pField = pRuntime->GetCurrentEventContext()->SourceField();
236   if (!pField)
237     return CJS_Result::Failure(JSMessage::kBadObjectError);
238   return CJS_Result::Success(pField->ToV8Object());
239 }
240 
set_source(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)241 CJS_Result CJS_Event::set_source(CJS_Runtime* pRuntime,
242                                  v8::Local<v8::Value> vp) {
243   return CJS_Result::Failure(JSMessage::kNotSupportedError);
244 }
245 
get_target(CJS_Runtime * pRuntime)246 CJS_Result CJS_Event::get_target(CJS_Runtime* pRuntime) {
247   CJS_Field* pField = pRuntime->GetCurrentEventContext()->TargetField();
248   if (!pField)
249     return CJS_Result::Failure(JSMessage::kBadObjectError);
250   return CJS_Result::Success(pField->ToV8Object());
251 }
252 
set_target(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)253 CJS_Result CJS_Event::set_target(CJS_Runtime* pRuntime,
254                                  v8::Local<v8::Value> vp) {
255   return CJS_Result::Failure(JSMessage::kNotSupportedError);
256 }
257 
get_target_name(CJS_Runtime * pRuntime)258 CJS_Result CJS_Event::get_target_name(CJS_Runtime* pRuntime) {
259   CJS_EventRecorder* pEvent =
260       pRuntime->GetCurrentEventContext()->GetEventRecorder();
261   return CJS_Result::Success(
262       pRuntime->NewString(pEvent->TargetName().AsStringView()));
263 }
264 
set_target_name(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)265 CJS_Result CJS_Event::set_target_name(CJS_Runtime* pRuntime,
266                                       v8::Local<v8::Value> vp) {
267   return CJS_Result::Failure(JSMessage::kNotSupportedError);
268 }
269 
get_type(CJS_Runtime * pRuntime)270 CJS_Result CJS_Event::get_type(CJS_Runtime* pRuntime) {
271   CJS_EventRecorder* pEvent =
272       pRuntime->GetCurrentEventContext()->GetEventRecorder();
273   return CJS_Result::Success(pRuntime->NewString(pEvent->Type()));
274 }
275 
set_type(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)276 CJS_Result CJS_Event::set_type(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
277   return CJS_Result::Failure(JSMessage::kNotSupportedError);
278 }
279 
get_value(CJS_Runtime * pRuntime)280 CJS_Result CJS_Event::get_value(CJS_Runtime* pRuntime) {
281   CJS_EventRecorder* pEvent =
282       pRuntime->GetCurrentEventContext()->GetEventRecorder();
283   if (pEvent->Type() != "Field")
284     return CJS_Result::Failure(L"Bad event type.");
285 
286   if (!pEvent->HasValue())
287     return CJS_Result::Failure(JSMessage::kBadObjectError);
288 
289   return CJS_Result::Success(
290       pRuntime->NewString(pEvent->Value().AsStringView()));
291 }
292 
set_value(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)293 CJS_Result CJS_Event::set_value(CJS_Runtime* pRuntime,
294                                 v8::Local<v8::Value> vp) {
295   CJS_EventRecorder* pEvent =
296       pRuntime->GetCurrentEventContext()->GetEventRecorder();
297   if (pEvent->Type() != "Field")
298     return CJS_Result::Failure(L"Bad event type.");
299 
300   if (!pEvent->HasValue())
301     return CJS_Result::Failure(JSMessage::kBadObjectError);
302 
303   if (vp.IsEmpty())
304     return CJS_Result::Failure(JSMessage::kBadObjectError);
305 
306   if (vp->IsNullOrUndefined() || vp->IsBoolean())
307     return CJS_Result::Failure(JSMessage::kInvalidSetError);
308 
309   pEvent->Value() = pRuntime->ToWideString(vp);
310   return CJS_Result::Success();
311 }
312 
get_will_commit(CJS_Runtime * pRuntime)313 CJS_Result CJS_Event::get_will_commit(CJS_Runtime* pRuntime) {
314   CJS_EventRecorder* pEvent =
315       pRuntime->GetCurrentEventContext()->GetEventRecorder();
316 
317   return CJS_Result::Success(pRuntime->NewBoolean(pEvent->WillCommit()));
318 }
319 
set_will_commit(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)320 CJS_Result CJS_Event::set_will_commit(CJS_Runtime* pRuntime,
321                                       v8::Local<v8::Value> vp) {
322   return CJS_Result::Failure(JSMessage::kNotSupportedError);
323 }
324