1 /*
2 * Copyright (c) 2021-2022 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_form.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/geometry/ng/size_t.h"
20 #include "base/log/ace_scoring_log.h"
21 #include "core/components_ng/base/view_abstract.h"
22 #include "core/components_ng/pattern/form/form_view.h"
23 #include "frameworks/bridge/declarative_frontend/jsview/js_utils.h"
24 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
25
26 #if !defined(WEARABLE_PRODUCT)
27 #include "frameworks/core/components/form/form_component.h"
28 #endif
29
30 namespace OHOS::Ace::Framework {
31
Create(const JSCallbackInfo & info)32 void JSForm::Create(const JSCallbackInfo& info)
33 {
34 if (info.Length() == 0 || !info[0]->IsObject()) {
35 LOGE("form create fail due to FormComponent construct param is empty or type is not Object");
36 return;
37 }
38 auto obj = JSRef<JSObject>::Cast(info[0]);
39 JSRef<JSVal> id = obj->GetProperty("id");
40 JSRef<JSVal> name = obj->GetProperty("name");
41 JSRef<JSVal> bundle = obj->GetProperty("bundle");
42 JSRef<JSVal> ability = obj->GetProperty("ability");
43 JSRef<JSVal> module = obj->GetProperty("module");
44 JSRef<JSVal> dimension = obj->GetProperty("dimension");
45 JSRef<JSVal> temporary = obj->GetProperty("temporary");
46 JSRef<JSVal> wantValue = obj->GetProperty("want");
47
48 LOGD("js form create id:%{public}d, name:%{public}s, bundle:%{public}s, ability:%{public}s, module:%{public}s, "
49 "temporary:%{public}s",
50 id->ToNumber<int32_t>(), name->ToString().c_str(), bundle->ToString().c_str(), ability->ToString().c_str(),
51 module->ToString().c_str(), temporary->ToString().c_str());
52
53 RequestFormInfo fomInfo;
54 fomInfo.id = id->ToNumber<int32_t>();
55 fomInfo.cardName = name->ToString();
56 fomInfo.bundleName = bundle->ToString();
57 fomInfo.abilityName = ability->ToString();
58 fomInfo.moduleName = module->ToString();
59 if (!dimension->IsNull() && !dimension->IsEmpty()) {
60 fomInfo.dimension = dimension->ToNumber<int32_t>();
61 }
62 fomInfo.temporary = temporary->ToBoolean();
63 if (!wantValue->IsNull() && wantValue->IsObject()) {
64 fomInfo.wantWrap = CreateWantWrapFromNapiValue(wantValue);
65 }
66
67 if (Container::IsCurrentUseNewPipeline()) {
68 NG::FormView::Create(fomInfo);
69 return;
70 }
71
72 RefPtr<FormComponent> form = AceType::MakeRefPtr<OHOS::Ace::FormComponent>();
73 form->SetFormRequestInfo(fomInfo);
74 form->SetInspectorTag("FormComponent");
75 ViewStackProcessor::GetInstance()->Push(form, false);
76 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
77 boxComponent->SetMouseAnimationType(HoverAnimationType::SCALE);
78 }
79
SetSize(const JSCallbackInfo & info)80 void JSForm::SetSize(const JSCallbackInfo& info)
81 {
82 if (Container::IsCurrentUseNewPipeline()) {
83 JSViewAbstract::JsSize(info);
84 return;
85 }
86
87 if (info.Length() == 0 || !info[0]->IsObject()) {
88 LOGW("form set size fail due to FormComponent construct param is empty or type is not Object");
89 }
90 Dimension width = 0.0_vp;
91 Dimension height = 0.0_vp;
92
93 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
94 JSRef<JSVal> widthValue = sizeObj->GetProperty("width");
95 if (!widthValue->IsNull() && !widthValue->IsEmpty()) {
96 if (widthValue->IsNumber()) {
97 width = Dimension(widthValue->ToNumber<double>(), DimensionUnit::VP);
98 } else if (widthValue->IsString()) {
99 width = StringUtils::StringToDimension(widthValue->ToString(), true);
100 }
101 }
102
103 JSRef<JSVal> heightValue = sizeObj->GetProperty("height");
104 if (!heightValue->IsNull() && !heightValue->IsEmpty()) {
105 if (heightValue->IsNumber()) {
106 height = Dimension(heightValue->ToNumber<double>(), DimensionUnit::VP);
107 } else if (heightValue->IsString()) {
108 height = StringUtils::StringToDimension(heightValue->ToString(), true);
109 }
110 }
111 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
112 if (form) {
113 form->SetCardSize(width.IsValid() ? width : 0.0_vp, height.IsValid() ? height : 0.0_vp);
114 }
115 }
116
SetDimension(int32_t value)117 void JSForm::SetDimension(int32_t value)
118 {
119 if (Container::IsCurrentUseNewPipeline()) {
120 NG::FormView::SetDimension(value);
121 return;
122 }
123
124 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
125 if (form) {
126 form->SetDimension(value);
127 }
128 }
129
AllowUpdate(const JSCallbackInfo & info)130 void JSForm::AllowUpdate(const JSCallbackInfo& info)
131 {
132 if (info.Length() <= 0 || !info[0]->IsBoolean()) {
133 LOGE("param is not valid");
134 return;
135 }
136
137 auto allowUpdate = info[0]->ToBoolean();
138 if (Container::IsCurrentUseNewPipeline()) {
139 NG::FormView::SetAllowUpdate(allowUpdate);
140 return;
141 }
142
143 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
144 if (form) {
145 form->SetAllowUpdate(allowUpdate);
146 }
147 }
148
SetVisibility(const JSCallbackInfo & info)149 void JSForm::SetVisibility(const JSCallbackInfo& info)
150 {
151 if (info.Length() <= 0 || !info[0]->IsNumber()) {
152 LOGE("param is not valid");
153 return;
154 }
155
156 auto type = info[0]->ToNumber<int32_t>();
157 if (Container::IsCurrentUseNewPipeline()) {
158 NG::ViewAbstract::SetVisibility(VisibleType(type));
159 return;
160 }
161
162 auto component = ViewStackProcessor::GetInstance()->GetDisplayComponent();
163 auto display = AceType::DynamicCast<DisplayComponent>(component);
164 display->SetVisible(VisibleType(type));
165 }
166
SetModuleName(const JSCallbackInfo & info)167 void JSForm::SetModuleName(const JSCallbackInfo& info)
168 {
169 if (info.Length() <= 0 || !info[0]->IsString()) {
170 LOGE("param is not valid");
171 return;
172 }
173
174 auto moduleName = info[0]->ToString();
175 if (Container::IsCurrentUseNewPipeline()) {
176 NG::FormView::SetModuleName(moduleName);
177 return;
178 }
179
180 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
181 if (form) {
182 form->SetModuleName(moduleName);
183 }
184 }
185
JsOnAcquired(const JSCallbackInfo & info)186 void JSForm::JsOnAcquired(const JSCallbackInfo& info)
187 {
188 if (Container::IsCurrentUseNewPipeline()) {
189 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
190 auto onAcquired = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
191 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
192 ACE_SCORING_EVENT("Form.onAcquired");
193 std::vector<std::string> keys = { "id" };
194 func->Execute(keys, param);
195 };
196 NG::FormView::SetOnAcquired(std::move(onAcquired));
197 return;
198 }
199
200 if (info[0]->IsFunction()) {
201 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
202 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
203
204 auto onAppearId =
205 EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
206 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
207 LOGI("onAcquire send:%{public}s", param.c_str());
208 std::vector<std::string> keys = { "id" };
209 ACE_SCORING_EVENT("Form.onAcquired");
210 func->Execute(keys, param);
211 });
212 form->SetOnAcquireFormEventId(onAppearId);
213 }
214 }
215
JsOnError(const JSCallbackInfo & info)216 void JSForm::JsOnError(const JSCallbackInfo& info)
217 {
218 if (Container::IsCurrentUseNewPipeline()) {
219 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
220 auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
221 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
222 ACE_SCORING_EVENT("Form.onError");
223 std::vector<std::string> keys = { "errcode", "msg" };
224 func->Execute(keys, param);
225 };
226 NG::FormView::SetOnError(std::move(onError));
227 return;
228 }
229
230 if (info[0]->IsFunction()) {
231 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
232 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
233
234 auto onErrorId =
235 EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
236 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
237 LOGI("onError send:%{public}s", param.c_str());
238 std::vector<std::string> keys = { "errcode", "msg" };
239 ACE_SCORING_EVENT("Form.onError");
240 func->Execute(keys, param);
241 });
242
243 form->SetOnErrorEventId(onErrorId);
244 }
245 }
246
JsOnUninstall(const JSCallbackInfo & info)247 void JSForm::JsOnUninstall(const JSCallbackInfo& info)
248 {
249 if (Container::IsCurrentUseNewPipeline()) {
250 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
251 auto onUninstall = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
252 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
253 ACE_SCORING_EVENT("Form.onUninstall");
254 std::vector<std::string> keys = { "id" };
255 func->Execute(keys, param);
256 };
257 NG::FormView::SetOnUninstall(std::move(onUninstall));
258 return;
259 }
260
261 if (info[0]->IsFunction()) {
262 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
263 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
264
265 auto onUninstallId =
266 EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
267 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
268 LOGI("onUninstall send:%{public}s", param.c_str());
269 std::vector<std::string> keys = { "id" };
270 ACE_SCORING_EVENT("Form.onUninstall");
271 func->Execute(keys, param);
272 });
273
274 form->SetOnUninstallEventId(onUninstallId);
275 }
276 }
277
JsOnRouter(const JSCallbackInfo & info)278 void JSForm::JsOnRouter(const JSCallbackInfo& info)
279 {
280 if (Container::IsCurrentUseNewPipeline()) {
281 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
282 auto onRouter = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
283 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
284 ACE_SCORING_EVENT("Form.onRouter");
285 std::vector<std::string> keys = { "action" };
286 func->Execute(keys, param);
287 };
288 NG::FormView::SetOnRouter(std::move(onRouter));
289 return;
290 }
291
292 if (info[0]->IsFunction()) {
293 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
294 auto form = AceType::DynamicCast<FormComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
295
296 auto onRouterId =
297 EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
298 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
299 LOGI("onRouter send:%{public}s", param.c_str());
300 std::vector<std::string> keys = { "action" };
301 ACE_SCORING_EVENT("Form.onRouter");
302 func->Execute(keys, param);
303 });
304
305 form->SetOnRouterEventId(onRouterId);
306 }
307 }
308
JSBind(BindingTarget globalObj)309 void JSForm::JSBind(BindingTarget globalObj)
310 {
311 JSClass<JSForm>::Declare("FormComponent");
312 MethodOptions opt = MethodOptions::NONE;
313 JSClass<JSForm>::StaticMethod("create", &JSForm::Create, opt);
314 JSClass<JSForm>::StaticMethod("size", &JSForm::SetSize, opt);
315 JSClass<JSForm>::StaticMethod("dimension", &JSForm::SetDimension, opt);
316 JSClass<JSForm>::StaticMethod("allowUpdate", &JSForm::AllowUpdate, opt);
317 JSClass<JSForm>::StaticMethod("visibility", &JSForm::SetVisibility, opt);
318 JSClass<JSForm>::StaticMethod("moduleName", &JSForm::SetModuleName, opt);
319 JSClass<JSForm>::StaticMethod("clip", &JSViewAbstract::JsClip, opt);
320
321 JSClass<JSForm>::StaticMethod("onAcquired", &JSForm::JsOnAcquired);
322 JSClass<JSForm>::StaticMethod("onError", &JSForm::JsOnError);
323 JSClass<JSForm>::StaticMethod("onUninstall", &JSForm::JsOnUninstall);
324 JSClass<JSForm>::StaticMethod("onRouter", &JSForm::JsOnRouter);
325 JSClass<JSForm>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
326 JSClass<JSForm>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
327 JSClass<JSForm>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
328 JSClass<JSForm>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
329 JSClass<JSForm>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
330 JSClass<JSForm>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
331
332 JSClass<JSForm>::Inherit<JSViewAbstract>();
333 JSClass<JSForm>::Bind<>(globalObj);
334 }
335
336 } // namespace OHOS::Ace::Framework
337