| // Copyright 2014 PDFium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 
 |  | 
 | #ifndef FXJS_JS_DEFINE_H_ | 
 | #define FXJS_JS_DEFINE_H_ | 
 |  | 
 | #include <memory> | 
 | #include <vector> | 
 |  | 
 | #include "core/fxcrt/unowned_ptr.h" | 
 | #include "fxjs/cfxjs_engine.h" | 
 | #include "fxjs/cjs_result.h" | 
 | #include "fxjs/cjs_runtime.h" | 
 | #include "fxjs/js_resources.h" | 
 |  | 
 | class CJS_Object; | 
 |  | 
 | double JS_DateParse(v8::Isolate* pIsolate, const WideString& str); | 
 |  | 
 | // Some JS methods have the bizarre convention that they may also be called | 
 | // with a single argument which is an object containing the actual arguments | 
 | // as its properties. The varying arguments to this method are the property | 
 | // names as wchar_t string literals corresponding to each positional argument. | 
 | // The result will always contain |nKeywords| value, check for the unspecified | 
 | // ones in the result using IsExpandedParamKnown() below. | 
 | std::vector<v8::Local<v8::Value>> ExpandKeywordParams( | 
 |     CJS_Runtime* pRuntime, | 
 |     const std::vector<v8::Local<v8::Value>>& originals, | 
 |     size_t nKeywords, | 
 |     ...); | 
 |  | 
 | bool IsExpandedParamKnown(v8::Local<v8::Value> value); | 
 |  | 
 | // All JS classes have a name, an object defintion ID, and the ability to | 
 | // register themselves with FXJS_V8. We never make a BASE class on its own | 
 | // because it can't really do anything. | 
 |  | 
 | // Rich JS classes provide constants, methods, properties, and the ability | 
 | // to construct native object state. | 
 |  | 
 | template <class T> | 
 | static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) { | 
 |   pEngine->SetObjectPrivate( | 
 |       obj, std::make_unique<T>(obj, static_cast<CJS_Runtime*>(pEngine))); | 
 | } | 
 |  | 
 | // CJS_Object has virtual dtor, template not required. | 
 | void JSDestructor(v8::Local<v8::Object> obj); | 
 |  | 
 | template <class C> | 
 | UnownedPtr<C> JSGetObject(v8::Isolate* isolate, v8::Local<v8::Object> obj) { | 
 |   if (CFXJS_Engine::GetObjDefnID(obj) != C::GetObjDefnID()) | 
 |     return nullptr; | 
 |  | 
 |   CJS_Object* pJSObj = CFXJS_Engine::GetObjectPrivate(isolate, obj); | 
 |   if (!pJSObj) | 
 |     return nullptr; | 
 |  | 
 |   return UnownedPtr<C>(static_cast<C*>(pJSObj)); | 
 | } | 
 |  | 
 | template <class C, CJS_Result (C::*M)(CJS_Runtime*)> | 
 | void JSPropGetter(const char* prop_name_string, | 
 |                   const char* class_name_string, | 
 |                   v8::Local<v8::String> property, | 
 |                   const v8::PropertyCallbackInfo<v8::Value>& info) { | 
 |   auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder()); | 
 |   if (!pObj) | 
 |     return; | 
 |  | 
 |   CJS_Runtime* pRuntime = pObj->GetRuntime(); | 
 |   if (!pRuntime) | 
 |     return; | 
 |  | 
 |   CJS_Result result = (pObj.Get()->*M)(pRuntime); | 
 |   if (result.HasError()) { | 
 |     pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string, | 
 |                                         result.Error())); | 
 |     return; | 
 |   } | 
 |  | 
 |   if (result.HasReturn()) | 
 |     info.GetReturnValue().Set(result.Return()); | 
 | } | 
 |  | 
 | template <class C, CJS_Result (C::*M)(CJS_Runtime*, v8::Local<v8::Value>)> | 
 | void 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) { | 
 |   auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder()); | 
 |   if (!pObj) | 
 |     return; | 
 |  | 
 |   CJS_Runtime* pRuntime = pObj->GetRuntime(); | 
 |   if (!pRuntime) | 
 |     return; | 
 |  | 
 |   CJS_Result result = (pObj.Get()->*M)(pRuntime, value); | 
 |   if (result.HasError()) { | 
 |     pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string, | 
 |                                         result.Error())); | 
 |   } | 
 | } | 
 |  | 
 | template <class C, | 
 |           CJS_Result (C::*M)(CJS_Runtime*, | 
 |                              const std::vector<v8::Local<v8::Value>>&)> | 
 | void JSMethod(const char* method_name_string, | 
 |               const char* class_name_string, | 
 |               const v8::FunctionCallbackInfo<v8::Value>& info) { | 
 |   auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder()); | 
 |   if (!pObj) | 
 |     return; | 
 |  | 
 |   CJS_Runtime* pRuntime = pObj->GetRuntime(); | 
 |   if (!pRuntime) | 
 |     return; | 
 |  | 
 |   std::vector<v8::Local<v8::Value>> parameters; | 
 |   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) | 
 |     parameters.push_back(info[i]); | 
 |  | 
 |   CJS_Result result = (pObj.Get()->*M)(pRuntime, parameters); | 
 |   if (result.HasError()) { | 
 |     pRuntime->Error(JSFormatErrorString(class_name_string, method_name_string, | 
 |                                         result.Error())); | 
 |     return; | 
 |   } | 
 |  | 
 |   if (result.HasReturn()) | 
 |     info.GetReturnValue().Set(result.Return()); | 
 | } | 
 |  | 
 | #define JS_STATIC_PROP(err_name, prop_name, class_name)           \ | 
 |   static void get_##prop_name##_static(                           \ | 
 |       v8::Local<v8::String> property,                             \ | 
 |       const v8::PropertyCallbackInfo<v8::Value>& info) {          \ | 
 |     JSPropGetter<class_name, &class_name::get_##prop_name>(       \ | 
 |         #err_name, class_name::kName, property, info);            \ | 
 |   }                                                               \ | 
 |   static void set_##prop_name##_static(                           \ | 
 |       v8::Local<v8::String> property, v8::Local<v8::Value> value, \ | 
 |       const v8::PropertyCallbackInfo<void>& info) {               \ | 
 |     JSPropSetter<class_name, &class_name::set_##prop_name>(       \ | 
 |         #err_name, class_name::kName, property, value, info);     \ | 
 |   } | 
 |  | 
 | #define JS_STATIC_METHOD(method_name, class_name)                            \ | 
 |   static void method_name##_static(                                          \ | 
 |       const v8::FunctionCallbackInfo<v8::Value>& info) {                     \ | 
 |     JSMethod<class_name, &class_name::method_name>(#method_name,             \ | 
 |                                                    class_name::kName, info); \ | 
 |   } | 
 |  | 
 | #endif  // FXJS_JS_DEFINE_H_ |