blob: 8c00ba593a0678b80ca85a9d0fd918c0bf1e3390 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Tom Sepez37458412015-10-06 11:33:46 -07007#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
8#define FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07009
Tom Sepez37458412015-10-06 11:33:46 -070010#include "../../include/jsapi/fxjs_v8.h"
Tom Sepez3a832662015-03-02 12:59:05 -080011#include "resource.h"
Tom Sepeza1160452015-02-19 10:00:55 -080012#include "JS_Object.h"
13#include "JS_Value.h"
14
Nico Weber9d8ec5a2015-08-04 13:00:21 -070015struct JSConstSpec {
16 const wchar_t* pName;
17 double number;
18 const wchar_t* string;
19 uint8_t t; // 0:double 1:str
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070020};
21
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022struct JSPropertySpec {
23 const wchar_t* pName;
24 v8::AccessorGetterCallback pPropGet;
25 v8::AccessorSetterCallback pPropPut;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026};
27
Nico Weber9d8ec5a2015-08-04 13:00:21 -070028struct JSMethodSpec {
29 const wchar_t* pName;
30 v8::FunctionCallback pMethodCall;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031};
32
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033/* ====================================== PUBLIC DEFINE SPEC
34 * ============================================== */
35#define JS_WIDESTRING(widestring) L## #widestring
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070036
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037#define BEGIN_JS_STATIC_CONST(js_class_name) \
38 JSConstSpec js_class_name::JS_Class_Consts[] = {
39#define JS_STATIC_CONST_ENTRY_NUMBER(const_name, pValue) \
Nico Weber077f1a32015-08-06 15:08:57 -070040 { const_name, pValue, L"", 0 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -070041 ,
Nico Weber077f1a32015-08-06 15:08:57 -070042#define JS_STATIC_CONST_ENTRY_STRING(const_name, pValue) \
43 { const_name, 0, pValue, 1 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 ,
45#define END_JS_STATIC_CONST() \
46 { 0, 0, 0, 0 } \
47 } \
48 ;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050#define BEGIN_JS_STATIC_PROP(js_class_name) \
51 JSPropertySpec js_class_name::JS_Class_Properties[] = {
Tom Sepez37458412015-10-06 11:33:46 -070052#define JS_STATIC_PROP_ENTRY(prop_name) \
53 { \
54 JS_WIDESTRING(prop_name), get_##prop_name##_static, \
55 set_##prop_name##_static \
56 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -070057 ,
58#define END_JS_STATIC_PROP() \
59 { 0, 0, 0 } \
60 } \
61 ;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070062
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063#define BEGIN_JS_STATIC_METHOD(js_class_name) \
64 JSMethodSpec js_class_name::JS_Class_Methods[] = {
65#define JS_STATIC_METHOD_ENTRY(method_name) \
66 { JS_WIDESTRING(method_name), method_name##_static } \
67 ,
68#define END_JS_STATIC_METHOD() \
69 { 0, 0 } \
70 } \
71 ;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073/* ======================================== PROP CALLBACK
74 * ============================================ */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070075
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076template <class C,
77 FX_BOOL (C::*M)(IFXJS_Context*, CJS_PropValue&, CFX_WideString&)>
Tom Sepeza1160452015-02-19 10:00:55 -080078void JSPropGetter(const char* prop_name_string,
79 const char* class_name_string,
80 v8::Local<v8::String> property,
81 const v8::PropertyCallbackInfo<v8::Value>& info) {
82 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -070083 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
84 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -070085 return;
Tom Sepeza25fd092015-09-28 09:06:03 -070086 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepez39bfe122015-09-17 15:25:23 -070087 CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
Tom Sepeza1160452015-02-19 10:00:55 -080088 C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
Tom Sepez3a832662015-03-02 12:59:05 -080089 CFX_WideString sError;
Tom Sepeza25fd092015-09-28 09:06:03 -070090 CJS_PropValue value(isolate);
91 value.StartGetting();
Tom Sepeza1160452015-02-19 10:00:55 -080092 if (!(pObj->*M)(pRuntimeContext, value, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -070093 FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
94 sError));
Tom Sepeza1160452015-02-19 10:00:55 -080095 return;
96 }
Jochen Eisingerdfa2c992015-05-19 00:38:00 +020097 info.GetReturnValue().Set((v8::Local<v8::Value>)value);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100template <class C,
101 FX_BOOL (C::*M)(IFXJS_Context*, CJS_PropValue&, CFX_WideString&)>
Tom Sepeza1160452015-02-19 10:00:55 -0800102void JSPropSetter(const char* prop_name_string,
103 const char* class_name_string,
104 v8::Local<v8::String> property,
105 v8::Local<v8::Value> value,
106 const v8::PropertyCallbackInfo<void>& info) {
107 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700108 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
109 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700110 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700111 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepez39bfe122015-09-17 15:25:23 -0700112 CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
Tom Sepeza1160452015-02-19 10:00:55 -0800113 C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
Tom Sepez3a832662015-03-02 12:59:05 -0800114 CFX_WideString sError;
Tom Sepeza25fd092015-09-28 09:06:03 -0700115 CJS_PropValue propValue(CJS_Value(isolate, value, CJS_Value::VT_unknown));
116 propValue.StartSetting();
Tom Sepeza1160452015-02-19 10:00:55 -0800117 if (!(pObj->*M)(pRuntimeContext, propValue, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700118 FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
119 sError));
Tom Sepeza1160452015-02-19 10:00:55 -0800120 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700121}
122
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123#define JS_STATIC_PROP(prop_name, class_name) \
124 static void get_##prop_name##_static( \
125 v8::Local<v8::String> property, \
126 const v8::PropertyCallbackInfo<v8::Value>& info) { \
127 JSPropGetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
128 property, info); \
129 } \
130 static void set_##prop_name##_static( \
131 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
132 const v8::PropertyCallbackInfo<void>& info) { \
133 JSPropSetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
134 property, value, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800135 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137/* ========================================= METHOD CALLBACK
138 * =========================================== */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140template <class C,
141 FX_BOOL (C::*M)(IFXJS_Context*,
142 const CJS_Parameters&,
143 CJS_Value&,
144 CFX_WideString&)>
Tom Sepeza1160452015-02-19 10:00:55 -0800145void JSMethod(const char* method_name_string,
146 const char* class_name_string,
147 const v8::FunctionCallbackInfo<v8::Value>& info) {
148 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700149 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
150 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700151 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700152 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepeza1160452015-02-19 10:00:55 -0800153 CJS_Parameters parameters;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154 for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700155 parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown));
Tom Sepeza1160452015-02-19 10:00:55 -0800156 }
157 CJS_Value valueRes(isolate);
Tom Sepez39bfe122015-09-17 15:25:23 -0700158 CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
Tom Sepeza1160452015-02-19 10:00:55 -0800159 C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
Tom Sepez3a832662015-03-02 12:59:05 -0800160 CFX_WideString sError;
Tom Sepeza1160452015-02-19 10:00:55 -0800161 if (!(pObj->*M)(pRuntimeContext, parameters, valueRes, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700162 FXJS_Error(isolate, JSFormatErrorString(class_name_string,
163 method_name_string, sError));
Tom Sepeza1160452015-02-19 10:00:55 -0800164 return;
165 }
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700166 info.GetReturnValue().Set(valueRes.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700167}
168
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169#define JS_STATIC_METHOD(method_name, class_name) \
170 static void method_name##_static( \
171 const v8::FunctionCallbackInfo<v8::Value>& info) { \
172 JSMethod<class_name, &class_name::method_name>(#method_name, #class_name, \
173 info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800174 }
175
176#define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name) \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 static void method_name##_static( \
178 const v8::FunctionCallbackInfo<v8::Value>& info) { \
179 JSMethod<class_alternate, &class_alternate::method_name>( \
180 #method_name, #class_name, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800181 }
182
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183/* ===================================== JS CLASS
184 * =============================================== */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700185
Tom Sepez142165e2015-09-11 13:21:50 -0700186#define DECLARE_JS_CLASS(js_class_name) \
187 static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \
188 v8::Local<v8::Object> global); \
189 static void JSDestructor(v8::Local<v8::Object> obj); \
190 static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
191 static JSConstSpec JS_Class_Consts[]; \
192 static JSPropertySpec JS_Class_Properties[]; \
193 static JSMethodSpec JS_Class_Methods[]; \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 static const wchar_t* m_pClassName
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700195
Tom Sepez39bfe122015-09-17 15:25:23 -0700196#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \
197 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \
198 void js_class_name::JSConstructor(IFXJS_Context* cc, \
199 v8::Local<v8::Object> obj, \
200 v8::Local<v8::Object> global) { \
201 CJS_Object* pObj = new js_class_name(obj); \
202 pObj->SetEmbedObject(new class_alternate(pObj)); \
203 FXJS_SetPrivate(NULL, obj, (void*)pObj); \
204 pObj->InitInstance(cc); \
205 } \
206 \
207 void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \
208 js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj); \
209 pObj->ExitInstance(); \
210 delete pObj; \
211 } \
212 \
213 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \
214 FXJSOBJTYPE eObjType) { \
215 int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
216 eObjType, JSConstructor, JSDestructor); \
217 for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \
218 FXJS_DefineObjProperty( \
219 pIsolate, nObjDefnID, JS_Class_Properties[i].pName, \
220 JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \
221 } \
222 for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \
223 FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName, \
224 JS_Class_Methods[i].pMethodCall); \
225 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228#define IMPLEMENT_JS_CLASS(js_class_name, class_name) \
229 IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231/* ======================================== CONST CLASS
232 * ============================================ */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233
Tom Sepez142165e2015-09-11 13:21:50 -0700234#define DECLARE_JS_CLASS_CONST() \
235 static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
236 static JSConstSpec JS_Class_Consts[]; \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237 static const wchar_t* m_pClassName
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238
Tom Sepez39bfe122015-09-17 15:25:23 -0700239#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name) \
240 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \
241 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \
242 FXJSOBJTYPE eObjType) { \
243 int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
244 eObjType, NULL, NULL); \
245 for (int i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \
246 FXJS_DefineObjConst( \
247 pIsolate, nObjDefnID, JS_Class_Consts[i].pName, \
248 JS_Class_Consts[i].t == 0 \
249 ? FXJS_NewNumber(pIsolate, JS_Class_Consts[i].number) \
250 : FXJS_NewString(pIsolate, JS_Class_Consts[i].string)); \
251 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254/* ===================================== SPECIAL JS CLASS
255 * =============================================== */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256
Tom Sepez2311b782015-02-23 10:22:51 -0800257template <class Alt>
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258void JSSpecialPropQuery(const char*,
259 v8::Local<v8::String> property,
260 const v8::PropertyCallbackInfo<v8::Integer>& info) {
Tom Sepez2311b782015-02-23 10:22:51 -0800261 v8::Isolate* isolate = info.GetIsolate();
262 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 CFX_WideString propname =
264 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
265 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700266 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800267 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
268 FX_BOOL bRet = pObj->QueryProperty(propname.c_str());
269 info.GetReturnValue().Set(bRet ? 4 : 0);
270}
271
272template <class Alt>
273void JSSpecialPropGet(const char* class_name,
274 v8::Local<v8::String> property,
275 const v8::PropertyCallbackInfo<v8::Value>& info) {
276 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700277 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
278 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700279 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700280 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700282 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800283 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
284 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 CFX_WideString propname =
286 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
Tom Sepez3a832662015-03-02 12:59:05 -0800287 CFX_WideString sError;
Tom Sepez2311b782015-02-23 10:22:51 -0800288 CJS_PropValue value(isolate);
289 value.StartGetting();
290 if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), value, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700291 FXJS_Error(isolate, JSFormatErrorString(class_name, "GetProperty", sError));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 return;
Tom Sepez2311b782015-02-23 10:22:51 -0800293 }
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200294 info.GetReturnValue().Set((v8::Local<v8::Value>)value);
Tom Sepez2311b782015-02-23 10:22:51 -0800295}
296
297template <class Alt>
298void JSSpecialPropPut(const char* class_name,
299 v8::Local<v8::String> property,
300 v8::Local<v8::Value> value,
301 const v8::PropertyCallbackInfo<v8::Value>& info) {
302 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700303 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
304 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700305 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700306 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700307 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700308 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800309 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
310 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311 CFX_WideString propname =
312 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
Tom Sepez3a832662015-03-02 12:59:05 -0800313 CFX_WideString sError;
Tom Sepez39bfe122015-09-17 15:25:23 -0700314 CJS_PropValue PropValue(CJS_Value(isolate, value, CJS_Value::VT_unknown));
Tom Sepez2311b782015-02-23 10:22:51 -0800315 PropValue.StartSetting();
316 if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), PropValue, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700317 FXJS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
Tom Sepez2311b782015-02-23 10:22:51 -0800318 }
319}
320
321template <class Alt>
322void JSSpecialPropDel(const char* class_name,
323 v8::Local<v8::String> property,
324 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
325 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700326 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
327 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700328 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700329 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700331 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800332 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
333 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334 CFX_WideString propname =
335 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
Tom Sepez3a832662015-03-02 12:59:05 -0800336 CFX_WideString sError;
Tom Sepez2311b782015-02-23 10:22:51 -0800337 if (!pObj->DelProperty(pRuntimeContext, propname.c_str(), sError)) {
338 CFX_ByteString cbName;
339 cbName.Format("%s.%s", class_name, "DelProperty");
Tom Sepez39bfe122015-09-17 15:25:23 -0700340 // Probably a missing call to JSFX_Error().
Tom Sepez2311b782015-02-23 10:22:51 -0800341 }
342}
343
Tom Sepez142165e2015-09-11 13:21:50 -0700344#define DECLARE_SPECIAL_JS_CLASS(js_class_name) \
345 static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \
346 v8::Local<v8::Object> global); \
347 static void JSDestructor(v8::Local<v8::Object> obj); \
348 static JSConstSpec JS_Class_Consts[]; \
349 static JSPropertySpec JS_Class_Properties[]; \
350 static JSMethodSpec JS_Class_Methods[]; \
351 static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
352 static const wchar_t* m_pClassName; \
353 static void queryprop_##js_class_name##_static( \
354 v8::Local<v8::String> property, \
355 const v8::PropertyCallbackInfo<v8::Integer>& info); \
356 static void getprop_##js_class_name##_static( \
357 v8::Local<v8::String> property, \
358 const v8::PropertyCallbackInfo<v8::Value>& info); \
359 static void putprop_##js_class_name##_static( \
360 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
361 const v8::PropertyCallbackInfo<v8::Value>& info); \
362 static void delprop_##js_class_name##_static( \
363 v8::Local<v8::String> property, \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364 const v8::PropertyCallbackInfo<v8::Boolean>& info)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700365
366#define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700367 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \
368 void js_class_name::queryprop_##js_class_name##_static( \
369 v8::Local<v8::String> property, \
370 const v8::PropertyCallbackInfo<v8::Integer>& info) { \
371 JSSpecialPropQuery<class_alternate>(#class_name, property, info); \
372 } \
373 void js_class_name::getprop_##js_class_name##_static( \
374 v8::Local<v8::String> property, \
375 const v8::PropertyCallbackInfo<v8::Value>& info) { \
376 JSSpecialPropGet<class_alternate>(#class_name, property, info); \
377 } \
378 void js_class_name::putprop_##js_class_name##_static( \
379 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
380 const v8::PropertyCallbackInfo<v8::Value>& info) { \
381 JSSpecialPropPut<class_alternate>(#class_name, property, value, info); \
382 } \
383 void js_class_name::delprop_##js_class_name##_static( \
384 v8::Local<v8::String> property, \
385 const v8::PropertyCallbackInfo<v8::Boolean>& info) { \
386 JSSpecialPropDel<class_alternate>(#class_name, property, info); \
387 } \
Tom Sepez808a99e2015-09-10 12:28:37 -0700388 void js_class_name::JSConstructor(IFXJS_Context* cc, \
389 v8::Local<v8::Object> obj, \
390 v8::Local<v8::Object> global) { \
Nico Weber077f1a32015-08-06 15:08:57 -0700391 CJS_Object* pObj = new js_class_name(obj); \
392 pObj->SetEmbedObject(new class_alternate(pObj)); \
Tom Sepez39bfe122015-09-17 15:25:23 -0700393 FXJS_SetPrivate(NULL, obj, (void*)pObj); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394 pObj->InitInstance(cc); \
395 } \
396 \
Tom Sepez808a99e2015-09-10 12:28:37 -0700397 void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700398 js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700399 ASSERT(pObj != NULL); \
400 pObj->ExitInstance(); \
401 delete pObj; \
402 } \
403 \
Tom Sepez142165e2015-09-11 13:21:50 -0700404 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \
405 FXJSOBJTYPE eObjType) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700406 int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
407 eObjType, JSConstructor, JSDestructor); \
Tom Sepez570875c2015-09-11 08:35:03 -0700408 for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700409 FXJS_DefineObjProperty( \
410 pIsolate, nObjDefnID, JS_Class_Properties[i].pName, \
411 JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412 } \
413 \
Tom Sepez570875c2015-09-11 08:35:03 -0700414 for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700415 FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName, \
416 JS_Class_Methods[i].pMethodCall); \
Tom Sepez570875c2015-09-11 08:35:03 -0700417 } \
Tom Sepez39bfe122015-09-17 15:25:23 -0700418 FXJS_DefineObjAllProperties( \
Tom Sepez142165e2015-09-11 13:21:50 -0700419 pIsolate, nObjDefnID, \
420 js_class_name::queryprop_##js_class_name##_static, \
421 js_class_name::getprop_##js_class_name##_static, \
422 js_class_name::putprop_##js_class_name##_static, \
423 js_class_name::delprop_##js_class_name##_static); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700425
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426/* ======================================== GLOBAL METHODS
427 * ============================================ */
Tom Sepeza1160452015-02-19 10:00:55 -0800428
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429template <FX_BOOL (
430 *F)(IFXJS_Context*, const CJS_Parameters&, CJS_Value&, CFX_WideString&)>
431void JSGlobalFunc(const char* func_name_string,
Tom Sepeza1160452015-02-19 10:00:55 -0800432 const v8::FunctionCallbackInfo<v8::Value>& info) {
433 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700434 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
435 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700436 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700437 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepeza1160452015-02-19 10:00:55 -0800438 CJS_Parameters parameters;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700439 for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700440 parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown));
Tom Sepeza1160452015-02-19 10:00:55 -0800441 }
442 CJS_Value valueRes(isolate);
Tom Sepez3a832662015-03-02 12:59:05 -0800443 CFX_WideString sError;
444 if (!(*F)(pRuntimeContext, parameters, valueRes, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700445 FXJS_Error(isolate, JSFormatErrorString(func_name_string, nullptr, sError));
Tom Sepeza1160452015-02-19 10:00:55 -0800446 return;
447 }
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700448 info.GetReturnValue().Set(valueRes.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700449}
450
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700451#define JS_STATIC_GLOBAL_FUN(fun_name) \
452 static void fun_name##_static( \
453 const v8::FunctionCallbackInfo<v8::Value>& info) { \
454 JSGlobalFunc<fun_name>(#fun_name, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800455 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700456
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700457#define JS_STATIC_DECLARE_GLOBAL_FUN() \
458 static JSMethodSpec global_methods[]; \
Tom Sepez142165e2015-09-11 13:21:50 -0700459 static void DefineJSObjects(v8::Isolate* pIsolate)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700460
461#define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700462 JSMethodSpec js_class_name::global_methods[] = {
463#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name) \
464 JS_STATIC_METHOD_ENTRY(method_name)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700465
466#define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
467
Tom Sepez39bfe122015-09-17 15:25:23 -0700468#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \
469 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate) { \
470 for (int i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \
471 FXJS_DefineGlobalMethod(pIsolate, \
472 js_class_name::global_methods[i].pName, \
473 js_class_name::global_methods[i].pMethodCall); \
474 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700475 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700476
Tom Sepez39bfe122015-09-17 15:25:23 -0700477CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700478
Tom Sepez37458412015-10-06 11:33:46 -0700479#endif // FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_