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