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/jsview/js_plugin.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/jsview/models/plugin_model_impl.h"
20 #include "core/components_ng/pattern/plugin/plugin_model_ng.h"
21 
22 namespace OHOS::Ace {
GetInstance()23 PluginModel* PluginModel::GetInstance()
24 {
25 #ifdef NG_BUILD
26     static NG::PluginModelNG instance;
27     return &instance;
28 #else
29     if (Container::IsCurrentUseNewPipeline()) {
30         static NG::PluginModelNG instance;
31         return &instance;
32     } else {
33         static Framework::PluginModelImpl instance;
34         return &instance;
35     }
36 #endif
37 }
38 } // namespace OHOS::Ace
39 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo& info)40 void JSPlugin::Create(const JSCallbackInfo& info)
41 {
42     if (!info[0]->IsObject()) {
43         return;
44     }
45 
46     // Parse template
47     RequestPluginInfo pluginInfo;
48     auto obj = JSRef<JSObject>::Cast(info[0]);
49     auto templateObj = obj->GetProperty("template");
50     if (templateObj->IsObject()) {
51         auto jstemplateObj = JSRef<JSObject>::Cast(templateObj);
52         auto sourceVal = jstemplateObj->GetProperty("source");
53         if (sourceVal->IsString()) {
54             pluginInfo.pluginName = sourceVal->ToString();
55         }
56         auto abilityVal = jstemplateObj->GetProperty("ability");
57         if (!abilityVal->IsEmpty() && abilityVal->IsString()) {
58             pluginInfo.bundleName = abilityVal->ToString();
59         }
60 
61         auto bundleValue = jstemplateObj->GetProperty("bundleName");
62         if (!bundleValue->IsEmpty() && bundleValue->IsString()) {
63             pluginInfo.bundleName = bundleValue->ToString();
64         }
65     }
66     if (pluginInfo.bundleName.size() > PATH_MAX || pluginInfo.pluginName.size() > PATH_MAX) {
67         return;
68     }
69     // Parse data
70     auto dataValue = obj->GetProperty("data");
71 
72     PluginModel::GetInstance()->Create(pluginInfo);
73     if (dataValue->IsObject()) {
74         PluginModel::GetInstance()->SetData(dataValue->ToString());
75     }
76 }
77 
JsSize(const JSCallbackInfo& info)78 void JSPlugin::JsSize(const JSCallbackInfo& info)
79 {
80     if (!info[0]->IsObject()) {
81         return;
82     }
83 
84     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
85     JSRef<JSVal> widthValue = sizeObj->GetProperty("width");
86     CalcDimension width = 0.0_vp;
87     if (!ParseJsDimensionVp(widthValue, width)) {
88         return;
89     }
90     JSRef<JSVal> heightValue = sizeObj->GetProperty("height");
91     CalcDimension height = 0.0_vp;
92     if (!ParseJsDimensionVp(heightValue, height)) {
93         return;
94     }
95     PluginModel::GetInstance()->SetPluginSize(width.IsValid() ? width : 0.0_vp, height.IsValid() ? height : 0.0_vp);
96 }
97 
JsWidth(const JSCallbackInfo& info)98 void JSPlugin::JsWidth(const JSCallbackInfo& info)
99 {
100     CalcDimension value;
101     if (!ParseJsDimensionVp(info[0], value)) {
102         return;
103     }
104 
105     if (LessNotEqual(value.Value(), 0.0)) {
106         value.SetValue(0.0);
107     }
108 
109     PluginModel::GetInstance()->SetWidth(value.IsValid() ? value : 0.0_vp);
110 }
111 
JsHeight(const JSCallbackInfo& info)112 void JSPlugin::JsHeight(const JSCallbackInfo& info)
113 {
114     CalcDimension value;
115     if (!ParseJsDimensionVp(info[0], value)) {
116         return;
117     }
118 
119     if (LessNotEqual(value.Value(), 0.0)) {
120         value.SetValue(0.0);
121     }
122 
123     PluginModel::GetInstance()->SetHeight(value.IsValid() ? value : 0.0_vp);
124 }
125 
JsOnComplete(const JSCallbackInfo& info)126 void JSPlugin::JsOnComplete(const JSCallbackInfo& info)
127 {
128 #if defined(PLUGIN_COMPONENT_SUPPORTED)
129     if (info[0]->IsFunction()) {
130         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
131         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
132         auto OnComplete = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
133                                 const std::string& param) {
134             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
135             ACE_SCORING_EVENT("Plugin.OnComplete");
136             PipelineContext::SetCallBackNode(node);
137             func->Execute();
138         };
139         PluginModel::GetInstance()->SetOnComplete(std::move(OnComplete));
140     }
141 #endif
142 }
143 
JsOnError(const JSCallbackInfo& info)144 void JSPlugin::JsOnError(const JSCallbackInfo& info)
145 {
146 #if defined(PLUGIN_COMPONENT_SUPPORTED)
147     if (info[0]->IsFunction()) {
148         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
149         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
150         auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
151                             const std::string& param) {
152             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
153             ACE_SCORING_EVENT("Plugin.OnComplete");
154             std::vector<std::string> keys = { "errcode", "msg" };
155             PipelineContext::SetCallBackNode(node);
156             func->Execute(keys, param);
157         };
158         PluginModel::GetInstance()->SetOnError(std::move(onError));
159     }
160 #endif
161 }
162 
JSBind(BindingTarget globalObj)163 void JSPlugin::JSBind(BindingTarget globalObj)
164 {
165     JSClass<JSPlugin>::Declare("PluginComponent");
166     MethodOptions opt = MethodOptions::NONE;
167     JSClass<JSPlugin>::StaticMethod("create", &JSPlugin::Create, opt);
168     JSClass<JSPlugin>::StaticMethod("size", &JSPlugin::JsSize, opt);
169     JSClass<JSPlugin>::StaticMethod("width", &JSPlugin::JsWidth);
170     JSClass<JSPlugin>::StaticMethod("height", &JSPlugin::JsHeight);
171     JSClass<JSPlugin>::StaticMethod("onComplete", &JSPlugin::JsOnComplete);
172     JSClass<JSPlugin>::StaticMethod("onError", &JSPlugin::JsOnError);
173     JSClass<JSPlugin>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
174     JSClass<JSPlugin>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
175     JSClass<JSPlugin>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
176     JSClass<JSPlugin>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
177     JSClass<JSPlugin>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
178     JSClass<JSPlugin>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
179     JSClass<JSPlugin>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
180     JSClass<JSPlugin>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
181 
182     JSClass<JSPlugin>::InheritAndBind<JSViewAbstract>(globalObj);
183 }
184 } // namespace OHOS::Ace::Framework
185