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/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/jsview/models/form_model_impl.h"
20 #include "core/components_ng/pattern/form/form_model_ng.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_utils.h"
22
23 #if !defined(WEARABLE_PRODUCT)
24 #include "frameworks/core/components/form/form_component.h"
25 #endif
26
27 namespace OHOS::Ace {
28
29 std::unique_ptr<FormModel> FormModel::instance_ = nullptr;
30 std::mutex FormModel::mutex_;
31
GetInstance()32 FormModel* FormModel::GetInstance()
33 {
34 if (!instance_) {
35 std::lock_guard<std::mutex> lock(mutex_);
36 if (!instance_) {
37 #ifdef NG_BUILD
38 instance_.reset(new NG::FormModelNG());
39 #else
40 if (Container::IsCurrentUseNewPipeline()) {
41 instance_.reset(new NG::FormModelNG());
42 } else {
43 instance_.reset(new Framework::FormModelImpl());
44 }
45 #endif
46 }
47 }
48 return instance_.get();
49 }
50
51 } // namespace OHOS::Ace
52
53 namespace OHOS::Ace::Framework {
54
Create(const JSCallbackInfo & info)55 void JSForm::Create(const JSCallbackInfo& info)
56 {
57 if (info.Length() == 0 || !info[0]->IsObject()) {
58 return;
59 }
60 auto obj = JSRef<JSObject>::Cast(info[0]);
61 JSRef<JSVal> id = obj->GetProperty("id");
62 JSRef<JSVal> name = obj->GetProperty("name");
63 JSRef<JSVal> bundle = obj->GetProperty("bundle");
64 JSRef<JSVal> ability = obj->GetProperty("ability");
65 JSRef<JSVal> module = obj->GetProperty("module");
66 JSRef<JSVal> dimension = obj->GetProperty("dimension");
67 JSRef<JSVal> temporary = obj->GetProperty("temporary");
68 JSRef<JSVal> wantValue = obj->GetProperty("want");
69 JSRef<JSVal> renderingMode = obj->GetProperty("renderingMode");
70 JSRef<JSVal> shape = obj->GetProperty("shape");
71 RequestFormInfo formInfo;
72 if (id->IsString()) {
73 if (!StringUtils::IsNumber(id->ToString())) {
74 TAG_LOGE(AceLogTag::ACE_FORM, "Invalid form id : %{public}s", id->ToString().c_str());
75 return;
76 }
77 int64_t inputFormId = StringUtils::StringToLongInt(id->ToString().c_str(), -1);
78 if (inputFormId == -1) {
79 TAG_LOGE(AceLogTag::ACE_FORM, "StringToLongInt failed : %{public}s", id->ToString().c_str());
80 return;
81 }
82 formInfo.id = inputFormId;
83 } else if (id->IsNumber()) {
84 formInfo.id = id->ToNumber<int64_t>();
85 }
86 TAG_LOGI(AceLogTag::ACE_FORM, "JSForm Create, info.id: %{public}" PRId64, formInfo.id);
87 formInfo.cardName = name->ToString();
88 formInfo.bundleName = bundle->ToString();
89 formInfo.abilityName = ability->ToString();
90 formInfo.moduleName = module->ToString();
91 if (!dimension->IsNull() && !dimension->IsEmpty()) {
92 formInfo.dimension = dimension->ToNumber<int32_t>();
93 }
94 formInfo.temporary = temporary->ToBoolean();
95 if (!wantValue->IsNull() && wantValue->IsObject()) {
96 formInfo.wantWrap = CreateWantWrapFromNapiValue(wantValue);
97 }
98 if (!renderingMode->IsNull() && !renderingMode->IsEmpty()) {
99 formInfo.renderingMode = renderingMode->ToNumber<int32_t>();
100 }
101 if (!shape->IsNull() && !shape->IsEmpty()) {
102 formInfo.shape = shape->ToNumber<int32_t>();
103 }
104 FormModel::GetInstance()->Create(formInfo);
105 }
106
SetSize(const JSCallbackInfo & info)107 void JSForm::SetSize(const JSCallbackInfo& info)
108 {
109 JSViewAbstract::JsSize(info);
110
111 if (info.Length() == 0 || !info[0]->IsObject()) {
112 return;
113 }
114 Dimension width = 0.0_vp;
115 Dimension height = 0.0_vp;
116
117 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
118 JSRef<JSVal> widthValue = sizeObj->GetProperty("width");
119 if (!widthValue->IsNull() && !widthValue->IsEmpty()) {
120 if (widthValue->IsNumber()) {
121 width = Dimension(widthValue->ToNumber<double>(), DimensionUnit::VP);
122 } else if (widthValue->IsString()) {
123 width = StringUtils::StringToDimension(widthValue->ToString(), true);
124 }
125 }
126
127 JSRef<JSVal> heightValue = sizeObj->GetProperty("height");
128 if (!heightValue->IsNull() && !heightValue->IsEmpty()) {
129 if (heightValue->IsNumber()) {
130 height = Dimension(heightValue->ToNumber<double>(), DimensionUnit::VP);
131 } else if (heightValue->IsString()) {
132 height = StringUtils::StringToDimension(heightValue->ToString(), true);
133 }
134 }
135 FormModel::GetInstance()->SetSize(width, height);
136 }
137
SetDimension(int32_t value)138 void JSForm::SetDimension(int32_t value)
139 {
140 FormModel::GetInstance()->SetDimension(value);
141 }
142
AllowUpdate(const JSCallbackInfo & info)143 void JSForm::AllowUpdate(const JSCallbackInfo& info)
144 {
145 if (info.Length() <= 0 || !info[0]->IsBoolean()) {
146 return;
147 }
148
149 auto allowUpdate = info[0]->ToBoolean();
150 FormModel::GetInstance()->AllowUpdate(allowUpdate);
151 }
152
SetVisibility(const JSCallbackInfo & info)153 void JSForm::SetVisibility(const JSCallbackInfo& info)
154 {
155 if (info.Length() <= 0 || !info[0]->IsNumber()) {
156 return;
157 }
158
159 auto type = info[0]->ToNumber<int32_t>();
160 FormModel::GetInstance()->SetVisibility(VisibleType(type));
161 }
162
SetModuleName(const JSCallbackInfo & info)163 void JSForm::SetModuleName(const JSCallbackInfo& info)
164 {
165 if (info.Length() <= 0 || !info[0]->IsString()) {
166 return;
167 }
168
169 auto moduleName = info[0]->ToString();
170 FormModel::GetInstance()->SetModuleName(moduleName);
171 }
172
JsOnAcquired(const JSCallbackInfo & info)173 void JSForm::JsOnAcquired(const JSCallbackInfo& info)
174 {
175 if (info[0]->IsFunction()) {
176 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
177 auto onAcquired = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
178 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
179 ACE_SCORING_EVENT("Form.onAcquired");
180 std::vector<std::string> keys = { "id", "idString", "isLocked" };
181 func->Execute(keys, param);
182 };
183 FormModel::GetInstance()->SetOnAcquired(std::move(onAcquired));
184 }
185 }
186
JsOnError(const JSCallbackInfo & info)187 void JSForm::JsOnError(const JSCallbackInfo& info)
188 {
189 if (info[0]->IsFunction()) {
190 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
191 auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
192 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
193 ACE_SCORING_EVENT("Form.onError");
194 std::vector<std::string> keys = { "errcode", "msg" };
195 func->Execute(keys, param);
196 };
197 FormModel::GetInstance()->SetOnError(std::move(onError));
198 }
199 }
200
JsOnUninstall(const JSCallbackInfo & info)201 void JSForm::JsOnUninstall(const JSCallbackInfo& info)
202 {
203 if (info[0]->IsFunction()) {
204 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
205 auto onUninstall = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
206 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
207 ACE_SCORING_EVENT("Form.onUninstall");
208 std::vector<std::string> keys = { "id", "idString", "isLocked" };
209 func->Execute(keys, param);
210 };
211 FormModel::GetInstance()->SetOnUninstall(std::move(onUninstall));
212 }
213 }
214
JsOnRouter(const JSCallbackInfo & info)215 void JSForm::JsOnRouter(const JSCallbackInfo& info)
216 {
217 if (info[0]->IsFunction()) {
218 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
219 auto onRouter = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
220 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
221 ACE_SCORING_EVENT("Form.onRouter");
222 std::vector<std::string> keys = { "action" };
223 func->Execute(keys, param);
224 };
225 FormModel::GetInstance()->SetOnRouter(std::move(onRouter));
226 }
227 }
228
JsOnLoad(const JSCallbackInfo & info)229 void JSForm::JsOnLoad(const JSCallbackInfo& info)
230 {
231 if (info[0]->IsFunction()) {
232 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
233 auto onLoad = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
234 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
235 ACE_SCORING_EVENT("Form.onLoad");
236 std::vector<std::string> keys;
237 func->Execute(keys, param);
238 };
239 FormModel::GetInstance()->SetOnLoad(std::move(onLoad));
240 }
241 }
242
JsObscured(const JSCallbackInfo & info)243 void JSForm::JsObscured(const JSCallbackInfo& info)
244 {
245 if (info[0]->IsUndefined()) {
246 TAG_LOGE(AceLogTag::ACE_FORM, "Obscured reasons undefined");
247 return;
248 }
249 if (!info[0]->IsArray()) {
250 TAG_LOGE(AceLogTag::ACE_FORM, "Obscured reasons not Array");
251 return;
252 }
253 auto obscuredArray = JSRef<JSArray>::Cast(info[0]);
254 size_t size = obscuredArray->Length();
255 std::vector<ObscuredReasons> reasons;
256 reasons.reserve(size);
257 for (size_t i = 0; i < size; ++i) {
258 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
259 if (reason->IsNumber()) {
260 reasons.push_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
261 }
262 }
263 FormModel::GetInstance()->SetObscured(reasons);
264 }
265
JSBind(BindingTarget globalObj)266 void JSForm::JSBind(BindingTarget globalObj)
267 {
268 JSClass<JSForm>::Declare("FormComponent");
269 MethodOptions opt = MethodOptions::NONE;
270 JSClass<JSForm>::StaticMethod("create", &JSForm::Create, opt);
271 JSClass<JSForm>::StaticMethod("size", &JSForm::SetSize, opt);
272 JSClass<JSForm>::StaticMethod("dimension", &JSForm::SetDimension, opt);
273 JSClass<JSForm>::StaticMethod("allowUpdate", &JSForm::AllowUpdate, opt);
274 JSClass<JSForm>::StaticMethod("visibility", &JSForm::SetVisibility, opt);
275 JSClass<JSForm>::StaticMethod("moduleName", &JSForm::SetModuleName, opt);
276 JSClass<JSForm>::StaticMethod("clip", &JSViewAbstract::JsClip, opt);
277 JSClass<JSForm>::StaticMethod("obscured", &JSForm::JsObscured);
278
279 JSClass<JSForm>::StaticMethod("onAcquired", &JSForm::JsOnAcquired);
280 JSClass<JSForm>::StaticMethod("onError", &JSForm::JsOnError);
281 JSClass<JSForm>::StaticMethod("onUninstall", &JSForm::JsOnUninstall);
282 JSClass<JSForm>::StaticMethod("onRouter", &JSForm::JsOnRouter);
283 JSClass<JSForm>::StaticMethod("onLoad", &JSForm::JsOnLoad);
284 JSClass<JSForm>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
285 JSClass<JSForm>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
286 JSClass<JSForm>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
287 JSClass<JSForm>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
288 JSClass<JSForm>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
289 JSClass<JSForm>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
290 JSClass<JSForm>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
291 JSClass<JSForm>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
292
293 JSClass<JSForm>::InheritAndBind<JSViewAbstract>(globalObj);
294 }
295
296 } // namespace OHOS::Ace::Framework
297