1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
17
18 #include "base/json/json_util.h"
19 #include "base/log/ace_trace.h"
20 #include "base/log/log.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_xcomponent.h"
22
23 namespace OHOS::Ace::Framework {
24
JsFunction(const JSRef<JSFunc> & jsFunction)25 JsFunction::JsFunction(const JSRef<JSFunc>& jsFunction)
26 {
27 jsFunction_ = jsFunction;
28 }
29
JsFunction(const JSRef<JSObject> & jsObject,const JSRef<JSFunc> & jsFunction)30 JsFunction::JsFunction(const JSRef<JSObject>& jsObject, const JSRef<JSFunc>& jsFunction)
31 {
32 jsThis_ = jsObject;
33 jsFunction_ = jsFunction;
34 }
35
JsWeakFunction(const JSRef<JSFunc> & jsFunction)36 JsWeakFunction::JsWeakFunction(const JSRef<JSFunc>& jsFunction)
37 {
38 jsWeakFunction_ = jsFunction;
39 }
40
JsWeakFunction(const JSRef<JSObject> & jsObject,const JSRef<JSFunc> & jsFunction)41 JsWeakFunction::JsWeakFunction(const JSRef<JSObject>& jsObject, const JSRef<JSFunc>& jsFunction)
42 {
43 jsThis_ = jsObject;
44 jsWeakFunction_ = jsFunction;
45 }
46
~JsFunction()47 JsFunction::~JsFunction() {}
48
Execute(const JSRef<JSObject> & jsParamsObject)49 void JsFunctionBase::Execute(const JSRef<JSObject>& jsParamsObject)
50 {
51 JSRef<JSVal> paramObj = JSRef<JSVal>::Cast(jsParamsObject);
52 ExecuteJS(1, ¶mObj);
53 }
54
Execute(const std::vector<std::string> & keys,const std::string & param)55 void JsFunctionBase::Execute(const std::vector<std::string>& keys, const std::string& param)
56 {
57 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(param);
58 if (!argsPtr) {
59 return;
60 }
61 JSRef<JSObject> eventInfo = JSRef<JSObject>::New();
62 for (auto iter = keys.begin(); iter != keys.end(); iter++) {
63 const std::string key = *iter;
64 const auto value = argsPtr->GetValue(key);
65 if (!value) {
66 LOGI("key[%{public}s] is not exist.", key.c_str());
67 continue;
68 }
69 ExecuteInternal(value, key, eventInfo);
70 }
71
72 JSRef<JSVal> paramObj = JSRef<JSVal>::Cast(eventInfo);
73 ExecuteJS(1, ¶mObj);
74 }
75
ExecuteInternal(const std::unique_ptr<JsonValue> & value,const std::string & key,const JSRef<JSObject> & eventInfo)76 void JsFunctionBase::ExecuteInternal(const std::unique_ptr<JsonValue>& value, const std::string& key,
77 const JSRef<JSObject>& eventInfo)
78 {
79 if (value->IsString()) {
80 eventInfo->SetProperty<std::string>(key.c_str(), value->GetString().c_str());
81 } else if (value->IsNumber()) {
82 eventInfo->SetProperty<double>(key.c_str(), value->GetDouble());
83 } else if (value->IsBool()) {
84 eventInfo->SetProperty<bool>(key.c_str(), value->GetBool());
85 } else if (value->IsObject()) {
86 eventInfo->SetPropertyJsonObject(key.c_str(), value->ToString().c_str());
87 } else if (value->IsArray()) {
88 JSRef<JSArray> valueArray = JSRef<JSArray>::New();
89 for (auto index = 0; index < value->GetArraySize(); index++) {
90 auto item = value->GetArrayItem(index);
91 if (item && item->IsString()) {
92 valueArray->SetValueAt(index, JSRef<JSVal>::Make(ToJSValue(item->GetString())));
93 }
94 }
95 eventInfo->SetPropertyObject(key.c_str(), valueArray);
96 }
97 }
98
ExecuteNew(const std::vector<std::string> & keys,const std::string & param)99 void JsFunctionBase::ExecuteNew(const std::vector<std::string>& keys, const std::string& param)
100 {
101 JSRef<JSVal> jsVal;
102 if (keys.size() > 1) {
103 auto result = XComponentClient::GetInstance().GetJSVal(keys[1], jsVal);
104 RefPtr<JSXComponentController> controller =
105 XComponentClient::GetInstance().GetControllerFromJSXComponentControllersMap(keys[1]);
106 if (result && controller) {
107 controller->SetXComponentContext(jsVal);
108 }
109 }
110 ExecuteJS(1, &jsVal);
111 }
112
ExecuteJS(int argc,JSRef<JSVal> argv[])113 JSRef<JSVal> JsWeakFunction::ExecuteJS(int argc, JSRef<JSVal> argv[])
114 {
115 JAVASCRIPT_EXECUTION_SCOPE_STATIC
116 ACE_FUNCTION_TRACE();
117 JSRef<JSVal> jsObject = jsThis_.Lock();
118 auto jsFunction = jsWeakFunction_.Lock();
119 if (jsFunction.IsEmpty()) {
120 LOGW("js function is null.");
121 return {};
122 }
123 JSRef<JSVal> result = jsFunction->Call(jsObject, argc, argv);
124 return result;
125 }
126
ExecuteJS(int argc,JSRef<JSVal> argv[])127 JSRef<JSVal> JsFunction::ExecuteJS(int argc, JSRef<JSVal> argv[])
128 {
129 JAVASCRIPT_EXECUTION_SCOPE_STATIC
130 ACE_FUNCTION_TRACE();
131
132 JSRef<JSVal> jsObject = jsThis_.Lock();
133 JSRef<JSVal> result = jsFunction_->Call(jsObject, argc, argv);
134 return result;
135 }
136
CreateEventTargetObject(const BaseEventInfo & info)137 JSRef<JSObject> CreateEventTargetObject(const BaseEventInfo& info)
138 {
139 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
140 JSRef<JSObject> target = objectTemplate->NewInstance();
141 JSRef<JSObject> area = objectTemplate->NewInstance();
142 JSRef<JSObject> offset = objectTemplate->NewInstance();
143 JSRef<JSObject> globalOffset = objectTemplate->NewInstance();
144 const auto& localOffset = info.GetTarget().area.GetOffset();
145 const auto& origin = info.GetTarget().origin;
146 offset->SetProperty<double>("x", localOffset.GetX().ConvertToVp());
147 offset->SetProperty<double>("y", localOffset.GetY().ConvertToVp());
148 globalOffset->SetProperty<double>("x", (origin.GetX().ConvertToVp() + localOffset.GetX().ConvertToVp()));
149 globalOffset->SetProperty<double>("y", (origin.GetY().ConvertToVp() + localOffset.GetY().ConvertToVp()));
150 area->SetPropertyObject("position", offset);
151 area->SetPropertyObject("globalPosition", globalOffset);
152 area->SetProperty<double>("width", info.GetTarget().area.GetWidth().ConvertToVp());
153 area->SetProperty<double>("height", info.GetTarget().area.GetHeight().ConvertToVp());
154 target->SetPropertyObject("area", area);
155 return target;
156 }
157
158 } // namespace OHOS::Ace::Framework
159