blob: 2c15c9f4e28da2f3b93cf23cf4b9679ff42c0951 [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
Dan Sinclaire0345a42017-10-30 20:20:42 +00007#ifndef FXJS_JS_DEFINE_H_
8#define FXJS_JS_DEFINE_H_
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07009
Dan Sinclair3ebd1212016-03-09 09:59:23 -050010#include <vector>
11
Tom Sepez82999fa2018-07-16 22:17:46 +000012#include "core/fxcrt/unowned_ptr.h"
Tom Sepezb7c7df62018-02-09 19:08:59 +000013#include "fxjs/cfxjs_engine.h"
Tom Sepez3a6d0582018-08-17 19:28:52 +000014#include "fxjs/cjs_result.h"
Lei Zhang31beedc2018-10-18 21:09:55 +000015#include "fxjs/cjs_runtime.h"
Dan Sinclaire0345a42017-10-30 20:20:42 +000016#include "fxjs/js_resources.h"
Tom Sepez2108e572018-01-30 20:15:10 +000017#include "third_party/base/ptr_util.h"
Tom Sepeza1160452015-02-19 10:00:55 -080018
Lei Zhang31beedc2018-10-18 21:09:55 +000019class CJS_Object;
20
Dan Sinclaira1465072017-10-30 17:05:31 +000021double JS_DateParse(const WideString& str);
Dan Sinclaira1465072017-10-30 17:05:31 +000022
23// Some JS methods have the bizarre convention that they may also be called
24// with a single argument which is an object containing the actual arguments
25// as its properties. The varying arguments to this method are the property
26// names as wchar_t string literals corresponding to each positional argument.
Tom Sepez0e5bab12018-10-18 21:39:40 +000027// The result will always contain |nKeywords| value, check for the unspecified
28// ones in the result using IsExpandedParamKnown() below.
Dan Sinclaira1465072017-10-30 17:05:31 +000029std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
30 CJS_Runtime* pRuntime,
31 const std::vector<v8::Local<v8::Value>>& originals,
32 size_t nKeywords,
33 ...);
34
Tom Sepez0e5bab12018-10-18 21:39:40 +000035bool IsExpandedParamKnown(v8::Local<v8::Value> value);
36
Dan Sinclair89d26c82017-10-26 12:21:28 -040037// All JS classes have a name, an object defintion ID, and the ability to
38// register themselves with FXJS_V8. We never make a BASE class on its own
39// because it can't really do anything.
40
41// Rich JS classes provide constants, methods, properties, and the ability
42// to construct native object state.
43
Dan Sinclair998fee32018-02-05 21:43:19 +000044template <class T>
Dan Sinclaird808dfd2017-10-26 15:04:17 -040045static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
Tom Sepez83b259e2018-06-08 20:43:55 +000046 pEngine->SetObjectPrivate(
47 obj, pdfium::MakeUnique<T>(obj, static_cast<CJS_Runtime*>(pEngine)));
Dan Sinclaird808dfd2017-10-26 15:04:17 -040048}
Tom Sepez04557b82017-02-16 09:43:10 -080049
Lei Zhangb1a4db52018-07-11 13:02:54 +000050// CJS_Object has virtual dtor, template not required.
Tom Sepezb3f10462018-02-08 20:16:09 +000051void JSDestructor(v8::Local<v8::Object> obj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052
Lei Zhangad1f7b42018-07-11 13:04:43 +000053template <class C>
Tom Sepez82999fa2018-07-16 22:17:46 +000054UnownedPtr<C> JSGetObject(v8::Local<v8::Object> obj) {
Lei Zhangad1f7b42018-07-11 13:04:43 +000055 if (CFXJS_Engine::GetObjDefnID(obj) != C::GetObjDefnID())
56 return nullptr;
57
58 CJS_Object* pJSObj = CFXJS_Engine::GetObjectPrivate(obj);
59 if (!pJSObj)
60 return nullptr;
61
Tom Sepez82999fa2018-07-16 22:17:46 +000062 return UnownedPtr<C>(static_cast<C*>(pJSObj));
Lei Zhangad1f7b42018-07-11 13:04:43 +000063}
64
Tom Sepez3a6d0582018-08-17 19:28:52 +000065template <class C, CJS_Result (C::*M)(CJS_Runtime*)>
Tom Sepeza1160452015-02-19 10:00:55 -080066void JSPropGetter(const char* prop_name_string,
67 const char* class_name_string,
68 v8::Local<v8::String> property,
69 const v8::PropertyCallbackInfo<v8::Value>& info) {
Tom Sepez82999fa2018-07-16 22:17:46 +000070 auto pObj = JSGetObject<C>(info.Holder());
Lei Zhangad1f7b42018-07-11 13:04:43 +000071 if (!pObj)
Tom Sepeza25fd092015-09-28 09:06:03 -070072 return;
dan sinclaircbe23db2017-10-19 14:29:33 -040073
Lei Zhangad1f7b42018-07-11 13:04:43 +000074 CJS_Runtime* pRuntime = pObj->GetRuntime();
Tom Sepezddaa40f2018-06-06 18:30:15 +000075 if (!pRuntime)
Tom Sepezc5a14722017-02-24 15:31:12 -080076 return;
dan sinclaircbe23db2017-10-19 14:29:33 -040077
Tom Sepez3a6d0582018-08-17 19:28:52 +000078 CJS_Result result = (pObj.Get()->*M)(pRuntime);
Dan Sinclair8f524d62017-10-25 13:30:31 -040079 if (result.HasError()) {
80 pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
81 result.Error()));
Tom Sepeza1160452015-02-19 10:00:55 -080082 return;
83 }
Dan Sinclair8f524d62017-10-25 13:30:31 -040084
85 if (result.HasReturn())
86 info.GetReturnValue().Set(result.Return());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087}
88
Tom Sepez3a6d0582018-08-17 19:28:52 +000089template <class C, CJS_Result (C::*M)(CJS_Runtime*, v8::Local<v8::Value>)>
Tom Sepeza1160452015-02-19 10:00:55 -080090void JSPropSetter(const char* prop_name_string,
91 const char* class_name_string,
92 v8::Local<v8::String> property,
93 v8::Local<v8::Value> value,
94 const v8::PropertyCallbackInfo<void>& info) {
Tom Sepez82999fa2018-07-16 22:17:46 +000095 auto pObj = JSGetObject<C>(info.Holder());
Lei Zhangad1f7b42018-07-11 13:04:43 +000096 if (!pObj)
Tom Sepeza25fd092015-09-28 09:06:03 -070097 return;
dan sinclaircbe23db2017-10-19 14:29:33 -040098
Lei Zhangad1f7b42018-07-11 13:04:43 +000099 CJS_Runtime* pRuntime = pObj->GetRuntime();
Tom Sepezddaa40f2018-06-06 18:30:15 +0000100 if (!pRuntime)
Tom Sepezc5a14722017-02-24 15:31:12 -0800101 return;
dan sinclaircbe23db2017-10-19 14:29:33 -0400102
Tom Sepez3a6d0582018-08-17 19:28:52 +0000103 CJS_Result result = (pObj.Get()->*M)(pRuntime, value);
Dan Sinclair8f524d62017-10-25 13:30:31 -0400104 if (result.HasError()) {
105 pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
106 result.Error()));
Tom Sepeza1160452015-02-19 10:00:55 -0800107 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700108}
109
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110template <class C,
Tom Sepez3a6d0582018-08-17 19:28:52 +0000111 CJS_Result (C::*M)(CJS_Runtime*,
Dan Sinclair8f524d62017-10-25 13:30:31 -0400112 const std::vector<v8::Local<v8::Value>>&)>
Tom Sepeza1160452015-02-19 10:00:55 -0800113void JSMethod(const char* method_name_string,
114 const char* class_name_string,
115 const v8::FunctionCallbackInfo<v8::Value>& info) {
Tom Sepez82999fa2018-07-16 22:17:46 +0000116 auto pObj = JSGetObject<C>(info.Holder());
Lei Zhangad1f7b42018-07-11 13:04:43 +0000117 if (!pObj)
Tom Sepeza25fd092015-09-28 09:06:03 -0700118 return;
Dan Sinclaire4974922017-10-24 09:36:16 -0400119
Lei Zhangad1f7b42018-07-11 13:04:43 +0000120 CJS_Runtime* pRuntime = pObj->GetRuntime();
Tom Sepezddaa40f2018-06-06 18:30:15 +0000121 if (!pRuntime)
Tom Sepezc5a14722017-02-24 15:31:12 -0800122 return;
Dan Sinclaire4974922017-10-24 09:36:16 -0400123
Dan Sinclair8f524d62017-10-25 13:30:31 -0400124 std::vector<v8::Local<v8::Value>> parameters;
125 for (unsigned int i = 0; i < (unsigned int)info.Length(); i++)
126 parameters.push_back(info[i]);
127
Tom Sepez3a6d0582018-08-17 19:28:52 +0000128 CJS_Result result = (pObj.Get()->*M)(pRuntime, parameters);
Dan Sinclair8f524d62017-10-25 13:30:31 -0400129 if (result.HasError()) {
130 pRuntime->Error(JSFormatErrorString(class_name_string, method_name_string,
131 result.Error()));
Tom Sepeza1160452015-02-19 10:00:55 -0800132 return;
133 }
Dan Sinclair8f524d62017-10-25 13:30:31 -0400134
135 if (result.HasReturn())
136 info.GetReturnValue().Set(result.Return());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700137}
138
Dan Sinclair89d26c82017-10-26 12:21:28 -0400139#define JS_STATIC_PROP(err_name, prop_name, class_name) \
140 static void get_##prop_name##_static( \
141 v8::Local<v8::String> property, \
142 const v8::PropertyCallbackInfo<v8::Value>& info) { \
143 JSPropGetter<class_name, &class_name::get_##prop_name>( \
Dan Sinclairf7435522018-02-05 22:27:22 +0000144 #err_name, class_name::kName, property, info); \
Dan Sinclair89d26c82017-10-26 12:21:28 -0400145 } \
146 static void set_##prop_name##_static( \
147 v8::Local<v8::String> property, v8::Local<v8::Value> value, \
148 const v8::PropertyCallbackInfo<void>& info) { \
149 JSPropSetter<class_name, &class_name::set_##prop_name>( \
Dan Sinclairf7435522018-02-05 22:27:22 +0000150 #err_name, class_name::kName, property, value, info); \
Dan Sinclair89d26c82017-10-26 12:21:28 -0400151 }
152
Dan Sinclairf7435522018-02-05 22:27:22 +0000153#define JS_STATIC_METHOD(method_name, class_name) \
154 static void method_name##_static( \
155 const v8::FunctionCallbackInfo<v8::Value>& info) { \
156 JSMethod<class_name, &class_name::method_name>(#method_name, \
157 class_name::kName, info); \
Tom Sepeza1160452015-02-19 10:00:55 -0800158 }
159
Dan Sinclaire0345a42017-10-30 20:20:42 +0000160#endif // FXJS_JS_DEFINE_H_