blob: e91ce03d3054f3844fa7bacdeafbe985dcb4c3fa [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 Sepez19922bb2015-05-28 13:23:12 -07007#ifndef FPDFSDK_INCLUDE_JAVASCRIPT_JS_DEFINE_H_
8#define FPDFSDK_INCLUDE_JAVASCRIPT_JS_DEFINE_H_
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07009
Tom Sepez3a832662015-03-02 12:59:05 -080010#include "../jsapi/fxjs_v8.h"
11#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[] = {
52#define JS_STATIC_PROP_ENTRY(prop_name) \
53 { \
54 JS_WIDESTRING(prop_name), get_##prop_name##_static, set_##prop_name##_static \
55 } \
56 ,
57#define END_JS_STATIC_PROP() \
58 { 0, 0, 0 } \
59 } \
60 ;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062#define BEGIN_JS_STATIC_METHOD(js_class_name) \
63 JSMethodSpec js_class_name::JS_Class_Methods[] = {
64#define JS_STATIC_METHOD_ENTRY(method_name) \
65 { JS_WIDESTRING(method_name), method_name##_static } \
66 ,
67#define END_JS_STATIC_METHOD() \
68 { 0, 0 } \
69 } \
70 ;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070071
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072/* ======================================== PROP CALLBACK
73 * ============================================ */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075template <class C,
76 FX_BOOL (C::*M)(IFXJS_Context*, CJS_PropValue&, CFX_WideString&)>
Tom Sepeza1160452015-02-19 10:00:55 -080077void JSPropGetter(const char* prop_name_string,
78 const char* class_name_string,
79 v8::Local<v8::String> property,
80 const v8::PropertyCallbackInfo<v8::Value>& info) {
81 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -070082 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
83 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -070084 return;
Tom Sepeza25fd092015-09-28 09:06:03 -070085 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepez39bfe122015-09-17 15:25:23 -070086 CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
Tom Sepeza1160452015-02-19 10:00:55 -080087 C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
Tom Sepez3a832662015-03-02 12:59:05 -080088 CFX_WideString sError;
Tom Sepeza25fd092015-09-28 09:06:03 -070089 CJS_PropValue value(isolate);
90 value.StartGetting();
Tom Sepeza1160452015-02-19 10:00:55 -080091 if (!(pObj->*M)(pRuntimeContext, value, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -070092 FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
93 sError));
Tom Sepeza1160452015-02-19 10:00:55 -080094 return;
95 }
Jochen Eisingerdfa2c992015-05-19 00:38:00 +020096 info.GetReturnValue().Set((v8::Local<v8::Value>)value);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070097}
98
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099template <class C,
100 FX_BOOL (C::*M)(IFXJS_Context*, CJS_PropValue&, CFX_WideString&)>
Tom Sepeza1160452015-02-19 10:00:55 -0800101void JSPropSetter(const char* prop_name_string,
102 const char* class_name_string,
103 v8::Local<v8::String> property,
104 v8::Local<v8::Value> value,
105 const v8::PropertyCallbackInfo<void>& info) {
106 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700107 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
108 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700109 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700110 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepez39bfe122015-09-17 15:25:23 -0700111 CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
Tom Sepeza1160452015-02-19 10:00:55 -0800112 C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
Tom Sepez3a832662015-03-02 12:59:05 -0800113 CFX_WideString sError;
Tom Sepeza25fd092015-09-28 09:06:03 -0700114 CJS_PropValue propValue(CJS_Value(isolate, value, CJS_Value::VT_unknown));
115 propValue.StartSetting();
Tom Sepeza1160452015-02-19 10:00:55 -0800116 if (!(pObj->*M)(pRuntimeContext, propValue, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700117 FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
118 sError));
Tom Sepeza1160452015-02-19 10:00:55 -0800119 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120}
121
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122#define JS_STATIC_PROP(prop_name, class_name) \
123 static void get_##prop_name##_static( \
124 v8::Local<v8::String> property, \
125 const v8::PropertyCallbackInfo<v8::Value>& info) { \
126 JSPropGetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
127 property, info); \
128 } \
129 static void set_##prop_name##_static( \
130 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
131 const v8::PropertyCallbackInfo<void>& info) { \
132 JSPropSetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
133 property, value, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800134 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136/* ========================================= METHOD CALLBACK
137 * =========================================== */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700138
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139template <class C,
140 FX_BOOL (C::*M)(IFXJS_Context*,
141 const CJS_Parameters&,
142 CJS_Value&,
143 CFX_WideString&)>
Tom Sepeza1160452015-02-19 10:00:55 -0800144void JSMethod(const char* method_name_string,
145 const char* class_name_string,
146 const v8::FunctionCallbackInfo<v8::Value>& info) {
147 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700148 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
149 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700150 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700151 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepeza1160452015-02-19 10:00:55 -0800152 CJS_Parameters parameters;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700154 parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown));
Tom Sepeza1160452015-02-19 10:00:55 -0800155 }
156 CJS_Value valueRes(isolate);
Tom Sepez39bfe122015-09-17 15:25:23 -0700157 CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
Tom Sepeza1160452015-02-19 10:00:55 -0800158 C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
Tom Sepez3a832662015-03-02 12:59:05 -0800159 CFX_WideString sError;
Tom Sepeza1160452015-02-19 10:00:55 -0800160 if (!(pObj->*M)(pRuntimeContext, parameters, valueRes, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700161 FXJS_Error(isolate, JSFormatErrorString(class_name_string,
162 method_name_string, sError));
Tom Sepeza1160452015-02-19 10:00:55 -0800163 return;
164 }
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700165 info.GetReturnValue().Set(valueRes.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166}
167
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168#define JS_STATIC_METHOD(method_name, class_name) \
169 static void method_name##_static( \
170 const v8::FunctionCallbackInfo<v8::Value>& info) { \
171 JSMethod<class_name, &class_name::method_name>(#method_name, #class_name, \
172 info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800173 }
174
175#define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name) \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 static void method_name##_static( \
177 const v8::FunctionCallbackInfo<v8::Value>& info) { \
178 JSMethod<class_alternate, &class_alternate::method_name>( \
179 #method_name, #class_name, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800180 }
181
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182/* ===================================== JS CLASS
183 * =============================================== */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184
Tom Sepez142165e2015-09-11 13:21:50 -0700185#define DECLARE_JS_CLASS(js_class_name) \
186 static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \
187 v8::Local<v8::Object> global); \
188 static void JSDestructor(v8::Local<v8::Object> obj); \
189 static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
190 static JSConstSpec JS_Class_Consts[]; \
191 static JSPropertySpec JS_Class_Properties[]; \
192 static JSMethodSpec JS_Class_Methods[]; \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 static const wchar_t* m_pClassName
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700194
Tom Sepez39bfe122015-09-17 15:25:23 -0700195#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \
196 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \
197 void js_class_name::JSConstructor(IFXJS_Context* cc, \
198 v8::Local<v8::Object> obj, \
199 v8::Local<v8::Object> global) { \
200 CJS_Object* pObj = new js_class_name(obj); \
201 pObj->SetEmbedObject(new class_alternate(pObj)); \
202 FXJS_SetPrivate(NULL, obj, (void*)pObj); \
203 pObj->InitInstance(cc); \
204 } \
205 \
206 void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \
207 js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj); \
208 pObj->ExitInstance(); \
209 delete pObj; \
210 } \
211 \
212 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \
213 FXJSOBJTYPE eObjType) { \
214 int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
215 eObjType, JSConstructor, JSDestructor); \
216 for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \
217 FXJS_DefineObjProperty( \
218 pIsolate, nObjDefnID, JS_Class_Properties[i].pName, \
219 JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \
220 } \
221 for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \
222 FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName, \
223 JS_Class_Methods[i].pMethodCall); \
224 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227#define IMPLEMENT_JS_CLASS(js_class_name, class_name) \
228 IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700229
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230/* ======================================== CONST CLASS
231 * ============================================ */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700232
Tom Sepez142165e2015-09-11 13:21:50 -0700233#define DECLARE_JS_CLASS_CONST() \
234 static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
235 static JSConstSpec JS_Class_Consts[]; \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236 static const wchar_t* m_pClassName
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237
Tom Sepez39bfe122015-09-17 15:25:23 -0700238#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name) \
239 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \
240 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \
241 FXJSOBJTYPE eObjType) { \
242 int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
243 eObjType, NULL, NULL); \
244 for (int i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \
245 FXJS_DefineObjConst( \
246 pIsolate, nObjDefnID, JS_Class_Consts[i].pName, \
247 JS_Class_Consts[i].t == 0 \
248 ? FXJS_NewNumber(pIsolate, JS_Class_Consts[i].number) \
249 : FXJS_NewString(pIsolate, JS_Class_Consts[i].string)); \
250 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253/* ===================================== SPECIAL JS CLASS
254 * =============================================== */
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700255
Tom Sepez2311b782015-02-23 10:22:51 -0800256template <class Alt>
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257void JSSpecialPropQuery(const char*,
258 v8::Local<v8::String> property,
259 const v8::PropertyCallbackInfo<v8::Integer>& info) {
Tom Sepez2311b782015-02-23 10:22:51 -0800260 v8::Isolate* isolate = info.GetIsolate();
261 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 CFX_WideString propname =
263 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
264 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700265 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800266 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
267 FX_BOOL bRet = pObj->QueryProperty(propname.c_str());
268 info.GetReturnValue().Set(bRet ? 4 : 0);
269}
270
271template <class Alt>
272void JSSpecialPropGet(const char* class_name,
273 v8::Local<v8::String> property,
274 const v8::PropertyCallbackInfo<v8::Value>& info) {
275 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700276 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
277 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700278 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700279 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700281 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800282 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
283 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 CFX_WideString propname =
285 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
Tom Sepez3a832662015-03-02 12:59:05 -0800286 CFX_WideString sError;
Tom Sepez2311b782015-02-23 10:22:51 -0800287 CJS_PropValue value(isolate);
288 value.StartGetting();
289 if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), value, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700290 FXJS_Error(isolate, JSFormatErrorString(class_name, "GetProperty", sError));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 return;
Tom Sepez2311b782015-02-23 10:22:51 -0800292 }
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200293 info.GetReturnValue().Set((v8::Local<v8::Value>)value);
Tom Sepez2311b782015-02-23 10:22:51 -0800294}
295
296template <class Alt>
297void JSSpecialPropPut(const char* class_name,
298 v8::Local<v8::String> property,
299 v8::Local<v8::Value> value,
300 const v8::PropertyCallbackInfo<v8::Value>& info) {
301 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700302 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
303 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700304 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700305 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700307 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800308 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
309 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 CFX_WideString propname =
311 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
Tom Sepez3a832662015-03-02 12:59:05 -0800312 CFX_WideString sError;
Tom Sepez39bfe122015-09-17 15:25:23 -0700313 CJS_PropValue PropValue(CJS_Value(isolate, value, CJS_Value::VT_unknown));
Tom Sepez2311b782015-02-23 10:22:51 -0800314 PropValue.StartSetting();
315 if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), PropValue, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700316 FXJS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
Tom Sepez2311b782015-02-23 10:22:51 -0800317 }
318}
319
320template <class Alt>
321void JSSpecialPropDel(const char* class_name,
322 v8::Local<v8::String> property,
323 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
324 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700325 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
326 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700327 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700328 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700329 CJS_Object* pJSObj =
Tom Sepez39bfe122015-09-17 15:25:23 -0700330 reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
Tom Sepez2311b782015-02-23 10:22:51 -0800331 Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
332 v8::String::Utf8Value utf8_value(property);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700333 CFX_WideString propname =
334 CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
Tom Sepez3a832662015-03-02 12:59:05 -0800335 CFX_WideString sError;
Tom Sepez2311b782015-02-23 10:22:51 -0800336 if (!pObj->DelProperty(pRuntimeContext, propname.c_str(), sError)) {
337 CFX_ByteString cbName;
338 cbName.Format("%s.%s", class_name, "DelProperty");
Tom Sepez39bfe122015-09-17 15:25:23 -0700339 // Probably a missing call to JSFX_Error().
Tom Sepez2311b782015-02-23 10:22:51 -0800340 }
341}
342
Tom Sepez142165e2015-09-11 13:21:50 -0700343#define DECLARE_SPECIAL_JS_CLASS(js_class_name) \
344 static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj, \
345 v8::Local<v8::Object> global); \
346 static void JSDestructor(v8::Local<v8::Object> obj); \
347 static JSConstSpec JS_Class_Consts[]; \
348 static JSPropertySpec JS_Class_Properties[]; \
349 static JSMethodSpec JS_Class_Methods[]; \
350 static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
351 static const wchar_t* m_pClassName; \
352 static void queryprop_##js_class_name##_static( \
353 v8::Local<v8::String> property, \
354 const v8::PropertyCallbackInfo<v8::Integer>& info); \
355 static void getprop_##js_class_name##_static( \
356 v8::Local<v8::String> property, \
357 const v8::PropertyCallbackInfo<v8::Value>& info); \
358 static void putprop_##js_class_name##_static( \
359 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
360 const v8::PropertyCallbackInfo<v8::Value>& info); \
361 static void delprop_##js_class_name##_static( \
362 v8::Local<v8::String> property, \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 const v8::PropertyCallbackInfo<v8::Boolean>& info)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700364
365#define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366 const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name); \
367 void js_class_name::queryprop_##js_class_name##_static( \
368 v8::Local<v8::String> property, \
369 const v8::PropertyCallbackInfo<v8::Integer>& info) { \
370 JSSpecialPropQuery<class_alternate>(#class_name, property, info); \
371 } \
372 void js_class_name::getprop_##js_class_name##_static( \
373 v8::Local<v8::String> property, \
374 const v8::PropertyCallbackInfo<v8::Value>& info) { \
375 JSSpecialPropGet<class_alternate>(#class_name, property, info); \
376 } \
377 void js_class_name::putprop_##js_class_name##_static( \
378 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
379 const v8::PropertyCallbackInfo<v8::Value>& info) { \
380 JSSpecialPropPut<class_alternate>(#class_name, property, value, info); \
381 } \
382 void js_class_name::delprop_##js_class_name##_static( \
383 v8::Local<v8::String> property, \
384 const v8::PropertyCallbackInfo<v8::Boolean>& info) { \
385 JSSpecialPropDel<class_alternate>(#class_name, property, info); \
386 } \
Tom Sepez808a99e2015-09-10 12:28:37 -0700387 void js_class_name::JSConstructor(IFXJS_Context* cc, \
388 v8::Local<v8::Object> obj, \
389 v8::Local<v8::Object> global) { \
Nico Weber077f1a32015-08-06 15:08:57 -0700390 CJS_Object* pObj = new js_class_name(obj); \
391 pObj->SetEmbedObject(new class_alternate(pObj)); \
Tom Sepez39bfe122015-09-17 15:25:23 -0700392 FXJS_SetPrivate(NULL, obj, (void*)pObj); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393 pObj->InitInstance(cc); \
394 } \
395 \
Tom Sepez808a99e2015-09-10 12:28:37 -0700396 void js_class_name::JSDestructor(v8::Local<v8::Object> obj) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700397 js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398 ASSERT(pObj != NULL); \
399 pObj->ExitInstance(); \
400 delete pObj; \
401 } \
402 \
Tom Sepez142165e2015-09-11 13:21:50 -0700403 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate, \
404 FXJSOBJTYPE eObjType) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700405 int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
406 eObjType, JSConstructor, JSDestructor); \
Tom Sepez570875c2015-09-11 08:35:03 -0700407 for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700408 FXJS_DefineObjProperty( \
409 pIsolate, nObjDefnID, JS_Class_Properties[i].pName, \
410 JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411 } \
412 \
Tom Sepez570875c2015-09-11 08:35:03 -0700413 for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \
Tom Sepez39bfe122015-09-17 15:25:23 -0700414 FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName, \
415 JS_Class_Methods[i].pMethodCall); \
Tom Sepez570875c2015-09-11 08:35:03 -0700416 } \
Tom Sepez39bfe122015-09-17 15:25:23 -0700417 FXJS_DefineObjAllProperties( \
Tom Sepez142165e2015-09-11 13:21:50 -0700418 pIsolate, nObjDefnID, \
419 js_class_name::queryprop_##js_class_name##_static, \
420 js_class_name::getprop_##js_class_name##_static, \
421 js_class_name::putprop_##js_class_name##_static, \
422 js_class_name::delprop_##js_class_name##_static); \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700424
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425/* ======================================== GLOBAL METHODS
426 * ============================================ */
Tom Sepeza1160452015-02-19 10:00:55 -0800427
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700428template <FX_BOOL (
429 *F)(IFXJS_Context*, const CJS_Parameters&, CJS_Value&, CFX_WideString&)>
430void JSGlobalFunc(const char* func_name_string,
Tom Sepeza1160452015-02-19 10:00:55 -0800431 const v8::FunctionCallbackInfo<v8::Value>& info) {
432 v8::Isolate* isolate = info.GetIsolate();
Tom Sepezbd7fabf2015-09-28 10:31:27 -0700433 IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
434 if (!pRuntime)
Tom Sepeza25fd092015-09-28 09:06:03 -0700435 return;
Tom Sepeza25fd092015-09-28 09:06:03 -0700436 IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
Tom Sepeza1160452015-02-19 10:00:55 -0800437 CJS_Parameters parameters;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700438 for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700439 parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown));
Tom Sepeza1160452015-02-19 10:00:55 -0800440 }
441 CJS_Value valueRes(isolate);
Tom Sepez3a832662015-03-02 12:59:05 -0800442 CFX_WideString sError;
443 if (!(*F)(pRuntimeContext, parameters, valueRes, sError)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700444 FXJS_Error(isolate, JSFormatErrorString(func_name_string, nullptr, sError));
Tom Sepeza1160452015-02-19 10:00:55 -0800445 return;
446 }
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700447 info.GetReturnValue().Set(valueRes.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700448}
449
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700450#define JS_STATIC_GLOBAL_FUN(fun_name) \
451 static void fun_name##_static( \
452 const v8::FunctionCallbackInfo<v8::Value>& info) { \
453 JSGlobalFunc<fun_name>(#fun_name, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800454 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700455
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456#define JS_STATIC_DECLARE_GLOBAL_FUN() \
457 static JSMethodSpec global_methods[]; \
Tom Sepez142165e2015-09-11 13:21:50 -0700458 static void DefineJSObjects(v8::Isolate* pIsolate)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700459
460#define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461 JSMethodSpec js_class_name::global_methods[] = {
462#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name) \
463 JS_STATIC_METHOD_ENTRY(method_name)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700464
465#define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
466
Tom Sepez39bfe122015-09-17 15:25:23 -0700467#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \
468 void js_class_name::DefineJSObjects(v8::Isolate* pIsolate) { \
469 for (int i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \
470 FXJS_DefineGlobalMethod(pIsolate, \
471 js_class_name::global_methods[i].pName, \
472 js_class_name::global_methods[i].pMethodCall); \
473 } \
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700474 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700475
Tom Sepez39bfe122015-09-17 15:25:23 -0700476CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700477
Tom Sepez19922bb2015-05-28 13:23:12 -0700478#endif // FPDFSDK_INCLUDE_JAVASCRIPT_JS_DEFINE_H_