xref: /aosp_15_r20/external/pdfium/fxjs/js_define.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #ifndef FXJS_JS_DEFINE_H_
8*3ac0a46fSAndroid Build Coastguard Worker #define FXJS_JS_DEFINE_H_
9*3ac0a46fSAndroid Build Coastguard Worker 
10*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
11*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
12*3ac0a46fSAndroid Build Coastguard Worker 
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/unowned_ptr.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cfxjs_engine.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cjs_result.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cjs_runtime.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/js_resources.h"
18*3ac0a46fSAndroid Build Coastguard Worker 
19*3ac0a46fSAndroid Build Coastguard Worker class CJS_Object;
20*3ac0a46fSAndroid Build Coastguard Worker 
21*3ac0a46fSAndroid Build Coastguard Worker double JS_DateParse(v8::Isolate* pIsolate, const WideString& str);
22*3ac0a46fSAndroid Build Coastguard Worker 
23*3ac0a46fSAndroid Build Coastguard Worker // Some JS methods have the bizarre convention that they may also be called
24*3ac0a46fSAndroid Build Coastguard Worker // with a single argument which is an object containing the actual arguments
25*3ac0a46fSAndroid Build Coastguard Worker // as its properties. The varying arguments to this method are the property
26*3ac0a46fSAndroid Build Coastguard Worker // names as wchar_t string literals corresponding to each positional argument.
27*3ac0a46fSAndroid Build Coastguard Worker // The result will always contain |nKeywords| value, check for the unspecified
28*3ac0a46fSAndroid Build Coastguard Worker // ones in the result using IsExpandedParamKnown() below.
29*3ac0a46fSAndroid Build Coastguard Worker std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
30*3ac0a46fSAndroid Build Coastguard Worker     CJS_Runtime* pRuntime,
31*3ac0a46fSAndroid Build Coastguard Worker     const std::vector<v8::Local<v8::Value>>& originals,
32*3ac0a46fSAndroid Build Coastguard Worker     size_t nKeywords,
33*3ac0a46fSAndroid Build Coastguard Worker     ...);
34*3ac0a46fSAndroid Build Coastguard Worker 
35*3ac0a46fSAndroid Build Coastguard Worker bool IsExpandedParamKnown(v8::Local<v8::Value> value);
36*3ac0a46fSAndroid Build Coastguard Worker 
37*3ac0a46fSAndroid Build Coastguard Worker // All JS classes have a name, an object defintion ID, and the ability to
38*3ac0a46fSAndroid Build Coastguard Worker // register themselves with FXJS_V8. We never make a BASE class on its own
39*3ac0a46fSAndroid Build Coastguard Worker // because it can't really do anything.
40*3ac0a46fSAndroid Build Coastguard Worker 
41*3ac0a46fSAndroid Build Coastguard Worker // Rich JS classes provide constants, methods, properties, and the ability
42*3ac0a46fSAndroid Build Coastguard Worker // to construct native object state.
43*3ac0a46fSAndroid Build Coastguard Worker 
44*3ac0a46fSAndroid Build Coastguard Worker template <class T>
JSConstructor(CFXJS_Engine * pEngine,v8::Local<v8::Object> obj,v8::Local<v8::Object> proxy)45*3ac0a46fSAndroid Build Coastguard Worker static void JSConstructor(CFXJS_Engine* pEngine,
46*3ac0a46fSAndroid Build Coastguard Worker                           v8::Local<v8::Object> obj,
47*3ac0a46fSAndroid Build Coastguard Worker                           v8::Local<v8::Object> proxy) {
48*3ac0a46fSAndroid Build Coastguard Worker   pEngine->SetObjectPrivate(
49*3ac0a46fSAndroid Build Coastguard Worker       obj, std::make_unique<T>(proxy, static_cast<CJS_Runtime*>(pEngine)));
50*3ac0a46fSAndroid Build Coastguard Worker }
51*3ac0a46fSAndroid Build Coastguard Worker 
52*3ac0a46fSAndroid Build Coastguard Worker // CJS_Object has virtual dtor, template not required.
53*3ac0a46fSAndroid Build Coastguard Worker void JSDestructor(v8::Local<v8::Object> obj);
54*3ac0a46fSAndroid Build Coastguard Worker 
55*3ac0a46fSAndroid Build Coastguard Worker template <class C>
JSGetObject(v8::Isolate * isolate,v8::Local<v8::Object> obj)56*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<C> JSGetObject(v8::Isolate* isolate, v8::Local<v8::Object> obj) {
57*3ac0a46fSAndroid Build Coastguard Worker   if (CFXJS_Engine::GetObjDefnID(obj) != C::GetObjDefnID())
58*3ac0a46fSAndroid Build Coastguard Worker     return nullptr;
59*3ac0a46fSAndroid Build Coastguard Worker 
60*3ac0a46fSAndroid Build Coastguard Worker   CJS_Object* pJSObj = CFXJS_Engine::GetObjectPrivate(isolate, obj);
61*3ac0a46fSAndroid Build Coastguard Worker   if (!pJSObj)
62*3ac0a46fSAndroid Build Coastguard Worker     return nullptr;
63*3ac0a46fSAndroid Build Coastguard Worker 
64*3ac0a46fSAndroid Build Coastguard Worker   return UnownedPtr<C>(static_cast<C*>(pJSObj));
65*3ac0a46fSAndroid Build Coastguard Worker }
66*3ac0a46fSAndroid Build Coastguard Worker 
67*3ac0a46fSAndroid Build Coastguard Worker template <class C, CJS_Result (C::*M)(CJS_Runtime*)>
JSPropGetter(const char * prop_name_string,const char * class_name_string,v8::Local<v8::String> property,const v8::PropertyCallbackInfo<v8::Value> & info)68*3ac0a46fSAndroid Build Coastguard Worker void JSPropGetter(const char* prop_name_string,
69*3ac0a46fSAndroid Build Coastguard Worker                   const char* class_name_string,
70*3ac0a46fSAndroid Build Coastguard Worker                   v8::Local<v8::String> property,
71*3ac0a46fSAndroid Build Coastguard Worker                   const v8::PropertyCallbackInfo<v8::Value>& info) {
72*3ac0a46fSAndroid Build Coastguard Worker   auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder());
73*3ac0a46fSAndroid Build Coastguard Worker   if (!pObj)
74*3ac0a46fSAndroid Build Coastguard Worker     return;
75*3ac0a46fSAndroid Build Coastguard Worker 
76*3ac0a46fSAndroid Build Coastguard Worker   CJS_Runtime* pRuntime = pObj->GetRuntime();
77*3ac0a46fSAndroid Build Coastguard Worker   if (!pRuntime)
78*3ac0a46fSAndroid Build Coastguard Worker     return;
79*3ac0a46fSAndroid Build Coastguard Worker 
80*3ac0a46fSAndroid Build Coastguard Worker   CJS_Result result = (pObj.get()->*M)(pRuntime);
81*3ac0a46fSAndroid Build Coastguard Worker   if (result.HasError()) {
82*3ac0a46fSAndroid Build Coastguard Worker     pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
83*3ac0a46fSAndroid Build Coastguard Worker                                         result.Error()));
84*3ac0a46fSAndroid Build Coastguard Worker     return;
85*3ac0a46fSAndroid Build Coastguard Worker   }
86*3ac0a46fSAndroid Build Coastguard Worker 
87*3ac0a46fSAndroid Build Coastguard Worker   if (result.HasReturn())
88*3ac0a46fSAndroid Build Coastguard Worker     info.GetReturnValue().Set(result.Return());
89*3ac0a46fSAndroid Build Coastguard Worker }
90*3ac0a46fSAndroid Build Coastguard Worker 
91*3ac0a46fSAndroid Build Coastguard Worker template <class C, CJS_Result (C::*M)(CJS_Runtime*, v8::Local<v8::Value>)>
JSPropSetter(const char * prop_name_string,const char * class_name_string,v8::Local<v8::String> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<void> & info)92*3ac0a46fSAndroid Build Coastguard Worker void JSPropSetter(const char* prop_name_string,
93*3ac0a46fSAndroid Build Coastguard Worker                   const char* class_name_string,
94*3ac0a46fSAndroid Build Coastguard Worker                   v8::Local<v8::String> property,
95*3ac0a46fSAndroid Build Coastguard Worker                   v8::Local<v8::Value> value,
96*3ac0a46fSAndroid Build Coastguard Worker                   const v8::PropertyCallbackInfo<void>& info) {
97*3ac0a46fSAndroid Build Coastguard Worker   auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder());
98*3ac0a46fSAndroid Build Coastguard Worker   if (!pObj)
99*3ac0a46fSAndroid Build Coastguard Worker     return;
100*3ac0a46fSAndroid Build Coastguard Worker 
101*3ac0a46fSAndroid Build Coastguard Worker   CJS_Runtime* pRuntime = pObj->GetRuntime();
102*3ac0a46fSAndroid Build Coastguard Worker   if (!pRuntime)
103*3ac0a46fSAndroid Build Coastguard Worker     return;
104*3ac0a46fSAndroid Build Coastguard Worker 
105*3ac0a46fSAndroid Build Coastguard Worker   CJS_Result result = (pObj.get()->*M)(pRuntime, value);
106*3ac0a46fSAndroid Build Coastguard Worker   if (result.HasError()) {
107*3ac0a46fSAndroid Build Coastguard Worker     pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
108*3ac0a46fSAndroid Build Coastguard Worker                                         result.Error()));
109*3ac0a46fSAndroid Build Coastguard Worker   }
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker 
112*3ac0a46fSAndroid Build Coastguard Worker template <class C,
113*3ac0a46fSAndroid Build Coastguard Worker           CJS_Result (C::*M)(CJS_Runtime*,
114*3ac0a46fSAndroid Build Coastguard Worker                              const std::vector<v8::Local<v8::Value>>&)>
JSMethod(const char * method_name_string,const char * class_name_string,const v8::FunctionCallbackInfo<v8::Value> & info)115*3ac0a46fSAndroid Build Coastguard Worker void JSMethod(const char* method_name_string,
116*3ac0a46fSAndroid Build Coastguard Worker               const char* class_name_string,
117*3ac0a46fSAndroid Build Coastguard Worker               const v8::FunctionCallbackInfo<v8::Value>& info) {
118*3ac0a46fSAndroid Build Coastguard Worker   auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder());
119*3ac0a46fSAndroid Build Coastguard Worker   if (!pObj)
120*3ac0a46fSAndroid Build Coastguard Worker     return;
121*3ac0a46fSAndroid Build Coastguard Worker 
122*3ac0a46fSAndroid Build Coastguard Worker   CJS_Runtime* pRuntime = pObj->GetRuntime();
123*3ac0a46fSAndroid Build Coastguard Worker   if (!pRuntime)
124*3ac0a46fSAndroid Build Coastguard Worker     return;
125*3ac0a46fSAndroid Build Coastguard Worker 
126*3ac0a46fSAndroid Build Coastguard Worker   std::vector<v8::Local<v8::Value>> parameters;
127*3ac0a46fSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++)
128*3ac0a46fSAndroid Build Coastguard Worker     parameters.push_back(info[i]);
129*3ac0a46fSAndroid Build Coastguard Worker 
130*3ac0a46fSAndroid Build Coastguard Worker   CJS_Result result = (pObj.get()->*M)(pRuntime, parameters);
131*3ac0a46fSAndroid Build Coastguard Worker   if (result.HasError()) {
132*3ac0a46fSAndroid Build Coastguard Worker     pRuntime->Error(JSFormatErrorString(class_name_string, method_name_string,
133*3ac0a46fSAndroid Build Coastguard Worker                                         result.Error()));
134*3ac0a46fSAndroid Build Coastguard Worker     return;
135*3ac0a46fSAndroid Build Coastguard Worker   }
136*3ac0a46fSAndroid Build Coastguard Worker 
137*3ac0a46fSAndroid Build Coastguard Worker   if (result.HasReturn())
138*3ac0a46fSAndroid Build Coastguard Worker     info.GetReturnValue().Set(result.Return());
139*3ac0a46fSAndroid Build Coastguard Worker }
140*3ac0a46fSAndroid Build Coastguard Worker 
141*3ac0a46fSAndroid Build Coastguard Worker #define JS_STATIC_PROP(err_name, prop_name, class_name)           \
142*3ac0a46fSAndroid Build Coastguard Worker   static void get_##prop_name##_static(                           \
143*3ac0a46fSAndroid Build Coastguard Worker       v8::Local<v8::String> property,                             \
144*3ac0a46fSAndroid Build Coastguard Worker       const v8::PropertyCallbackInfo<v8::Value>& info) {          \
145*3ac0a46fSAndroid Build Coastguard Worker     JSPropGetter<class_name, &class_name::get_##prop_name>(       \
146*3ac0a46fSAndroid Build Coastguard Worker         #err_name, class_name::kName, property, info);            \
147*3ac0a46fSAndroid Build Coastguard Worker   }                                                               \
148*3ac0a46fSAndroid Build Coastguard Worker   static void set_##prop_name##_static(                           \
149*3ac0a46fSAndroid Build Coastguard Worker       v8::Local<v8::String> property, v8::Local<v8::Value> value, \
150*3ac0a46fSAndroid Build Coastguard Worker       const v8::PropertyCallbackInfo<void>& info) {               \
151*3ac0a46fSAndroid Build Coastguard Worker     JSPropSetter<class_name, &class_name::set_##prop_name>(       \
152*3ac0a46fSAndroid Build Coastguard Worker         #err_name, class_name::kName, property, value, info);     \
153*3ac0a46fSAndroid Build Coastguard Worker   }
154*3ac0a46fSAndroid Build Coastguard Worker 
155*3ac0a46fSAndroid Build Coastguard Worker #define JS_STATIC_METHOD(method_name, class_name)                            \
156*3ac0a46fSAndroid Build Coastguard Worker   static void method_name##_static(                                          \
157*3ac0a46fSAndroid Build Coastguard Worker       const v8::FunctionCallbackInfo<v8::Value>& info) {                     \
158*3ac0a46fSAndroid Build Coastguard Worker     JSMethod<class_name, &class_name::method_name>(#method_name,             \
159*3ac0a46fSAndroid Build Coastguard Worker                                                    class_name::kName, info); \
160*3ac0a46fSAndroid Build Coastguard Worker   }
161*3ac0a46fSAndroid Build Coastguard Worker 
162*3ac0a46fSAndroid Build Coastguard Worker #endif  // FXJS_JS_DEFINE_H_
163