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 "bridge/declarative_frontend/jsview/js_view_abstract.h"
17
18 #include <algorithm>
19 #include <cstdint>
20 #include <functional>
21 #include <memory>
22 #include <optional>
23 #include <regex>
24 #include <string>
25 #include <utility>
26 #include <vector>
27
28 #include "base/geometry/calc_dimension.h"
29 #include "base/geometry/dimension.h"
30 #include "base/geometry/matrix4.h"
31 #include "base/geometry/ng/offset_t.h"
32 #include "base/geometry/ng/vector.h"
33 #include "base/geometry/shape.h"
34 #include "base/json/json_util.h"
35 #include "base/log/ace_scoring_log.h"
36 #include "base/memory/ace_type.h"
37 #include "base/memory/referenced.h"
38 #include "base/utils/utils.h"
39 #include "bridge/common/utils/utils.h"
40 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
41 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
42 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
43 #include "bridge/declarative_frontend/engine/functions/js_function.h"
44 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
45 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
47 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
48 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
49 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
50 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
51 #include "bridge/declarative_frontend/jsview/js_utils.h"
52 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
53 #include "bridge/declarative_frontend/jsview/js_view_context.h"
54 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
55 #include "core/components/common/layout/screen_system_manager.h"
56 #include "core/components/common/properties/animation_option.h"
57 #include "core/components/common/properties/border_image.h"
58 #include "core/components/common/properties/color.h"
59 #include "core/components/common/properties/decoration.h"
60 #include "core/components/common/properties/shadow.h"
61 #include "core/components_ng/base/view_abstract_model.h"
62 #include "core/components_ng/pattern/menu/menu_pattern.h"
63 #include "core/components_ng/pattern/overlay/modal_style.h"
64 #include "core/components_ng/property/safe_area_insets.h"
65 #include "core/gestures/gesture_info.h"
66 #include "core/image/image_source_info.h"
67 #ifdef PLUGIN_COMPONENT_SUPPORTED
68 #include "core/common/plugin_manager.h"
69 #endif
70 #include "core/common/card_scope.h"
71 #include "core/common/container.h"
72 #include "core/components/progress/progress_theme.h"
73 #include "core/components_ng/base/view_abstract_model_ng.h"
74 #include "core/components_ng/base/view_stack_model.h"
75 #include "core/components_ng/property/progress_mask_property.h"
76
77 namespace OHOS::Ace {
78
79 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
80 std::mutex ViewAbstractModel::mutex_;
81 using DoubleBindCallback = std::function<void(const std::string&)>;
82
GetInstance()83 ViewAbstractModel* ViewAbstractModel::GetInstance()
84 {
85 if (!instance_) {
86 std::lock_guard<std::mutex> lock(mutex_);
87 if (!instance_) {
88 #ifdef NG_BUILD
89 instance_.reset(new NG::ViewAbstractModelNG());
90 #else
91 if (Container::IsCurrentUseNewPipeline()) {
92 instance_.reset(new NG::ViewAbstractModelNG());
93 } else {
94 instance_.reset(new Framework::ViewAbstractModelImpl());
95 }
96 #endif
97 }
98 }
99 return instance_.get();
100 }
101
102 } // namespace OHOS::Ace
103
104 namespace OHOS::Ace::Framework {
105 namespace {
106
107 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
108 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
109 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
110 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
111 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
112 constexpr int32_t MAX_ALIGN_VALUE = 8;
113 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
114 constexpr double FULL_DIMENSION = 100.0;
115 constexpr double HALF_DIMENSION = 50.0;
116 constexpr double ROUND_UNIT = 360.0;
117 constexpr double VISIBLE_RATIO_MIN = 0.0;
118 constexpr double VISIBLE_RATIO_MAX = 1.0;
119 constexpr int32_t MIN_ROTATE_VECTOR_Z = 9;
120 constexpr int32_t PLATFORM_VERSION_TEN = 10;
121 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
122 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
123 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
124 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
125 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
126 constexpr float MAX_ANGLE = 360.0f;
127 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
128 const std::string SHEET_HEIGHT_MEDIUM = "medium";
129 const std::string SHEET_HEIGHT_LARGE = "large";
130 const std::string SHEET_HEIGHT_AUTO = "auto";
131
CheckJSCallbackInfo(const std::string & callerName,const JSCallbackInfo & info,std::vector<JSCallbackInfoType> & infoTypes)132 bool CheckJSCallbackInfo(
133 const std::string& callerName, const JSCallbackInfo& info, std::vector<JSCallbackInfoType>& infoTypes)
134 {
135 if (info.Length() < 1) {
136 LOGE("%{public}s: The arg is supposed to have at least one argument", callerName.c_str());
137 return false;
138 }
139 bool typeVerified = false;
140 std::string unrecognizedType;
141 auto tmpInfo = info[0];
142 for (const auto& infoType : infoTypes) {
143 switch (infoType) {
144 case JSCallbackInfoType::STRING:
145 if (tmpInfo->IsString()) {
146 typeVerified = true;
147 } else {
148 unrecognizedType += "string|";
149 }
150 break;
151 case JSCallbackInfoType::NUMBER:
152 if (tmpInfo->IsNumber()) {
153 typeVerified = true;
154 } else {
155 unrecognizedType += "number|";
156 }
157 break;
158 case JSCallbackInfoType::OBJECT:
159 if (tmpInfo->IsObject()) {
160 typeVerified = true;
161 } else {
162 unrecognizedType += "object|";
163 }
164 break;
165 case JSCallbackInfoType::FUNCTION:
166 if (tmpInfo->IsFunction()) {
167 typeVerified = true;
168 } else {
169 unrecognizedType += "Function|";
170 }
171 break;
172 default:
173 break;
174 }
175 }
176 if (!typeVerified) {
177 LOGE("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
178 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
179 }
180 return typeVerified || infoTypes.size() == 0;
181 }
182
ParseJsScale(std::unique_ptr<JsonValue> & argsPtrItem,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)183 void ParseJsScale(std::unique_ptr<JsonValue>& argsPtrItem, float& scaleX, float& scaleY, float& scaleZ,
184 CalcDimension& centerX, CalcDimension& centerY)
185 {
186 double xVal = 1.0;
187 double yVal = 1.0;
188 double zVal = 1.0;
189 if (!argsPtrItem->IsObject() && !argsPtrItem->IsNumber() && !argsPtrItem->IsString()) {
190 scaleX = static_cast<float>(xVal);
191 scaleY = static_cast<float>(yVal);
192 scaleZ = static_cast<float>(zVal);
193 CalcDimension length;
194 centerX = length;
195 centerY = length;
196 return;
197 }
198 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), xVal);
199 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), yVal);
200 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), zVal);
201 scaleX = static_cast<float>(xVal);
202 scaleY = static_cast<float>(yVal);
203 scaleZ = static_cast<float>(zVal);
204 // if specify centerX
205 CalcDimension length;
206 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length)) {
207 centerX = length;
208 }
209 // if specify centerY
210 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length)) {
211 centerY = length;
212 }
213 }
214
ParseJsTranslate(std::unique_ptr<JsonValue> & argsPtrItem,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)215 void ParseJsTranslate(std::unique_ptr<JsonValue>& argsPtrItem, CalcDimension& translateX, CalcDimension& translateY,
216 CalcDimension& translateZ)
217 {
218 CalcDimension length;
219 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("x"), length)) {
220 translateX = length;
221 }
222 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("y"), length)) {
223 translateY = length;
224 }
225 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("z"), length)) {
226 translateZ = length;
227 }
228 }
229
GetDefaultRotateVector(double & dx,double & dy,double & dz)230 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
231 {
232 dx = 0.0;
233 dy = 0.0;
234 dz = 0.0;
235 auto container = Container::Current();
236 if (!container) {
237 LOGW("container is null");
238 return;
239 }
240 auto pipelineContext = container->GetPipelineContext();
241 if (!pipelineContext) {
242 LOGE("pipelineContext is null!");
243 return;
244 }
245 if (pipelineContext->GetMinPlatformVersion() >= MIN_ROTATE_VECTOR_Z) {
246 dz = 1.0;
247 }
248 }
249
ParseJsRotate(std::unique_ptr<JsonValue> & argsPtrItem,NG::RotateOptions & rotate,std::optional<float> & angle)250 void ParseJsRotate(std::unique_ptr<JsonValue>& argsPtrItem, NG::RotateOptions& rotate, std::optional<float>& angle)
251 {
252 // default: dx, dy, dz (0.0, 0.0, 0.0)
253 double dxVal = 0.0;
254 double dyVal = 0.0;
255 double dzVal = 0.0;
256 if (!argsPtrItem->Contains("x") && !argsPtrItem->Contains("y") && !argsPtrItem->Contains("z")) {
257 GetDefaultRotateVector(dxVal, dyVal, dzVal);
258 }
259 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), dxVal);
260 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), dyVal);
261 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), dzVal);
262 rotate.xDirection = static_cast<float>(dxVal);
263 rotate.yDirection = static_cast<float>(dyVal);
264 rotate.zDirection = static_cast<float>(dzVal);
265 // if specify centerX
266 CalcDimension length;
267 if (!JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length, true)) {
268 length = Dimension(0.5f, DimensionUnit::PERCENT);
269 }
270 rotate.centerX = length;
271 // if specify centerY
272
273 if (!JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length, true)) {
274 length = Dimension(0.5f, DimensionUnit::PERCENT);
275 }
276 rotate.centerY = length;
277
278 // if specify centerZ
279 if (!JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerZ"), length, true)) {
280 length = Dimension(0.5f, DimensionUnit::PERCENT);
281 }
282 rotate.centerZ = length;
283 // if specify angle
284 JSViewAbstract::GetAngle("angle", argsPtrItem, angle);
285 float perspective = 0.0f;
286 JSViewAbstract::GetPerspective("perspective", argsPtrItem, perspective);
287 rotate.perspective = perspective;
288 }
289
ParseMotionPath(const std::unique_ptr<JsonValue> & argsPtrItem,MotionPathOption & option)290 bool ParseMotionPath(const std::unique_ptr<JsonValue>& argsPtrItem, MotionPathOption& option)
291 {
292 if (argsPtrItem && !argsPtrItem->IsNull()) {
293 auto path = argsPtrItem->GetString("path", "");
294 if (!path.empty()) {
295 option.SetPath(path);
296 double from = 0.0;
297 double to = 1.0;
298 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("from"), from);
299 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("to"), to);
300 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
301 LOGW("ParseMotionPath, from value %{public}f is illegal, use default 0.0", from);
302 from = 0.0;
303 }
304 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
305 LOGW("ParseMotionPath, to value %{public}f is illegal, use default 1.0", to);
306 to = 1.0;
307 } else if (to < from) {
308 LOGW("ParseMotionPath, to value %{public}f less than from value %{public}f", to, from);
309 to = from;
310 }
311 option.SetBegin(static_cast<float>(from));
312 option.SetEnd(static_cast<float>(to));
313 option.SetRotate(argsPtrItem->GetBool("rotatable", false));
314 return true;
315 }
316 }
317 return false;
318 }
319
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)320 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
321 BackgroundImagePosition& bgImgPosition)
322 {
323 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
324 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
325 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
326 }
327
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)328 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
329 {
330 JSRef<JSVal> item = params->GetValueAt(pos + containCount);
331 if (type == "d") {
332 if (item->IsNumber()) {
333 return std::to_string(item->ToNumber<uint32_t>());
334 }
335 } else if (type == "s") {
336 if (item->IsString()) {
337 return item->ToString();
338 }
339 } else if (type == "f") {
340 if (item->IsNumber()) {
341 return std::to_string(item->ToNumber<float>());
342 }
343 }
344 return std::string();
345 }
346
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)347 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
348 {
349 auto size = static_cast<int32_t>(params->Length());
350 if (containCount == size) {
351 return;
352 }
353 std::string::const_iterator start = originStr.begin();
354 std::string::const_iterator end = originStr.end();
355 std::smatch matches;
356 bool shortHolderType = false;
357 bool firstMatch = true;
358 int searchTime = 0;
359 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
360 std::string pos = matches[2];
361 std::string type = matches[4];
362 if (firstMatch) {
363 firstMatch = false;
364 shortHolderType = pos.length() == 0;
365 } else {
366 if (shortHolderType ^ (pos.length() == 0)) {
367 LOGE("wrong place holder,stop parse string");
368 return;
369 }
370 }
371
372 std::string replaceContentStr;
373 if (shortHolderType) {
374 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
375 } else {
376 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
377 }
378
379 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
380 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
381 end = originStr.end();
382 searchTime++;
383 }
384 }
385
ParseLocationProps(const JSCallbackInfo & info,CalcDimension & x,CalcDimension & y)386 bool ParseLocationProps(const JSCallbackInfo& info, CalcDimension& x, CalcDimension& y)
387 {
388 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
389 if (!CheckJSCallbackInfo("ParseLocationProps", info, checkList)) {
390 return false;
391 }
392 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
393 JSRef<JSVal> xVal = sizeObj->GetProperty("x");
394 JSRef<JSVal> yVal = sizeObj->GetProperty("y");
395 bool hasX = JSViewAbstract::ParseJsDimensionVp(xVal, x);
396 bool hasY = JSViewAbstract::ParseJsDimensionVp(yVal, y);
397 return hasX || hasY;
398 }
399
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)400 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
401 {
402 JSRef<JSVal> builder;
403 if (info->IsObject()) {
404 auto builderObj = JSRef<JSObject>::Cast(info);
405 builder = builderObj->GetProperty("builder");
406 } else if (info->IsFunction()) {
407 builder = info;
408 } else {
409 return nullptr;
410 }
411
412 if (!builder->IsFunction()) {
413 return nullptr;
414 }
415
416 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
417 }
418
419 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
420 const JSRef<JSObject>& object, const JSExecutionContext& context);
421
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)422 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
423 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
424 {
425 RefPtr<NG::ChainedTransitionEffect> effect;
426 if (effectOption->IsObject()) {
427 auto rotateArgs = JsonUtil::ParseJsonString(effectOption->ToString());
428 if (!rotateArgs || rotateArgs->IsNull()) {
429 LOGE("Js Parse object failed. argsPtr is null. %{public}s", effectOption->ToString().c_str());
430 return nullptr;
431 }
432 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
433 std::optional<float> angle;
434 ParseJsRotate(rotateArgs, rotate, angle);
435 if (angle.has_value()) {
436 rotate.angle = angle.value();
437 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
438 }
439 LOGW("RotateOption does not specify angle");
440 } else {
441 LOGW("chained rotate effect, but effect option is not object");
442 }
443 return nullptr;
444 }
445
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)446 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
447 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
448 {
449 double opacity = 1.0;
450 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
451 if ((LessNotEqual(opacity, 0.0)) || opacity > 1.0) {
452 LOGW("set opacity to %{public}f, over range, set to default opacity", opacity);
453 opacity = 1.0;
454 }
455 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
456 }
457 LOGW("chained opacity effect, but effect option is not number");
458 return nullptr;
459 }
460
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)461 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
462 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
463 {
464 if (effectOption->IsObject()) {
465 auto translateArgs = JsonUtil::ParseJsonString(effectOption->ToString());
466 // default: x, y, z (0.0, 0.0, 0.0)
467 NG::TranslateOptions translate;
468 ParseJsTranslate(translateArgs, translate.x, translate.y, translate.z);
469 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
470 }
471 LOGW("chained translate effect, but effect option is not object");
472 return nullptr;
473 }
474
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)475 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
476 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
477 {
478 if (effectOption->IsObject()) {
479 auto scaleArgs = JsonUtil::ParseJsonString(effectOption->ToString());
480 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
481 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
482 ParseJsScale(scaleArgs, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
483 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
484 }
485 LOGW("chained scale effect, but effect option is not object");
486 return nullptr;
487 }
488
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)489 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
490 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
491 {
492 int32_t edge = 0;
493 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
494 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
495 edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
496 LOGW("set edge to %{public}d, over range, set to default edge", edge);
497 edge = static_cast<int32_t>(NG::TransitionEdge::START);
498 }
499 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
500 }
501 LOGW("chained move effect, but effect option is not number");
502 return nullptr;
503 }
504
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)505 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
506 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
507 {
508 if (effectOption->IsObject()) {
509 auto effectObj = JSRef<JSObject>::Cast(effectOption);
510 auto appearJsVal = effectObj->GetProperty("appear");
511 auto disappearJsVal = effectObj->GetProperty("disappear");
512 RefPtr<NG::ChainedTransitionEffect> appearEffect;
513 RefPtr<NG::ChainedTransitionEffect> disappearEffect;
514 if (appearJsVal->IsObject()) {
515 auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
516 appearEffect = ParseChainedTransition(appearObj, context);
517 }
518 if (disappearJsVal->IsObject()) {
519 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
520 disappearEffect = ParseChainedTransition(disappearObj, context);
521 }
522 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
523 }
524 LOGW("chained asymmetric effect, but effect option is not object");
525 return nullptr;
526 }
527
528 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
529 const JSRef<JSVal>&, const JSExecutionContext&);
530
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)531 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
532 const JSRef<JSObject>& object, const JSExecutionContext& context)
533 {
534 auto propType = object->GetProperty("type_");
535 if (!propType->IsString()) {
536 LOGW("ParseChainedTransition failed, transitionEffect type is not string");
537 return nullptr;
538 }
539 std::string type = propType->ToString();
540 auto propEffectOption = object->GetProperty("effect_");
541 auto propAnimationOption = object->GetProperty("animation_");
542 auto propSuccessor = object->GetProperty("successor_");
543 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
544 { "asymmetric", ParseChainedAsymmetricTransition },
545 { "identity",
546 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
547 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
548 { "move", ParseChainedMoveTransition },
549 { "opacity", ParseChainedOpacityTransition },
550 { "rotate", ParseChainedRotateTransition },
551 { "scale", ParseChainedScaleTransition },
552 { "slideSwitch",
553 [](const JSRef<JSVal>& effectOption,
554 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
555 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
556 } },
557 { "translate", ParseChainedTranslateTransition },
558 };
559 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
560 if (index < 0) {
561 LOGW("no valid creator found for ChainedTransitionEffect, type: %{public}s", type.c_str());
562 return nullptr;
563 }
564 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
565 if (!result) {
566 return nullptr;
567 }
568 if (propAnimationOption->IsObject()) {
569 auto animationOptionArgs = JsonUtil::ParseJsonString(propAnimationOption->ToString());
570 auto animationOptionResult =
571 std::make_shared<AnimationOption>(JSViewContext::CreateAnimation(animationOptionArgs, nullptr));
572 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
573 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
574 if (onFinish->IsFunction()) {
575 RefPtr<JsFunction> jsFunc =
576 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
577 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
578 id = Container::CurrentId()]() {
579 ContainerScope scope(id);
580 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
581 func->Execute();
582 };
583 animationOptionResult->SetOnFinishEvent(onFinishEvent);
584 }
585 result->SetAnimationOption(animationOptionResult);
586 }
587 if (propSuccessor->IsObject()) {
588 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
589 }
590 return result;
591 }
592
593 #ifndef WEARABLE_PRODUCT
594 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
595 Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
596 Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
597
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)598 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
599 {
600 JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
601 if (!changeEvent->IsFunction()) {
602 return {};
603 }
604 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
605 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
606 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
607 if (param != "true" && param != "false") {
608 LOGE("param is not equal true or false, invalid.");
609 return;
610 }
611 bool newValue = StringToBool(param);
612 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
613 func->ExecuteJS(1, &newJSVal);
614 };
615 return callback;
616 }
617
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)618 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
619 {
620 auto colorValue = messageOptionsObj->GetProperty("textColor");
621 Color textColor;
622 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
623 if (popupParam) {
624 popupParam->SetTextColor(textColor);
625 } else {
626 LOGI("Empty popup.");
627 }
628 }
629
630 auto font = messageOptionsObj->GetProperty("font");
631 if (!font->IsNull() && font->IsObject()) {
632 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
633 auto fontSizeValue = fontObj->GetProperty("size");
634 CalcDimension fontSize;
635 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
636 if (popupParam) {
637 popupParam->SetFontSize(fontSize);
638 } else {
639 LOGI("Empty popup.");
640 }
641 }
642 auto fontWeightValue = fontObj->GetProperty("weight");
643 if (fontWeightValue->IsString()) {
644 if (popupParam) {
645 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
646 } else {
647 LOGI("Empty popup.");
648 }
649 }
650 auto fontStyleValue = fontObj->GetProperty("style");
651 if (fontStyleValue->IsNumber()) {
652 int32_t value = fontStyleValue->ToNumber<int32_t>();
653 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
654 LOGI("Text fontStyle(%d) is invalid value", value);
655 return;
656 }
657 if (popupParam) {
658 popupParam->SetFontStyle(FONT_STYLES[value]);
659 } else {
660 LOGI("Empty popup.");
661 }
662 }
663 }
664 }
665
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)666 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
667 {
668 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
669 if (placementOnTopVal->IsBoolean() && popupParam) {
670 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
671 }
672 }
673
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)674 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
675 {
676 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
677 if (popupParam) {
678 popupParam->SetMessage(messageVal->ToString());
679 } else {
680 LOGI("Empty popup.");
681 }
682
683 auto arrowOffset = popupObj->GetProperty("arrowOffset");
684 CalcDimension offset;
685 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
686 if (popupParam) {
687 popupParam->SetArrowOffset(offset);
688 } else {
689 LOGI("Empty popup.");
690 }
691 }
692
693 auto targetSpace = popupObj->GetProperty("targetSpace");
694 if (!targetSpace->IsNull()) {
695 CalcDimension space;
696 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
697 if (popupParam) {
698 popupParam->SetTargetSpace(space);
699 } else {
700 LOGI("Empty popup.");
701 }
702 }
703 }
704
705 auto messageOptions = popupObj->GetProperty("messageOptions");
706 JSRef<JSObject> messageOptionsObj;
707 if (!messageOptions->IsNull() && messageOptions->IsObject()) {
708 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
709 SetPopupMessageOptions(messageOptionsObj, popupParam);
710 }
711
712 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
713 if (showInSubWindowValue->IsBoolean()) {
714 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
715 #if defined(PREVIEW)
716 if (showInSubBoolean) {
717 LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
718 showInSubBoolean = false;
719 }
720 #endif
721 if (popupParam) {
722 popupParam->SetShowInSubWindow(showInSubBoolean);
723 } else {
724 LOGI("Empty popup.");
725 }
726 }
727
728 auto placementValue = popupObj->GetProperty("placement");
729 if (placementValue->IsNumber()) {
730 auto placement = placementValue->ToNumber<int32_t>();
731 if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
732 popupParam->SetPlacement(PLACEMENT[placement]);
733 }
734 } else {
735 SetPlacementOnTopVal(popupObj, popupParam);
736 }
737
738 auto enableArrowValue = popupObj->GetProperty("enableArrow");
739 if (enableArrowValue->IsBoolean()) {
740 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
741 }
742
743 JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
744 if (maskValue->IsBoolean()) {
745 if (popupParam) {
746 popupParam->SetBlockEvent(maskValue->ToBoolean());
747 } else {
748 LOGI("Empty popup.");
749 }
750 }
751 if (maskValue->IsObject()) {
752 auto maskObj = JSRef<JSObject>::Cast(maskValue);
753 auto colorValue = maskObj->GetProperty("color");
754 Color maskColor;
755 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
756 popupParam->SetMaskColor(maskColor);
757 }
758 }
759 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
760 if (onStateChangeVal->IsFunction()) {
761 std::vector<std::string> keys = { "isVisible" };
762 RefPtr<JsFunction> jsFunc =
763 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
764 if (popupParam) {
765 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](
766 const std::string& param) {
767 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
768 ACE_SCORING_EVENT("Popup.onStateChange");
769 func->Execute(keys, param);
770 };
771 popupParam->SetOnStateChange(onStateChangeCallback);
772 } else {
773 LOGI("Empty popup.");
774 }
775 }
776
777 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
778 if (primaryButtonVal->IsObject()) {
779 ButtonProperties properties;
780 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
781 JSRef<JSVal> value = obj->GetProperty("value");
782 if (value->IsString()) {
783 properties.value = value->ToString();
784 }
785
786 JSRef<JSVal> actionValue = obj->GetProperty("action");
787 if (actionValue->IsFunction()) {
788 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
789 if (popupParam) {
790 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc)](
791 GestureEvent& info) {
792 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
793 ACE_SCORING_EVENT("primaryButton.action");
794 LOGI("Call primary click");
795 func->Execute(info);
796 };
797 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
798 }
799 }
800 properties.showButton = true;
801 if (popupParam) {
802 popupParam->SetPrimaryButtonProperties(properties);
803 } else {
804 LOGI("Empty.");
805 }
806 }
807
808 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
809 if (secondaryButtonVal->IsObject()) {
810 ButtonProperties properties;
811 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
812 JSRef<JSVal> value = obj->GetProperty("value");
813 if (value->IsString()) {
814 properties.value = value->ToString();
815 }
816
817 JSRef<JSVal> actionValue = obj->GetProperty("action");
818 if (actionValue->IsFunction()) {
819 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
820 if (popupParam) {
821 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc)](
822 GestureEvent& info) {
823 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
824 ACE_SCORING_EVENT("secondaryButton.action");
825 LOGI("Call secondary click");
826 func->Execute(info);
827 };
828 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
829 }
830 }
831 properties.showButton = true;
832 if (popupParam) {
833 popupParam->SetSecondaryButtonProperties(properties);
834 } else {
835 LOGI("Empty.");
836 }
837 }
838
839 auto offsetVal = popupObj->GetProperty("offset");
840 if (offsetVal->IsObject()) {
841 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
842 auto xVal = offsetObj->GetProperty("x");
843 auto yVal = offsetObj->GetProperty("y");
844 Offset popupOffset;
845 CalcDimension dx;
846 CalcDimension dy;
847 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
848 popupOffset.SetX(dx.ConvertToPx());
849 }
850 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
851 popupOffset.SetY(dy.ConvertToPx());
852 }
853 if (popupParam) {
854 popupParam->SetTargetOffset(popupOffset);
855 }
856 }
857 }
858
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)859 void ParseCustomPopupParam(
860 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
861 {
862 auto builderValue = popupObj->GetProperty("builder");
863 if (!builderValue->IsObject()) {
864 LOGE("builder param is not an object.");
865 return;
866 }
867
868 JSRef<JSObject> builderObj;
869 builderObj = JSRef<JSObject>::Cast(builderValue);
870 auto builder = builderObj->GetProperty("builder");
871 if (!builder->IsFunction()) {
872 LOGE("builder param is not a function.");
873 return;
874 }
875 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
876 if (!builderFunc) {
877 LOGE("builder function is null.");
878 return;
879 }
880
881 if (popupParam) {
882 popupParam->SetUseCustomComponent(true);
883 }
884
885 auto placementValue = popupObj->GetProperty("placement");
886 if (placementValue->IsNumber()) {
887 auto placement = placementValue->ToNumber<int32_t>();
888 if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
889 popupParam->SetPlacement(PLACEMENT[placement]);
890 }
891 }
892
893 auto arrowOffset = popupObj->GetProperty("arrowOffset");
894 CalcDimension offset;
895 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
896 popupParam->SetArrowOffset(offset);
897 }
898
899 auto targetSpace = popupObj->GetProperty("targetSpace");
900 CalcDimension space;
901 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
902 if (popupParam) {
903 popupParam->SetTargetSpace(space);
904 } else {
905 LOGI("Empty popup.");
906 }
907 }
908
909 auto maskColorValue = popupObj->GetProperty("maskColor");
910 Color maskColor;
911 if (JSViewAbstract::ParseJsColor(maskColorValue, maskColor)) {
912 popupParam->SetMaskColor(maskColor);
913 }
914
915 auto maskValue = popupObj->GetProperty("mask");
916 if (maskValue->IsBoolean()) {
917 popupParam->SetBlockEvent(maskValue->ToBoolean());
918 }
919 if (maskValue->IsObject()) {
920 auto maskObj = JSRef<JSObject>::Cast(maskValue);
921 auto colorValue = maskObj->GetProperty("color");
922 Color maskColor;
923 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
924 popupParam->SetMaskColor(maskColor);
925 }
926 }
927
928 auto popupColorValue = popupObj->GetProperty("popupColor");
929 Color backgroundColor;
930 if (JSViewAbstract::ParseJsColor(popupColorValue, backgroundColor)) {
931 popupParam->SetBackgroundColor(backgroundColor);
932 }
933
934 auto enableArrowValue = popupObj->GetProperty("enableArrow");
935 if (enableArrowValue->IsBoolean()) {
936 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
937 }
938
939 auto showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
940 if (showInSubWindowValue->IsBoolean()) {
941 #if defined(PREVIEW)
942 LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
943 popupParam->SetShowInSubWindow(false);
944 #else
945 popupParam->SetShowInSubWindow(showInSubWindowValue->ToBoolean());
946 #endif
947 }
948
949 auto autoCancelValue = popupObj->GetProperty("autoCancel");
950 if (autoCancelValue->IsBoolean()) {
951 popupParam->SetHasAction(!autoCancelValue->ToBoolean());
952 }
953
954 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
955 if (onStateChangeVal->IsFunction()) {
956 std::vector<std::string> keys = { "isVisible" };
957 RefPtr<JsFunction> jsFunc =
958 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
959 if (popupParam) {
960 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](
961 const std::string& param) {
962 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
963 ACE_SCORING_EVENT("popup.onStateChange");
964 func->Execute(keys, param);
965 };
966 popupParam->SetOnStateChange(onStateChangeCallback);
967 }
968 }
969
970 auto offsetVal = popupObj->GetProperty("offset");
971 if (offsetVal->IsObject()) {
972 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
973 auto xVal = offsetObj->GetProperty("x");
974 auto yVal = offsetObj->GetProperty("y");
975 Offset popupOffset;
976 CalcDimension dx;
977 CalcDimension dy;
978 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
979 popupOffset.SetX(dx.ConvertToPx());
980 }
981 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
982 popupOffset.SetY(dy.ConvertToPx());
983 }
984 if (popupParam) {
985 popupParam->SetTargetOffset(popupOffset);
986 }
987 }
988 }
989 #endif
990
991 } // namespace
992
ColorAlphaAdapt(uint32_t origin)993 uint32_t ColorAlphaAdapt(uint32_t origin)
994 {
995 uint32_t result = origin;
996 if (origin >> COLOR_ALPHA_OFFSET == 0) {
997 result = origin | COLOR_ALPHA_VALUE;
998 }
999 return result;
1000 }
1001
JsScale(const JSCallbackInfo & info)1002 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1003 {
1004 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1005 if (!CheckJSCallbackInfo("JsScale", info, checkList)) {
1006 SetDefaultScale();
1007 return;
1008 }
1009
1010 if (info[0]->IsObject()) {
1011 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1012 if (!argsPtrItem || argsPtrItem->IsNull()) {
1013 return;
1014 }
1015 if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
1016 // default: x, y, z (1.0, 1.0, 1.0)
1017 auto scaleX = 1.0f;
1018 auto scaleY = 1.0f;
1019 auto scaleZ = 1.0f;
1020 // default centerX, centerY 50% 50%;
1021 CalcDimension centerX = 0.5_pct;
1022 CalcDimension centerY = 0.5_pct;
1023 ParseJsScale(argsPtrItem, scaleX, scaleY, scaleZ, centerX, centerY);
1024 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1025 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1026 return;
1027 } else {
1028 SetDefaultScale();
1029 }
1030 }
1031 double scale = 0.0;
1032 if (ParseJsDouble(info[0], scale)) {
1033 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1034 }
1035 }
1036
SetDefaultScale()1037 void JSViewAbstract::SetDefaultScale()
1038 {
1039 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1040 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1041 }
1042
JsScaleX(const JSCallbackInfo & info)1043 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1044 {
1045 LOGD("JsScaleX");
1046 if (info.Length() < 1) {
1047 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1048 return;
1049 }
1050
1051 double scaleVal = 0.0;
1052 if (!ParseJsDouble(info[0], scaleVal)) {
1053 return;
1054 }
1055 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1056 }
1057
JsScaleY(const JSCallbackInfo & info)1058 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1059 {
1060 LOGD("JsScaleY");
1061 if (info.Length() < 1) {
1062 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1063 return;
1064 }
1065
1066 double scaleVal = 0.0;
1067 if (!ParseJsDouble(info[0], scaleVal)) {
1068 return;
1069 }
1070 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1071 }
1072
JsOpacity(const JSCallbackInfo & info)1073 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1074 {
1075 LOGD("js_opacity");
1076 if (info.Length() < 1) {
1077 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1078 return;
1079 }
1080
1081 double opacity = 0.0;
1082 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER,
1083 JSCallbackInfoType::STRING };
1084 if (!CheckJSCallbackInfo("Opacity", info, checkList)) {
1085 ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1086 return;
1087 }
1088 if (!ParseJsDouble(info[0], opacity)) {
1089 return;
1090 }
1091
1092 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
1093 LOGD("set opacity to %{public}f, over range, set to default opacity", opacity);
1094 opacity = 1.0;
1095 }
1096
1097 ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1098 }
1099
JsTranslate(const JSCallbackInfo & info)1100 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1101 {
1102 LOGD("JsTranslate");
1103 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1104 JSCallbackInfoType::OBJECT };
1105 if (!CheckJSCallbackInfo("JsTranslate", info, checkList)) {
1106 SetDefaultTranslate();
1107 return;
1108 }
1109
1110 CalcDimension value;
1111
1112 if (info[0]->IsObject()) {
1113 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1114 if (!argsPtrItem || argsPtrItem->IsNull()) {
1115 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
1116 return;
1117 }
1118 if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
1119 // default: x, y, z (0.0, 0.0, 0.0)
1120 auto translateX = CalcDimension(0.0);
1121 auto translateY = CalcDimension(0.0);
1122 auto translateZ = CalcDimension(0.0);
1123 ParseJsTranslate(argsPtrItem, translateX, translateY, translateZ);
1124 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1125 return;
1126 } else {
1127 SetDefaultTranslate();
1128 }
1129 }
1130 if (ParseJsDimensionVp(info[0], value)) {
1131 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1132 }
1133 }
1134
SetDefaultTranslate()1135 void JSViewAbstract::SetDefaultTranslate()
1136 {
1137 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1138 }
1139
JsTranslateX(const JSCallbackInfo & info)1140 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1141 {
1142 LOGD("JsTranslateX");
1143 if (info.Length() < 1) {
1144 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1145 return;
1146 }
1147 CalcDimension value;
1148 if (!ParseJsDimensionVp(info[0], value)) {
1149 return;
1150 }
1151 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1152 }
1153
JsTranslateY(const JSCallbackInfo & info)1154 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1155 {
1156 LOGD("JsTranslateY");
1157 if (info.Length() < 1) {
1158 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1159 return;
1160 }
1161 CalcDimension value;
1162 if (!ParseJsDimensionVp(info[0], value)) {
1163 return;
1164 }
1165 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1166 }
1167
JsRotate(const JSCallbackInfo & info)1168 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1169 {
1170 LOGD("JsRotate");
1171 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1172 if (!CheckJSCallbackInfo("JsRotate", info, checkList)) {
1173 SetDefaultRotate();
1174 return;
1175 }
1176
1177 if (info[0]->IsObject()) {
1178 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1179 if (!argsPtrItem || argsPtrItem->IsNull()) {
1180 SetDefaultRotate();
1181 return;
1182 }
1183 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1184 std::optional<float> angle;
1185 ParseJsRotate(argsPtrItem, rotate, angle);
1186 if (angle) {
1187 ViewAbstractModel::GetInstance()->SetRotate(
1188 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1189 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1190 } else {
1191 SetDefaultRotate();
1192 }
1193 return;
1194 }
1195 double rotateZ;
1196 if (ParseJsDouble(info[0], rotateZ)) {
1197 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1198 }
1199 }
1200
SetDefaultRotate()1201 void JSViewAbstract::SetDefaultRotate()
1202 {
1203 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1204 ViewAbstractModel::GetInstance()->SetRotate(
1205 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1206 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1207 }
1208
JsRotateX(const JSCallbackInfo & info)1209 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1210 {
1211 LOGD("JsRotateX");
1212 if (info.Length() < 1) {
1213 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1214 return;
1215 }
1216
1217 double rotateVal = 0.0;
1218 if (!ParseJsDouble(info[0], rotateVal)) {
1219 return;
1220 }
1221 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1222 }
1223
JsRotateY(const JSCallbackInfo & info)1224 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1225 {
1226 LOGD("JsRotateX");
1227 if (info.Length() < 1) {
1228 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1229 return;
1230 }
1231
1232 double rotateVal = 0.0;
1233 if (!ParseJsDouble(info[0], rotateVal)) {
1234 return;
1235 }
1236 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1237 }
1238
JsTransform(const JSCallbackInfo & info)1239 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1240 {
1241 LOGD("JsTransform");
1242 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1243 if (!CheckJSCallbackInfo("JsTransform", info, checkList)) {
1244 SetDefaultTransform();
1245 return;
1246 }
1247 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1248 if (!argsPtrItem || argsPtrItem->IsNull()) {
1249 LOGE("Js Parse object failed. argsPtr is null. %{public}s", info[0]->ToString().c_str());
1250 return;
1251 }
1252 auto array = argsPtrItem->GetValue("matrix4x4");
1253 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1254 if (!array || array->IsNull() || !array->IsArray() || array->GetArraySize() != matrix4Len) {
1255 LOGE("Js Parse object failed, matrix4x4 is null or not Array");
1256 return;
1257 }
1258 std::vector<float> matrix(matrix4Len);
1259 for (int32_t i = 0; i < matrix4Len; i++) {
1260 double value = 0.0;
1261 ParseJsonDouble(array->GetArrayItem(i), value);
1262 matrix[i] = static_cast<float>(value);
1263 }
1264 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1265 }
1266
SetDefaultTransform()1267 void JSViewAbstract::SetDefaultTransform()
1268 {
1269 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1270 std::vector<float> matrix(matrix4Len);
1271 const int32_t initPosition = 5;
1272 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1273 double value = 1.0;
1274 matrix[i] = static_cast<float>(value);
1275 }
1276 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1277 }
1278
ParseTransition(std::unique_ptr<JsonValue> & transitionArgs)1279 NG::TransitionOptions JSViewAbstract::ParseTransition(std::unique_ptr<JsonValue>& transitionArgs)
1280 {
1281 bool hasEffect = false;
1282 NG::TransitionOptions transitionOption;
1283 transitionOption.Type = ParseTransitionType(transitionArgs->GetString("type", "All"));
1284 if (transitionArgs->Contains("opacity")) {
1285 double opacity = 1.0;
1286 ParseJsonDouble(transitionArgs->GetValue("opacity"), opacity);
1287 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1288 LOGW("set opacity in transition to %{public}lf, over range, use default opacity 1", opacity);
1289 opacity = 1.0;
1290 }
1291 transitionOption.UpdateOpacity(static_cast<float>(opacity));
1292 hasEffect = true;
1293 }
1294 if (transitionArgs->Contains("translate")) {
1295 auto translateArgs = transitionArgs->GetObject("translate");
1296 // default: x, y, z (0.0, 0.0, 0.0)
1297 NG::TranslateOptions translate;
1298 ParseJsTranslate(translateArgs, translate.x, translate.y, translate.z);
1299 transitionOption.UpdateTranslate(translate);
1300 hasEffect = true;
1301 }
1302 if (transitionArgs->Contains("scale")) {
1303 auto scaleArgs = transitionArgs->GetObject("scale");
1304 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1305 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1306 ParseJsScale(scaleArgs, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
1307 transitionOption.UpdateScale(scale);
1308 hasEffect = true;
1309 }
1310 if (transitionArgs->Contains("rotate")) {
1311 auto rotateArgs = transitionArgs->GetObject("rotate");
1312 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1313 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1314 std::optional<float> angle;
1315 ParseJsRotate(rotateArgs, rotate, angle);
1316 if (angle.has_value()) {
1317 rotate.angle = angle.value();
1318 transitionOption.UpdateRotate(rotate);
1319 hasEffect = true;
1320 }
1321 }
1322 if (!hasEffect) {
1323 // default transition
1324 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1325 }
1326 return transitionOption;
1327 }
1328
JsTransition(const JSCallbackInfo & info)1329 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1330 {
1331 if (info.Length() > 1) {
1332 return;
1333 }
1334 if (info.Length() == 0) {
1335 ViewAbstractModel::GetInstance()->SetTransition(
1336 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
1337 return;
1338 }
1339 if (!info[0]->IsObject()) {
1340 LOGE("arg is not Object.");
1341 return;
1342 }
1343 auto obj = JSRef<JSObject>::Cast(info[0]);
1344 if (!obj->GetProperty("successor_")->IsUndefined()) {
1345 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1346 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect);
1347 return;
1348 }
1349 auto transitionArgs = JsonUtil::ParseJsonString(info[0]->ToString());
1350 auto options = ParseTransition(transitionArgs);
1351 ViewAbstractModel::GetInstance()->SetTransition(options);
1352 }
1353
JsWidth(const JSCallbackInfo & info)1354 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1355 {
1356 if (info.Length() < 1) {
1357 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1358 return;
1359 }
1360
1361 JsWidth(info[0]);
1362 }
1363
JsWidth(const JSRef<JSVal> & jsValue)1364 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1365 {
1366 CalcDimension value;
1367 if (jsValue->IsUndefined()) {
1368 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1369 return true;
1370 }
1371 if (PipelineBase::GetCurrentContext() &&
1372 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
1373 if (!ParseJsDimensionVpNG(jsValue, value)) {
1374 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1375 return false;
1376 }
1377 } else if (!ParseJsDimensionVp(jsValue, value)) {
1378 return false;
1379 }
1380
1381 if (LessNotEqual(value.Value(), 0.0)) {
1382 value.SetValue(0.0);
1383 }
1384
1385 ViewAbstractModel::GetInstance()->SetWidth(value);
1386 return true;
1387 }
1388
JsHeight(const JSCallbackInfo & info)1389 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
1390 {
1391 JsHeight(info[0]);
1392 }
1393
JsHeight(const JSRef<JSVal> & jsValue)1394 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
1395 {
1396 CalcDimension value;
1397 if (jsValue->IsUndefined()) {
1398 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1399 return true;
1400 }
1401 if (PipelineBase::GetCurrentContext() &&
1402 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
1403 if (!ParseJsDimensionVpNG(jsValue, value)) {
1404 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1405 return false;
1406 }
1407 } else if (!ParseJsDimensionVp(jsValue, value)) {
1408 return false;
1409 }
1410
1411 if (LessNotEqual(value.Value(), 0.0)) {
1412 value.SetValue(0.0);
1413 }
1414
1415 ViewAbstractModel::GetInstance()->SetHeight(value);
1416 return true;
1417 }
1418
JsResponseRegion(const JSCallbackInfo & info)1419 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
1420 {
1421 if (info.Length() < 1) {
1422 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1423 return;
1424 }
1425
1426 std::vector<DimensionRect> result;
1427 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1428 return;
1429 }
1430
1431 ViewAbstractModel::GetInstance()->SetResponseRegion(result);
1432 }
1433
JsMouseResponseRegion(const JSCallbackInfo & info)1434 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
1435 {
1436 if (info.Length() < 1) {
1437 LOGI("The args is wrong, it is supposed to have at least 1 arguments");
1438 return;
1439 }
1440 std::vector<DimensionRect> result;
1441 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1442 return;
1443 }
1444 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
1445 }
1446
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)1447 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
1448 {
1449 if (!jsValue->IsObject()) {
1450 LOGE("arg is not Object.");
1451 return false;
1452 }
1453
1454 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
1455 JSRef<JSVal> x = obj->GetProperty("x");
1456 JSRef<JSVal> y = obj->GetProperty("y");
1457 JSRef<JSVal> width = obj->GetProperty("width");
1458 JSRef<JSVal> height = obj->GetProperty("height");
1459 CalcDimension xDimen = result.GetOffset().GetX();
1460 CalcDimension yDimen = result.GetOffset().GetY();
1461 CalcDimension widthDimen = result.GetWidth();
1462 CalcDimension heightDimen = result.GetHeight();
1463 auto s1 = width->ToString();
1464 auto s2 = height->ToString();
1465 if (s1.find('-') != std::string::npos) {
1466 width = JSRef<JSVal>::Make(ToJSValue("100%"));
1467 }
1468 if (s2.find('-') != std::string::npos) {
1469 height = JSRef<JSVal>::Make(ToJSValue("100%"));
1470 }
1471 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
1472 auto offset = result.GetOffset();
1473 offset.SetX(xDimen);
1474 result.SetOffset(offset);
1475 }
1476 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
1477 auto offset = result.GetOffset();
1478 offset.SetY(yDimen);
1479 result.SetOffset(offset);
1480 }
1481 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
1482 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
1483 return true;
1484 }
1485 result.SetWidth(widthDimen);
1486 }
1487 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
1488 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
1489 return true;
1490 }
1491 result.SetHeight(heightDimen);
1492 }
1493 return true;
1494 }
1495
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)1496 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
1497 {
1498 if (!jsValue->IsArray() && !jsValue->IsObject()) {
1499 LOGE("arg is not array or Object.");
1500 return false;
1501 }
1502
1503 if (jsValue->IsArray()) {
1504 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
1505 for (size_t i = 0; i < array->Length(); i++) {
1506 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1507 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1508 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1509 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1510 DimensionOffset offsetDimen(xDimen, yDimen);
1511 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1512 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
1513 result.emplace_back(dimenRect);
1514 } else {
1515 LOGE("Array element is not Object.");
1516 return false;
1517 }
1518 }
1519 return true;
1520 }
1521
1522 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1523 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1524 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1525 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1526 DimensionOffset offsetDimen(xDimen, yDimen);
1527 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1528 if (ParseJsDimensionRect(jsValue, dimenRect)) {
1529 result.emplace_back(dimenRect);
1530 return true;
1531 } else {
1532 LOGE("Array element is not Object.");
1533 return false;
1534 }
1535 }
1536
JsSize(const JSCallbackInfo & info)1537 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
1538 {
1539 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1540 if (!CheckJSCallbackInfo("JsSize", info, checkList)) {
1541 return;
1542 }
1543
1544 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1545 JsWidth(sizeObj->GetProperty("width"));
1546 JsHeight(sizeObj->GetProperty("height"));
1547 }
1548
JsConstraintSize(const JSCallbackInfo & info)1549 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
1550 {
1551 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1552 if (!CheckJSCallbackInfo("JsConstraintSize", info, checkList)) {
1553 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1554 ViewAbstractModel::GetInstance()->ResetMinSize(true);
1555 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1556 ViewAbstractModel::GetInstance()->ResetMinSize(false);
1557 return;
1558 }
1559
1560 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1561
1562 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
1563 CalcDimension minWidth;
1564 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
1565 CalcDimension maxWidth;
1566 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
1567 CalcDimension minHeight;
1568 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
1569 CalcDimension maxHeight;
1570 bool version10OrLarger = PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN;
1571 if (ParseJsDimensionVp(minWidthValue, minWidth)) {
1572 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
1573 } else if (version10OrLarger) {
1574 ViewAbstractModel::GetInstance()->ResetMinSize(true);
1575 }
1576
1577 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
1578 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
1579 } else if (version10OrLarger) {
1580 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1581 }
1582
1583 if (ParseJsDimensionVp(minHeightValue, minHeight)) {
1584 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
1585 } else if (version10OrLarger) {
1586 ViewAbstractModel::GetInstance()->ResetMinSize(false);
1587 }
1588
1589 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
1590 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
1591 } else if (version10OrLarger) {
1592 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1593 }
1594 }
1595
JsLayoutPriority(const JSCallbackInfo & info)1596 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
1597 {
1598 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1599 if (!CheckJSCallbackInfo("JsLayoutPriority", info, checkList)) {
1600 return;
1601 }
1602
1603 int32_t priority;
1604 if (info[0]->IsNumber()) {
1605 priority = info[0]->ToNumber<int32_t>();
1606 } else {
1607 priority = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1608 }
1609 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
1610 }
1611
JsLayoutWeight(const JSCallbackInfo & info)1612 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
1613 {
1614 int32_t value = 0.0;
1615 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1616 if (!CheckJSCallbackInfo("JsLayoutWeight", info, checkList)) {
1617 if (!info[0]->IsUndefined()) {
1618 return;
1619 }
1620 }
1621
1622 if (info[0]->IsNumber()) {
1623 value = info[0]->ToNumber<int32_t>();
1624 } else {
1625 value = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1626 }
1627
1628 ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
1629 }
1630
JsAlign(const JSCallbackInfo & info)1631 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
1632 {
1633 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
1634 if (!CheckJSCallbackInfo("JsAlign", info, checkList) && PipelineBase::GetCurrentContext() &&
1635 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() > 9) {
1636 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
1637 return;
1638 }
1639 auto value = info[0]->ToNumber<int32_t>();
1640 Alignment alignment = ParseAlignment(value);
1641 ViewAbstractModel::GetInstance()->SetAlign(alignment);
1642 }
1643
JsPosition(const JSCallbackInfo & info)1644 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
1645 {
1646 CalcDimension x;
1647 CalcDimension y;
1648 if (ParseLocationProps(info, x, y)) {
1649 ViewAbstractModel::GetInstance()->SetPosition(x, y);
1650 } else {
1651 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
1652 }
1653 }
1654
JsMarkAnchor(const JSCallbackInfo & info)1655 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
1656 {
1657 CalcDimension x;
1658 CalcDimension y;
1659 if (ParseLocationProps(info, x, y)) {
1660 ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
1661 } else {
1662 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
1663 }
1664 }
1665
JsOffset(const JSCallbackInfo & info)1666 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
1667 {
1668 CalcDimension x;
1669 CalcDimension y;
1670 if (ParseLocationProps(info, x, y)) {
1671 ViewAbstractModel::GetInstance()->SetOffset(x, y);
1672 } else {
1673 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
1674 }
1675 }
1676
JsEnabled(const JSCallbackInfo & info)1677 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
1678 {
1679 if (info.Length() < 1) {
1680 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1681 return;
1682 }
1683
1684 bool enabled;
1685 if (!info[0]->IsBoolean()) {
1686 LOGE("arg is not bool.");
1687 enabled = true;
1688 } else {
1689 enabled = info[0]->ToBoolean();
1690 }
1691
1692 ViewAbstractModel::GetInstance()->SetEnabled(enabled);
1693 }
1694
JsAspectRatio(const JSCallbackInfo & info)1695 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
1696 {
1697 if (info.Length() < 1) {
1698 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1699 return;
1700 }
1701
1702 double value = 0.0;
1703 auto context = PipelineBase::GetCurrentContext();
1704 CHECK_NULL_VOID(context);
1705 if (!ParseJsDouble(info[0], value)) {
1706 // add version protection, undefined use default value
1707 if (context->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN && (info[0]->IsNull() || info[0]->IsUndefined())) {
1708 ViewAbstractModel::GetInstance()->ResetAspectRatio();
1709 return;
1710 } else {
1711 return;
1712 }
1713 }
1714
1715 // negative use default value.
1716 if (LessOrEqual(value, 0.0)) {
1717 if (context->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
1718 ViewAbstractModel::GetInstance()->ResetAspectRatio();
1719 return;
1720 } else {
1721 value = 1.0;
1722 }
1723 }
1724
1725 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
1726 }
1727
JsOverlay(const JSCallbackInfo & info)1728 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
1729 {
1730 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
1731 return;
1732 }
1733 std::optional<Alignment> align;
1734 std::optional<CalcDimension> offsetX;
1735 std::optional<CalcDimension> offsetY;
1736
1737 if (info[1]->IsObject()) {
1738 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
1739 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
1740 auto value = alignVal->ToNumber<int32_t>();
1741 Alignment alignment = ParseAlignment(value);
1742 align = alignment;
1743
1744 JSRef<JSVal> val = optionObj->GetProperty("offset");
1745 if (val->IsObject()) {
1746 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
1747 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
1748 CalcDimension x;
1749 if (ParseJsDimensionVp(xVal, x)) {
1750 offsetX = x;
1751 }
1752 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
1753 CalcDimension y;
1754 if (ParseJsDimensionVp(yVal, y)) {
1755 offsetY = y;
1756 }
1757 }
1758 }
1759
1760 if (info[0]->IsString()) {
1761 std::string text = info[0]->ToString();
1762 ViewAbstractModel::GetInstance()->SetOverlay(text, nullptr, align, offsetX, offsetY);
1763 } else if (info[0]->IsObject()) {
1764 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[0]);
1765 auto builder = menuObj->GetProperty("builder");
1766 if (!builder->IsFunction()) {
1767 return;
1768 }
1769 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1770 CHECK_NULL_VOID(builderFunc);
1771 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
1772 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1773 ACE_SCORING_EVENT("Overlay");
1774 func->Execute();
1775 };
1776 ViewAbstractModel::GetInstance()->SetOverlay("", std::move(buildFunc), align, offsetX, offsetY);
1777 }
1778 }
1779
ParseAlignment(int32_t align)1780 Alignment JSViewAbstract::ParseAlignment(int32_t align)
1781 {
1782 Alignment alignment = Alignment::CENTER;
1783 switch (align) {
1784 case 0:
1785 alignment = Alignment::TOP_LEFT;
1786 break;
1787 case 1:
1788 alignment = Alignment::TOP_CENTER;
1789 break;
1790 case 2:
1791 alignment = Alignment::TOP_RIGHT;
1792 break;
1793 case 3:
1794 alignment = Alignment::CENTER_LEFT;
1795 break;
1796 case 4:
1797 alignment = Alignment::CENTER;
1798 break;
1799 case 5:
1800 alignment = Alignment::CENTER_RIGHT;
1801 break;
1802 case 6:
1803 alignment = Alignment::BOTTOM_LEFT;
1804 break;
1805 case 7:
1806 alignment = Alignment::BOTTOM_CENTER;
1807 break;
1808 case 8:
1809 alignment = Alignment::BOTTOM_RIGHT;
1810 break;
1811 default:
1812 LOGE("Invalid value for alignment");
1813 }
1814 return alignment;
1815 }
1816
SetVisibility(const JSCallbackInfo & info)1817 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
1818 {
1819 if (info.Length() < 1) {
1820 LOGE("SetVisibility: The arg is wrong, it is supposed to have at least 1 arguments");
1821 return;
1822 }
1823 int32_t visible = 0;
1824 if (info[0]->IsNull() || info[0]->IsUndefined()) {
1825 // undefined value use default value.
1826 visible = 0;
1827 } else if (!info[0]->IsNumber()) {
1828 LOGD("SetVisibility: The first param type is not number, invalid.");
1829 return;
1830 } else {
1831 visible = info[0]->ToNumber<int32_t>();
1832 }
1833
1834 if (info.Length() > 1 && info[1]->IsFunction()) {
1835 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
1836
1837 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](int32_t visible) {
1838 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1839 ACE_SCORING_EVENT("onVisibilityChange");
1840
1841 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
1842 func->ExecuteJS(1, &newJSVal);
1843 };
1844 ViewAbstractModel::GetInstance()->SetVisibility(
1845 static_cast<VisibleType>(visible), std::move(onVisibilityChange));
1846 } else {
1847 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
1848 }
1849 }
1850
JsFlexBasis(const JSCallbackInfo & info)1851 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
1852 {
1853 if (info.Length() < 1) {
1854 LOGE("JsFlexBasis: The arg is wrong, it is supposed to have at least 1 arguments");
1855 return;
1856 }
1857 CalcDimension value;
1858 if (!ParseJsDimensionVp(info[0], value)) {
1859 value.SetUnit(DimensionUnit::AUTO);
1860 }
1861 // flexbasis don't support percent case.
1862 if (value.Unit() == DimensionUnit::PERCENT) {
1863 value.SetUnit(DimensionUnit::AUTO);
1864 }
1865 ViewAbstractModel::GetInstance()->SetFlexBasis(value);
1866 }
1867
JsFlexGrow(const JSCallbackInfo & info)1868 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
1869 {
1870 if (info.Length() < 1) {
1871 LOGE("JsFlexGrow: The arg is wrong, it is supposed to have at least 1 arguments");
1872 return;
1873 }
1874 double value = 0.0;
1875 if (!ParseJsDouble(info[0], value)) {
1876 if (info[0]->IsNull() || info[0]->IsUndefined()) {
1877 // undefined use default value.
1878 value = 0.0;
1879 } else {
1880 return;
1881 }
1882 }
1883 // negative use default value.
1884 if (value < 0.0) {
1885 value = 0.0;
1886 }
1887 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
1888 }
1889
JsFlexShrink(const JSCallbackInfo & info)1890 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
1891 {
1892 if (info.Length() < 1) {
1893 LOGE("JsFlexShrink: The arg is wrong, it is supposed to have at least 1 arguments");
1894 return;
1895 }
1896 double value = 0.0;
1897 if (!ParseJsDouble(info[0], value)) {
1898 if (info[0]->IsNull() || info[0]->IsUndefined()) {
1899 // undefined use default value.
1900 ViewAbstractModel::GetInstance()->ResetFlexShrink();
1901 } else {
1902 return;
1903 }
1904 }
1905 // negative use default value.
1906 if (value < 0.0) {
1907 ViewAbstractModel::GetInstance()->ResetFlexShrink();
1908 return;
1909 }
1910 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
1911 }
1912
JsDisplayPriority(const JSCallbackInfo & info)1913 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
1914 {
1915 if (info.Length() < 1) {
1916 LOGE("JsDisplayPriority: The arg is wrong, it is supposed to have at least 1 arguments");
1917 return;
1918 }
1919 double value = 0.0;
1920 if (!ParseJsDouble(info[0], value)) {
1921 return;
1922 }
1923 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
1924 }
1925
JsSharedTransition(const JSCallbackInfo & info)1926 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
1927 {
1928 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
1929 if (!CheckJSCallbackInfo("JsSharedTransition", info, checkList)) {
1930 return;
1931 }
1932 // id
1933 auto id = info[0]->ToString();
1934 if (id.empty()) {
1935 LOGE("JsSharedTransition: id is empty.");
1936 return;
1937 }
1938 std::shared_ptr<SharedTransitionOption> sharedOption;
1939
1940 // options
1941 if (info.Length() > 1 && info[1]->IsObject()) {
1942 auto optionsArgs = JsonUtil::ParseJsonString(info[1]->ToString());
1943 sharedOption = std::make_shared<SharedTransitionOption>();
1944 // default: duration: 1000
1945 int32_t duration = DEFAULT_DURATION;
1946 auto durationValue = optionsArgs->GetValue("duration");
1947 if (durationValue && durationValue->IsNumber()) {
1948 duration = durationValue->GetInt();
1949 if (duration < 0) {
1950 duration = DEFAULT_DURATION;
1951 }
1952 }
1953 sharedOption->duration = duration;
1954 // default: delay: 0
1955 auto delay = optionsArgs->GetInt("delay", 0);
1956 if (delay < 0) {
1957 delay = 0;
1958 }
1959 sharedOption->delay = delay;
1960 // default: LinearCurve
1961 RefPtr<Curve> curve;
1962 auto curveArgs = optionsArgs->GetValue("curve");
1963 if (curveArgs->IsString()) {
1964 curve = CreateCurve(optionsArgs->GetString("curve", "linear"), false);
1965 } else if (curveArgs->IsObject()) {
1966 auto curveString = curveArgs->GetValue("__curveString");
1967 if (!curveString) {
1968 return;
1969 }
1970 curve = CreateCurve(curveString->GetString(), false);
1971 }
1972 if (!curve) {
1973 curve = Curves::LINEAR;
1974 }
1975 sharedOption->curve = curve;
1976 // motionPath
1977 if (optionsArgs->Contains("motionPath")) {
1978 MotionPathOption motionPathOption;
1979 if (ParseMotionPath(optionsArgs->GetValue("motionPath"), motionPathOption)) {
1980 sharedOption->motionPathOption = motionPathOption;
1981 }
1982 }
1983 // zIndex
1984 int32_t zIndex = 0;
1985 if (optionsArgs->Contains("zIndex")) {
1986 zIndex = optionsArgs->GetInt("zIndex", 0);
1987 }
1988 sharedOption->zIndex = zIndex;
1989 // type
1990 SharedTransitionEffectType type = SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE;
1991 if (optionsArgs->Contains("type")) {
1992 type = static_cast<SharedTransitionEffectType>(
1993 optionsArgs->GetInt("type", static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE)));
1994 }
1995 sharedOption->type = type;
1996 }
1997 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
1998 }
1999
JsGeometryTransition(const JSCallbackInfo & info)2000 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2001 {
2002 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2003 if (!CheckJSCallbackInfo("JsGeometryTransition", info, checkList)) {
2004 return;
2005 }
2006 // id
2007 auto id = info[0]->ToString();
2008 // follow flag
2009 bool followWithOutTransition = false;
2010 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsBoolean()) {
2011 followWithOutTransition = info[1]->ToBoolean();
2012 }
2013 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition);
2014 }
2015
JsAlignSelf(const JSCallbackInfo & info)2016 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2017 {
2018 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2019 if (!CheckJSCallbackInfo("JsAlignSelf", info, checkList)) {
2020 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2021 return;
2022 }
2023 auto alignVal = info[0]->ToNumber<int32_t>();
2024
2025 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2026 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2027 }
2028 }
2029
JsBackgroundColor(const JSCallbackInfo & info)2030 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2031 {
2032 if (info.Length() < 1) {
2033 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
2034 return;
2035 }
2036 Color backgroundColor;
2037 if (!ParseJsColor(info[0], backgroundColor)) {
2038 backgroundColor = Color::TRANSPARENT;
2039 }
2040
2041 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2042 }
2043
JsBackgroundImage(const JSCallbackInfo & info)2044 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2045 {
2046 if (info.Length() < 1) {
2047 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2048 return;
2049 }
2050
2051 std::string src;
2052 if (info[0]->IsString()) {
2053 src = info[0]->ToString();
2054 } else if (!ParseJsMedia(info[0], src)) {
2055 LOGE("can not parse image src.");
2056 return;
2057 }
2058 std::string bundle;
2059 std::string module;
2060 GetJsMediaBundleInfo(info[0], bundle, module);
2061
2062 int32_t repeatIndex = 0;
2063 if (info.Length() == 2 && info[1]->IsNumber()) {
2064 repeatIndex = info[1]->ToNumber<int32_t>();
2065 }
2066 auto repeat = static_cast<ImageRepeat>(repeatIndex);
2067 if (info[0]->IsString()) {
2068 ViewAbstractModel::GetInstance()->SetBackgroundImage(
2069 ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2070 } else {
2071 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2072 }
2073 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2074 }
2075
JsBackgroundBlurStyle(const JSCallbackInfo & info)2076 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2077 {
2078 if (info.Length() == 0) {
2079 LOGW("The arg of backgroundBlurStyle is wrong, it is supposed to have at least 1 argument");
2080 return;
2081 }
2082 BlurStyleOption styleOption;
2083 if (info[0]->IsNumber()) {
2084 auto blurStyle = info[0]->ToNumber<int32_t>();
2085 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2086 blurStyle <= static_cast<int>(BlurStyle::BACKGROUND_ULTRA_THICK)) {
2087 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2088 }
2089 }
2090 if (info.Length() > 1 && info[1]->IsObject()) {
2091 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2092 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2093 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2094 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2095 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2096 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2097 }
2098 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2099 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2100 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2101 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2102 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2103 }
2104 if (jsOption->GetProperty("scale")->IsNumber()) {
2105 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2106 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2107 }
2108 }
2109 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2110 }
2111
JsBackgroundEffect(const JSCallbackInfo & info)2112 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
2113 {
2114 if (info.Length() == 0) {
2115 LOGW("The arg of backgroundBlurStyle is wrong, it is supposed to have 1 argument");
2116 return;
2117 }
2118 if (!info[0]->IsObject()) {
2119 LOGW("failed to set background effect.");
2120 return;
2121 }
2122 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2123 CalcDimension radius;
2124 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2125 radius.SetValue(0.0f);
2126 }
2127 double saturation = 1.0f;
2128 if (jsOption->GetProperty("saturation")->IsNumber()) {
2129 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2130 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2131 }
2132 double brightness = 1.0f;
2133 if (jsOption->GetProperty("brightness")->IsNumber()) {
2134 brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2135 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2136 }
2137 Color color = Color::TRANSPARENT;
2138 if (!ParseJsColor(jsOption->GetProperty("color"), color)) {
2139 color.SetValue(Color::TRANSPARENT.GetValue());
2140 }
2141 EffectOption option = { radius, saturation, brightness, color };
2142 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
2143 }
2144
JsForegroundBlurStyle(const JSCallbackInfo & info)2145 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
2146 {
2147 if (info.Length() == 0) {
2148 LOGW("The arg of foregroundBlurStyle is wrong, it is supposed to have at least 1 argument");
2149 return;
2150 }
2151 BlurStyleOption styleOption;
2152 if (info[0]->IsNumber()) {
2153 auto blurStyle = info[0]->ToNumber<int32_t>();
2154 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2155 blurStyle <= static_cast<int>(BlurStyle::BACKGROUND_ULTRA_THICK)) {
2156 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2157 }
2158 }
2159 if (info.Length() > 1 && info[1]->IsObject()) {
2160 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2161 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2162 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2163 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2164 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2165 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2166 }
2167 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2168 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2169 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2170 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2171 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2172 }
2173 if (jsOption->GetProperty("scale")->IsNumber()) {
2174 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2175 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2176 }
2177 }
2178 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
2179 }
2180
JsSphericalEffect(const JSCallbackInfo & info)2181 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
2182 {
2183 if (info.Length() < 1) {
2184 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2185 return;
2186 }
2187 auto radio = 0.0;
2188 if (info[0]->IsNumber()) {
2189 radio = info[0]->ToNumber<double>();
2190 }
2191 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
2192 }
2193
JsPixelStretchEffect(const JSCallbackInfo & info)2194 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
2195 {
2196 if (info.Length() < 1) {
2197 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2198 return;
2199 }
2200
2201 if (!info[0]->IsObject()) {
2202 PixStretchEffectOption option;
2203 option.ResetValue();
2204 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2205 return;
2206 }
2207 auto jsObject = JSRef<JSObject>::Cast(info[0]);
2208 CalcDimension left;
2209 ParseJsDimensionVp(jsObject->GetProperty("left"), left);
2210 CalcDimension right;
2211 ParseJsDimensionVp(jsObject->GetProperty("right"), right);
2212 CalcDimension top;
2213 ParseJsDimensionVp(jsObject->GetProperty("top"), top);
2214 CalcDimension bottom;
2215 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
2216
2217 PixStretchEffectOption option;
2218 bool illegalInput = false;
2219 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
2220 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
2221 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
2222 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
2223 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
2224 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
2225 left.SetUnit(DimensionUnit::PERCENT);
2226 top.SetUnit(DimensionUnit::PERCENT);
2227 right.SetUnit(DimensionUnit::PERCENT);
2228 bottom.SetUnit(DimensionUnit::PERCENT);
2229 } else {
2230 illegalInput = true;
2231 }
2232 }
2233 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
2234 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
2235 option.left = left;
2236 option.top = top;
2237 option.right = right;
2238 option.bottom = bottom;
2239 } else {
2240 illegalInput = true;
2241 }
2242 if (illegalInput) {
2243 option.ResetValue();
2244 }
2245 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2246 }
2247
JsLightUpEffect(const JSCallbackInfo & info)2248 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
2249 {
2250 if (info.Length() < 1) {
2251 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2252 return;
2253 }
2254 auto radio = 1.0;
2255 if (info[0]->IsNumber()) {
2256 radio = info[0]->ToNumber<double>();
2257 }
2258 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
2259 }
2260
JsBackgroundImageSize(const JSCallbackInfo & info)2261 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
2262 {
2263 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2264 BackgroundImageSize bgImgSize;
2265 if (!CheckJSCallbackInfo("JsBackgroundImageSize", info, checkList)) {
2266 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2267 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2268 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2269 return;
2270 }
2271 if (info[0]->IsNumber()) {
2272 auto sizeType = static_cast<BackgroundImageSizeType>(info[0]->ToNumber<int32_t>());
2273 bgImgSize.SetSizeTypeX(sizeType);
2274 bgImgSize.SetSizeTypeY(sizeType);
2275 } else {
2276 auto imageArgs = JsonUtil::ParseJsonString(info[0]->ToString());
2277 if (imageArgs->IsNull()) {
2278 LOGE("Js Parse failed. imageArgs is null.");
2279 return;
2280 }
2281 CalcDimension width;
2282 CalcDimension height;
2283 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2284 ParseJsDimensionVp(object->GetProperty("width"), width);
2285 ParseJsDimensionVp(object->GetProperty("height"), height);
2286 double valueWidth = width.ConvertToPx();
2287 double valueHeight = height.ConvertToPx();
2288 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
2289 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
2290 if (width.Unit() == DimensionUnit::PERCENT) {
2291 typeWidth = BackgroundImageSizeType::PERCENT;
2292 valueWidth = width.Value() * FULL_DIMENSION;
2293 }
2294 if (height.Unit() == DimensionUnit::PERCENT) {
2295 typeHeight = BackgroundImageSizeType::PERCENT;
2296 valueHeight = height.Value() * FULL_DIMENSION;
2297 }
2298 bgImgSize.SetSizeTypeX(typeWidth);
2299 bgImgSize.SetSizeValueX(valueWidth);
2300 bgImgSize.SetSizeTypeY(typeHeight);
2301 bgImgSize.SetSizeValueY(valueHeight);
2302 }
2303
2304 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2305 }
2306
JsBackgroundImagePosition(const JSCallbackInfo & info)2307 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
2308 {
2309 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2310 BackgroundImagePosition bgImgPosition;
2311 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", info, checkList)) {
2312 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
2313 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2314 return;
2315 }
2316 if (info[0]->IsNumber()) {
2317 int32_t align = info[0]->ToNumber<int32_t>();
2318 bgImgPosition.SetIsAlign(true);
2319 switch (align) {
2320 case 0:
2321 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, 0.0, 0.0, bgImgPosition);
2322 break;
2323 case 1:
2324 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, HALF_DIMENSION, 0.0, bgImgPosition);
2325 break;
2326 case 2:
2327 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, FULL_DIMENSION, 0.0, bgImgPosition);
2328 break;
2329 case 3:
2330 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, 0.0, HALF_DIMENSION, bgImgPosition);
2331 break;
2332 case 4:
2333 SetBgImgPosition(
2334 DimensionUnit::PERCENT, DimensionUnit::PERCENT, HALF_DIMENSION, HALF_DIMENSION, bgImgPosition);
2335 break;
2336 case 5:
2337 SetBgImgPosition(
2338 DimensionUnit::PERCENT, DimensionUnit::PERCENT, FULL_DIMENSION, HALF_DIMENSION, bgImgPosition);
2339 break;
2340 case 6:
2341 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, 0.0, FULL_DIMENSION, bgImgPosition);
2342 break;
2343 case 7:
2344 SetBgImgPosition(
2345 DimensionUnit::PERCENT, DimensionUnit::PERCENT, HALF_DIMENSION, FULL_DIMENSION, bgImgPosition);
2346 break;
2347 case 8:
2348 SetBgImgPosition(
2349 DimensionUnit::PERCENT, DimensionUnit::PERCENT, FULL_DIMENSION, FULL_DIMENSION, bgImgPosition);
2350 break;
2351 default:
2352 break;
2353 }
2354 } else {
2355 auto imageArgs = JsonUtil::ParseJsonString(info[0]->ToString());
2356 if (imageArgs->IsNull()) {
2357 LOGE("Js Parse failed. imageArgs is null.");
2358 return;
2359 }
2360 CalcDimension x;
2361 CalcDimension y;
2362 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2363 ParseJsDimensionVp(object->GetProperty("x"), x);
2364 ParseJsDimensionVp(object->GetProperty("y"), y);
2365 double valueX = x.Value();
2366 double valueY = y.Value();
2367 DimensionUnit typeX = DimensionUnit::PX;
2368 DimensionUnit typeY = DimensionUnit::PX;
2369 if (x.Unit() == DimensionUnit::PERCENT) {
2370 valueX = x.Value();
2371 typeX = DimensionUnit::PERCENT;
2372 }
2373 if (y.Unit() == DimensionUnit::PERCENT) {
2374 valueY = y.Value();
2375 typeY = DimensionUnit::PERCENT;
2376 }
2377 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
2378 }
2379
2380 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2381 }
2382
ParseBindOptionParam(const JSCallbackInfo & info)2383 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info)
2384 {
2385 auto paramArray = JSRef<JSArray>::Cast(info[0]);
2386 std::vector<NG::OptionParam> params(paramArray->Length());
2387 // parse paramArray
2388 LOGD("parsing paramArray size = %{public}d", static_cast<int>(paramArray->Length()));
2389 for (size_t i = 0; i < paramArray->Length(); ++i) {
2390 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
2391 JSViewAbstract::ParseJsString(indexObject->GetProperty("value"), params[i].value);
2392 LOGD("option #%{public}d is %{public}s", static_cast<int>(i), params[i].value.c_str());
2393 auto actionFunc = indexObject->GetProperty("action");
2394 if (!actionFunc->IsFunction()) {
2395 return params;
2396 }
2397 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
2398 // set onClick function
2399 params[i].action = [func = std::move(action), context = info.GetExecutionContext()]() {
2400 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
2401 ACE_SCORING_EVENT("menu.action");
2402 if (func) {
2403 func->Execute();
2404 }
2405 };
2406 std::string iconPath;
2407 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty("icon"), iconPath)) {
2408 params[i].icon = iconPath;
2409 }
2410 }
2411 return params;
2412 }
2413
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)2414 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
2415 {
2416 auto enableArrowValue = menuOptions->GetProperty("enableArrow");
2417 if (enableArrowValue->IsBoolean()) {
2418 menuParam.enableArrow = enableArrowValue->ToBoolean();
2419 }
2420
2421 auto arrowOffset = menuOptions->GetProperty("arrowOffset");
2422 CalcDimension offset;
2423 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
2424 menuParam.arrowOffset = offset;
2425 }
2426
2427 // if enableArrow is true and placement not set, set placement default value to top.
2428 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
2429 menuParam.placement = Placement::TOP;
2430 }
2431 }
2432
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)2433 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
2434 {
2435 auto offsetVal = menuOptions->GetProperty("offset");
2436 if (offsetVal->IsObject()) {
2437 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
2438 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2439 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2440 CalcDimension dx;
2441 CalcDimension dy;
2442 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
2443 menuParam.positionOffset.SetX(dx.ConvertToPx());
2444 }
2445 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
2446 menuParam.positionOffset.SetY(dy.ConvertToPx());
2447 }
2448 }
2449
2450 auto placementValue = menuOptions->GetProperty("placement");
2451 if (placementValue->IsNumber()) {
2452 auto placement = placementValue->ToNumber<int32_t>();
2453 if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
2454 menuParam.placement = PLACEMENT[placement];
2455 }
2456 }
2457
2458 auto onAppearValue = menuOptions->GetProperty("onAppear");
2459 if (onAppearValue->IsFunction()) {
2460 RefPtr<JsFunction> jsOnAppearFunc =
2461 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
2462 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc)]() {
2463 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2464 LOGI("About to call onAppear method on js");
2465 ACE_SCORING_EVENT("onAppear");
2466 func->Execute();
2467 };
2468 menuParam.onAppear = std::move(onAppear);
2469 }
2470
2471 auto onDisappearValue = menuOptions->GetProperty("onDisappear");
2472 if (onDisappearValue->IsFunction()) {
2473 RefPtr<JsFunction> jsOnDisAppearFunc =
2474 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
2475 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc)]() {
2476 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2477 LOGI("About to call onAppear method on js");
2478 ACE_SCORING_EVENT("onDisappear");
2479 func->Execute();
2480 };
2481 menuParam.onDisappear = std::move(onDisappear);
2482 }
2483
2484 ParseMenuArrowParam(menuOptions, menuParam);
2485 }
2486
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam)2487 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam)
2488 {
2489 auto menuOptions = JSRef<JSObject>::Cast(info[1]);
2490 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
2491 ParseMenuParam(info, menuOptions, menuParam);
2492 }
2493
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam)2494 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam)
2495 {
2496 auto menuContentOptions = JSRef<JSObject>::Cast(args);
2497 ParseMenuParam(info, menuContentOptions, menuParam);
2498 }
2499
JsBindMenu(const JSCallbackInfo & info)2500 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
2501 {
2502 NG::MenuParam menuParam;
2503 auto container = Container::Current();
2504 CHECK_NULL_VOID(container);
2505 auto pipelineContext = container->GetPipelineContext();
2506 CHECK_NULL_VOID(pipelineContext);
2507 if (pipelineContext->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
2508 menuParam.placement = Placement::BOTTOM_LEFT;
2509 }
2510 if (info.Length() > PARAMETER_LENGTH_FIRST && info[1]->IsObject()) {
2511 ParseBindOptionParam(info, menuParam);
2512 }
2513 if (info[0]->IsArray()) {
2514 std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info);
2515 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
2516 } else if (info[0]->IsObject()) {
2517 // CustomBuilder
2518 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
2519 auto builder = obj->GetProperty("builder");
2520 if (!builder->IsFunction()) {
2521 LOGE("builder param is not a function.");
2522 return;
2523 }
2524 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2525 CHECK_NULL_VOID(builderFunc);
2526 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
2527 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2528 ACE_SCORING_EVENT("BuildMenu");
2529 func->Execute();
2530 };
2531 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
2532 } else {
2533 LOGE("bindMenu info is invalid");
2534 }
2535 }
2536
JsPadding(const JSCallbackInfo & info)2537 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
2538 {
2539 ParseMarginOrPadding(info, false);
2540 }
2541
JsMargin(const JSCallbackInfo & info)2542 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
2543 {
2544 ParseMarginOrPadding(info, true);
2545 }
2546
ParseMarginOrPadding(const JSCallbackInfo & info,bool isMargin)2547 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, bool isMargin)
2548 {
2549 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
2550 JSCallbackInfoType::NUMBER };
2551 if (!CheckJSCallbackInfo("MarginOrPadding", info, checkList)) {
2552 auto resetDimension = CalcDimension(0.0);
2553 if (isMargin) {
2554 ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
2555 } else {
2556 ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
2557 }
2558 return;
2559 }
2560 if (info[0]->IsObject()) {
2561 std::optional<CalcDimension> left;
2562 std::optional<CalcDimension> right;
2563 std::optional<CalcDimension> top;
2564 std::optional<CalcDimension> bottom;
2565 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info[0]);
2566
2567 CalcDimension leftDimen;
2568 if (ParseJsDimensionVp(paddingObj->GetProperty("left"), leftDimen)) {
2569 left = leftDimen;
2570 }
2571 CalcDimension rightDimen;
2572 if (ParseJsDimensionVp(paddingObj->GetProperty("right"), rightDimen)) {
2573 right = rightDimen;
2574 }
2575 CalcDimension topDimen;
2576 if (ParseJsDimensionVp(paddingObj->GetProperty("top"), topDimen)) {
2577 top = topDimen;
2578 }
2579 CalcDimension bottomDimen;
2580 if (ParseJsDimensionVp(paddingObj->GetProperty("bottom"), bottomDimen)) {
2581 bottom = bottomDimen;
2582 }
2583 if (left.has_value() || right.has_value() || top.has_value() || bottom.has_value()) {
2584 if (isMargin) {
2585 ViewAbstractModel::GetInstance()->SetMargins(top, bottom, left, right);
2586 } else {
2587 ViewAbstractModel::GetInstance()->SetPaddings(top, bottom, left, right);
2588 }
2589 return;
2590 }
2591 }
2592
2593 CalcDimension length;
2594 if (!ParseJsDimensionVp(info[0], length)) {
2595 // use default value.
2596 length.Reset();
2597 }
2598 if (isMargin) {
2599 ViewAbstractModel::GetInstance()->SetMargin(length);
2600 } else {
2601 ViewAbstractModel::GetInstance()->SetPadding(length);
2602 }
2603 }
2604
JsBorder(const JSCallbackInfo & info)2605 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
2606 {
2607 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2608 if (!CheckJSCallbackInfo("JsBorder", info, checkList)) {
2609 LOGE("args is not a object. %s", info[0]->ToString().c_str());
2610 CalcDimension borderWidth;
2611 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
2612 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
2613 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
2614 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
2615 return;
2616 }
2617 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2618 auto valueWidth = object->GetProperty("width");
2619 if (!valueWidth->IsUndefined()) {
2620 ParseBorderWidth(valueWidth);
2621 }
2622
2623 // use default value when undefined.
2624 ParseBorderColor(object->GetProperty("color"));
2625
2626 auto valueRadius = object->GetProperty("radius");
2627 if (!valueRadius->IsUndefined()) {
2628 ParseBorderRadius(valueRadius);
2629 }
2630 // use default value when undefined.
2631 ParseBorderStyle(object->GetProperty("style"));
2632
2633 info.ReturnSelf();
2634 }
2635
JsBorderWidth(const JSCallbackInfo & info)2636 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
2637 {
2638 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
2639 JSCallbackInfoType::OBJECT };
2640 if (!CheckJSCallbackInfo("JsBorderWidth", info, checkList)) {
2641 LOGW("args need a string or number or object");
2642 ViewAbstractModel::GetInstance()->SetBorderWidth({});
2643 return;
2644 }
2645 ParseBorderWidth(info[0]);
2646 }
2647
ParseBorderWidth(const JSRef<JSVal> & args)2648 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
2649 {
2650 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
2651 LOGE("args need a object or number or string. %{public}s", args->ToString().c_str());
2652 return;
2653 }
2654 std::optional<CalcDimension> leftDimen;
2655 std::optional<CalcDimension> rightDimen;
2656 std::optional<CalcDimension> topDimen;
2657 std::optional<CalcDimension> bottomDimen;
2658 CalcDimension borderWidth;
2659 if (ParseJsDimensionVp(args, borderWidth)) {
2660 if (borderWidth.IsNegative()) {
2661 borderWidth.Reset();
2662 }
2663 if (borderWidth.Unit() == DimensionUnit::PERCENT) {
2664 borderWidth.Reset();
2665 }
2666 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
2667 } else if (args->IsObject()) {
2668 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
2669 CalcDimension left;
2670 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
2671 if (left.Unit() == DimensionUnit::PERCENT) {
2672 left.Reset();
2673 }
2674 leftDimen = left;
2675 }
2676 CalcDimension right;
2677 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
2678 if (right.Unit() == DimensionUnit::PERCENT) {
2679 right.Reset();
2680 }
2681 rightDimen = right;
2682 }
2683 CalcDimension top;
2684 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
2685 if (top.Unit() == DimensionUnit::PERCENT) {
2686 top.Reset();
2687 }
2688 topDimen = top;
2689 }
2690 CalcDimension bottom;
2691 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
2692 if (bottom.Unit() == DimensionUnit::PERCENT) {
2693 bottom.Reset();
2694 }
2695 bottomDimen = bottom;
2696 }
2697 ViewAbstractModel::GetInstance()->SetBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
2698 } else {
2699 LOGE("args format error. %{public}s", args->ToString().c_str());
2700 return;
2701 }
2702 }
2703
ParseMenuOptions(const JSCallbackInfo & info,const JSRef<JSArray> & jsArray,std::vector<NG::MenuOptionsParam> & items)2704 void JSViewAbstract::ParseMenuOptions(
2705 const JSCallbackInfo& info, const JSRef<JSArray>& jsArray, std::vector<NG::MenuOptionsParam>& items)
2706 {
2707 auto length = jsArray->Length();
2708 for (size_t i = 0; i < length; i++) {
2709 auto item = jsArray->GetValueAt(i);
2710 if (!item->IsObject()) {
2711 LOGI("menu option item is not object");
2712 continue;
2713 }
2714 auto itemObject = JSRef<JSObject>::Cast(item);
2715 NG::MenuOptionsParam menuOptionItem;
2716 std::string value;
2717 std::string icon;
2718 auto menuOptionsValue = itemObject->GetProperty("content");
2719 auto menuOptionsIcon = itemObject->GetProperty("icon");
2720
2721 if (!ParseJsString(menuOptionsValue, value)) {
2722 LOGI("menuOptionsValue is null");
2723 return;
2724 }
2725 if (!ParseJsMedia(menuOptionsIcon, icon)) {
2726 LOGI("menuOptionsIcon is null");
2727 }
2728 menuOptionItem.content = value;
2729 menuOptionItem.icon = icon;
2730
2731 auto itemActionValue = itemObject->GetProperty("action");
2732 if (itemActionValue->IsFunction()) {
2733 JsEventCallback<void(const std::string&)> callback(
2734 info.GetExecutionContext(), JSRef<JSFunc>::Cast(itemActionValue));
2735 menuOptionItem.action = callback;
2736 }
2737 items.emplace_back(menuOptionItem);
2738 }
2739 }
2740
JsBorderImage(const JSCallbackInfo & info)2741 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
2742 {
2743 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2744 if (!CheckJSCallbackInfo("JsBorderImage", info, checkList)) {
2745 LOGE("args is not a object. %{public}s", info[0]->ToString().c_str());
2746 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
2747 uint8_t imageBorderBitsets = 0;
2748 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
2749 return;
2750 }
2751 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2752 if (object->IsEmpty()) {
2753 return;
2754 }
2755
2756 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
2757 uint8_t imageBorderBitsets = 0;
2758
2759 auto valueSource = object->GetProperty("source");
2760 if (!valueSource->IsString() && !valueSource->IsObject()) {
2761 LOGE("Border image source type not recognized");
2762 return;
2763 }
2764 std::string srcResult;
2765 if (valueSource->IsString()) {
2766 srcResult = valueSource->ToString();
2767 if (!srcResult.empty()) {
2768 borderImage->SetSrc(srcResult);
2769 imageBorderBitsets |= BorderImage::SOURCE_BIT;
2770 }
2771 } else if (valueSource->IsObject()) {
2772 if (ParseJsMedia(valueSource, srcResult)) {
2773 borderImage->SetSrc(srcResult);
2774 imageBorderBitsets |= BorderImage::SOURCE_BIT;
2775 } else {
2776 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
2777 }
2778 }
2779 auto valueOutset = object->GetProperty("outset");
2780 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
2781 imageBorderBitsets |= BorderImage::OUTSET_BIT;
2782 ParseBorderImageOutset(valueOutset, borderImage);
2783 }
2784 auto valueRepeat = object->GetProperty("repeat");
2785 if (!valueRepeat->IsNull()) {
2786 imageBorderBitsets |= BorderImage::REPEAT_BIT;
2787 ParseBorderImageRepeat(valueRepeat, borderImage);
2788 }
2789 auto valueSlice = object->GetProperty("slice");
2790 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
2791 imageBorderBitsets |= BorderImage::SLICE_BIT;
2792 ParseBorderImageSlice(valueSlice, borderImage);
2793 }
2794 auto valueWidth = object->GetProperty("width");
2795 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
2796 imageBorderBitsets |= BorderImage::WIDTH_BIT;
2797 ParseBorderImageWidth(valueWidth, borderImage);
2798 }
2799 auto needFill = object->GetProperty("fill");
2800 if (needFill->IsBoolean()) {
2801 borderImage->SetNeedFillCenter(needFill->ToBoolean());
2802 }
2803 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
2804 info.ReturnSelf();
2805 }
2806
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)2807 void JSViewAbstract::ParseBorderImageDimension(
2808 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
2809 {
2810 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
2811 static std::array<std::string, 4> keys = { "left", "right", "top", "bottom" };
2812 for (uint32_t i = 0; i < keys.size(); i++) {
2813 CalcDimension currentDimension;
2814 auto dimensionValue = object->GetProperty(keys.at(i).c_str());
2815 if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
2816 auto direction = static_cast<BorderImageDirection>(i);
2817 switch (direction) {
2818 case BorderImageDirection::LEFT:
2819 borderImageDimension.leftDimension = currentDimension;
2820 break;
2821 case BorderImageDirection::RIGHT:
2822 borderImageDimension.rightDimension = currentDimension;
2823 break;
2824 case BorderImageDirection::TOP:
2825 borderImageDimension.topDimension = currentDimension;
2826 break;
2827 case BorderImageDirection::BOTTOM:
2828 borderImageDimension.bottomDimension = currentDimension;
2829 break;
2830 default:
2831 LOGE("Unsupported border image direction");
2832 break;
2833 }
2834 }
2835 }
2836 }
2837
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)2838 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
2839 {
2840 auto argsPtrItem = JsonUtil::ParseJsonString(args->ToString());
2841 if (!argsPtrItem || argsPtrItem->IsNull()) {
2842 LOGE("Parse border image linear gradient failed. argsPtr is null. %{public}s", args->ToString().c_str());
2843 return;
2844 }
2845 NG::Gradient lineGradient;
2846 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
2847 // angle
2848 std::optional<float> degree;
2849 GetAngle("angle", argsPtrItem, degree);
2850 if (degree) {
2851 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
2852 degree.reset();
2853 }
2854 // direction
2855 auto direction = static_cast<NG::GradientDirection>(
2856 argsPtrItem->GetInt("direction", static_cast<int32_t>(NG::GradientDirection::NONE)));
2857 switch (direction) {
2858 case NG::GradientDirection::LEFT:
2859 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
2860 break;
2861 case NG::GradientDirection::RIGHT:
2862 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
2863 break;
2864 case NG::GradientDirection::TOP:
2865 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
2866 break;
2867 case NG::GradientDirection::BOTTOM:
2868 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
2869 break;
2870 case NG::GradientDirection::LEFT_TOP:
2871 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
2872 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
2873 break;
2874 case NG::GradientDirection::LEFT_BOTTOM:
2875 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
2876 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
2877 break;
2878 case NG::GradientDirection::RIGHT_TOP:
2879 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
2880 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
2881 break;
2882 case NG::GradientDirection::RIGHT_BOTTOM:
2883 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
2884 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
2885 break;
2886 case NG::GradientDirection::NONE:
2887 case NG::GradientDirection::START_TO_END:
2888 case NG::GradientDirection::END_TO_START:
2889 default:
2890 break;
2891 }
2892 auto repeating = argsPtrItem->GetBool("repeating", false);
2893 lineGradient.SetRepeat(repeating);
2894 NewGetGradientColorStops(lineGradient, argsPtrItem->GetValue("colors"));
2895 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
2896 bitset |= BorderImage::GRADIENT_BIT;
2897 }
2898
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)2899 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
2900 {
2901 auto repeatString = args->ToString();
2902 if (repeatString == "Repeat") {
2903 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
2904 } else if (repeatString == "Round") {
2905 borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
2906 } else if (repeatString == "Space") {
2907 borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
2908 } else {
2909 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
2910 }
2911 }
2912
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)2913 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
2914 {
2915 CalcDimension outsetDimension;
2916 if (ParseJsDimensionVp(args, outsetDimension)) {
2917 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
2918 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
2919 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
2920 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
2921 return;
2922 }
2923 BorderImage::BorderImageOption option;
2924 ParseBorderImageDimension(args, option);
2925 if (option.leftDimension.has_value()) {
2926 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
2927 }
2928 if (option.rightDimension.has_value()) {
2929 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
2930 }
2931 if (option.topDimension.has_value()) {
2932 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
2933 }
2934 if (option.bottomDimension.has_value()) {
2935 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
2936 }
2937 }
2938
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)2939 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
2940 {
2941 CalcDimension sliceDimension;
2942 if (ParseJsDimensionVp(args, sliceDimension)) {
2943 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
2944 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
2945 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
2946 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
2947 return;
2948 }
2949
2950 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
2951 static std::array<std::string, 4> keys = { "left", "right", "top", "bottom" };
2952 for (uint32_t i = 0; i < keys.size(); i++) {
2953 auto dimensionValue = object->GetProperty(keys.at(i).c_str());
2954 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
2955 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
2956 }
2957 }
2958 }
2959
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)2960 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
2961 {
2962 CalcDimension widthDimension;
2963 if (ParseJsDimensionVp(args, widthDimension)) {
2964 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
2965 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
2966 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
2967 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
2968 return;
2969 }
2970
2971 BorderImage::BorderImageOption option;
2972 ParseBorderImageDimension(args, option);
2973 if (option.leftDimension.has_value()) {
2974 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
2975 }
2976 if (option.rightDimension.has_value()) {
2977 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
2978 }
2979 if (option.topDimension.has_value()) {
2980 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
2981 }
2982 if (option.bottomDimension.has_value()) {
2983 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
2984 }
2985 }
2986
JsBorderColor(const JSCallbackInfo & info)2987 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
2988 {
2989 ParseBorderColor(info[0]);
2990 }
2991
ParseBorderColor(const JSRef<JSVal> & args)2992 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
2993 {
2994 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
2995 LOGI("args(%{public}s) is invalid, use default value.", args->ToString().c_str());
2996 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
2997 return;
2998 }
2999 std::optional<Color> leftColor;
3000 std::optional<Color> rightColor;
3001 std::optional<Color> topColor;
3002 std::optional<Color> bottomColor;
3003 Color borderColor;
3004 if (ParseJsColor(args, borderColor)) {
3005 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
3006 } else if (args->IsObject()) {
3007 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3008 Color left;
3009 if (ParseJsColor(object->GetProperty("left"), left)) {
3010 leftColor = left;
3011 }
3012 Color right;
3013 if (ParseJsColor(object->GetProperty("right"), right)) {
3014 rightColor = right;
3015 }
3016 Color top;
3017 if (ParseJsColor(object->GetProperty("top"), top)) {
3018 topColor = top;
3019 }
3020 Color bottom;
3021 if (ParseJsColor(object->GetProperty("bottom"), bottom)) {
3022 bottomColor = bottom;
3023 }
3024
3025 ViewAbstractModel::GetInstance()->SetBorderColor(leftColor, rightColor, topColor, bottomColor);
3026 } else {
3027 LOGE("args format error. %{public}s", args->ToString().c_str());
3028 return;
3029 }
3030 }
3031
JsBorderRadius(const JSCallbackInfo & info)3032 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
3033 {
3034 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3035 JSCallbackInfoType::OBJECT };
3036 if (!CheckJSCallbackInfo("JsBorderRadius", info, checkList)) {
3037 LOGW("args need a string or number or object");
3038 ViewAbstractModel::GetInstance()->SetBorderRadius({});
3039 return;
3040 }
3041 ParseBorderRadius(info[0]);
3042 }
3043
ParseBorderRadius(const JSRef<JSVal> & args)3044 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
3045 {
3046 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
3047 LOGE("args need a object or number or string. %{public}s", args->ToString().c_str());
3048 return;
3049 }
3050 CalcDimension borderRadius;
3051 if (ParseJsDimensionVp(args, borderRadius)) {
3052 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
3053 borderRadius.Reset();
3054 }
3055 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
3056 } else if (args->IsObject()) {
3057 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3058 CalcDimension topLeft;
3059 GetBorderRadius("topLeft", object, topLeft);
3060 CalcDimension topRight;
3061 GetBorderRadius("topRight", object, topRight);
3062 CalcDimension bottomLeft;
3063 GetBorderRadius("bottomLeft", object, bottomLeft);
3064 CalcDimension bottomRight;
3065 GetBorderRadius("bottomRight", object, bottomRight);
3066 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3067 } else {
3068 LOGE("args format error. %{public}s", args->ToString().c_str());
3069 return;
3070 }
3071 }
3072
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)3073 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
3074 {
3075 if (ParseJsDimensionVp(object->GetProperty(key), radius)) {
3076 if ((radius.Unit() == DimensionUnit::PERCENT)) {
3077 radius.Reset();
3078 }
3079 }
3080 }
3081
JsBorderStyle(const JSCallbackInfo & info)3082 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
3083 {
3084 ParseBorderStyle(info[0]);
3085 }
3086 namespace {
ConvertBorderStyle(int32_t value)3087 BorderStyle ConvertBorderStyle(int32_t value)
3088 {
3089 auto style = static_cast<BorderStyle>(value);
3090 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
3091 LOGW("border style(%{public}d) is invalid, use default value.", value);
3092 style = BorderStyle::SOLID;
3093 }
3094 return style;
3095 }
3096 } // namespace
3097
ParseBorderStyle(const JSRef<JSVal> & args)3098 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
3099 {
3100 if (!args->IsObject() && !args->IsNumber()) {
3101 LOGD("args(%{public}s) is invalid, use default value.", args->ToString().c_str());
3102 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3103 return;
3104 }
3105 if (args->IsObject()) {
3106 std::optional<BorderStyle> styleLeft;
3107 std::optional<BorderStyle> styleRight;
3108 std::optional<BorderStyle> styleTop;
3109 std::optional<BorderStyle> styleBottom;
3110 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3111 auto leftValue = object->GetProperty("left");
3112 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
3113 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3114 }
3115 auto rightValue = object->GetProperty("right");
3116 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
3117 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3118 }
3119 auto topValue = object->GetProperty("top");
3120 if (!topValue->IsUndefined() && topValue->IsNumber()) {
3121 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3122 }
3123 auto bottomValue = object->GetProperty("bottom");
3124 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
3125 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3126 }
3127 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3128 return;
3129 }
3130 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3131 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
3132 }
3133
JsBlur(const JSCallbackInfo & info)3134 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
3135 {
3136 if (info.Length() < 1) {
3137 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
3138 return;
3139 }
3140
3141 double blur = 0.0;
3142 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3143 JSCallbackInfoType::NUMBER };
3144 if (!CheckJSCallbackInfo("Blur", info, checkList)) {
3145 SetBlur(blur);
3146 info.SetReturnValue(info.This());
3147 return;
3148 }
3149 if (!ParseJsDouble(info[0], blur)) {
3150 return;
3151 }
3152 SetBlur(blur);
3153 info.SetReturnValue(info.This());
3154 }
3155
JsColorBlend(const JSCallbackInfo & info)3156 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
3157 {
3158 if (info.Length() < 1) {
3159 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
3160 return;
3161 }
3162 Color colorBlend;
3163 if (info[0]->IsUndefined()) {
3164 colorBlend = Color::TRANSPARENT;
3165 SetColorBlend(colorBlend);
3166 return;
3167 }
3168 if (!ParseJsColor(info[0], colorBlend)) {
3169 return;
3170 }
3171 SetColorBlend(colorBlend);
3172 info.SetReturnValue(info.This());
3173 }
3174
JsUseEffect(const JSCallbackInfo & info)3175 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
3176 {
3177 if (info[0]->IsBoolean()) {
3178 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean());
3179 }
3180 }
3181
JsBackdropBlur(const JSCallbackInfo & info)3182 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
3183 {
3184 if (info.Length() < 1) {
3185 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
3186 return;
3187 }
3188
3189 double blur = 0.0;
3190 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3191 JSCallbackInfoType::NUMBER };
3192 if (!CheckJSCallbackInfo("BackdropBlur", info, checkList)) {
3193 SetBackdropBlur(blur);
3194 info.SetReturnValue(info.This());
3195 return;
3196 }
3197 if (!ParseJsDouble(info[0], blur)) {
3198 return;
3199 }
3200 SetBackdropBlur(blur);
3201 info.SetReturnValue(info.This());
3202 }
3203
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const std::unique_ptr<JsonValue> & array)3204 void JSViewAbstract::GetFractionStops(
3205 std::vector<std::pair<float, float>>& fractionStops, const std::unique_ptr<JsonValue>& array)
3206 {
3207 if (!array || !array->IsArray() || static_cast<int32_t>(array->GetArraySize()) <= 1) {
3208 LOGI("Js Parse object failed, fractionStops is invalid");
3209 return;
3210 }
3211 float tmpPos = -1.0f;
3212 for (int32_t i = 0; i < array->GetArraySize(); i++) {
3213 std::pair<float, float> fractionStop;
3214 auto item = array->GetArrayItem(i);
3215 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
3216 auto fraction = item->GetArrayItem(0);
3217 double value = 0.0;
3218 if (ParseJsonDouble(fraction, value)) {
3219 value = std::clamp(value, 0.0, 1.0);
3220 fractionStop.first = static_cast<float>(value);
3221 }
3222 if (item->GetArraySize() <= 1) {
3223 continue;
3224 }
3225 auto stop = item->GetArrayItem(1);
3226 value = 0.0;
3227 if (ParseJsonDouble(stop, value)) {
3228 value = std::clamp(value, 0.0, 1.0);
3229 fractionStop.second = static_cast<float>(value);
3230 }
3231 }
3232 if (fractionStop.second <= tmpPos) {
3233 LOGE("fraction stop postion is not incremental.");
3234 fractionStops.clear();
3235 return;
3236 }
3237 tmpPos = fractionStop.second;
3238 fractionStops.push_back(fractionStop);
3239 }
3240 }
JsLinearGradientBlur(const JSCallbackInfo & info)3241 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
3242 {
3243 if (info.Length() < 2) { // 2 represents the least para num;
3244 LOGE("The argv is wrong, it is supposed to have at least 2 argument");
3245 return;
3246 }
3247 double blurRadius = 0.0;
3248 ParseJsDouble(info[0], blurRadius);
3249 blurRadius = std::clamp(blurRadius, 0.0, 60.0); // 60.0 represents largest blur radius;
3250
3251 std::vector<std::pair<float, float>> fractionStops;
3252 auto direction = GradientDirection::BOTTOM;
3253 if (info[1]->IsObject()) {
3254 auto argsPtrItem = JsonUtil::ParseJsonString(info[1]->ToString());
3255 if (argsPtrItem && !argsPtrItem->IsNull()) {
3256 auto array = argsPtrItem->GetValue("fractionStops");
3257 if (array) {
3258 GetFractionStops(fractionStops, array);
3259 }
3260 auto directionValue = argsPtrItem->GetInt("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
3261 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
3262 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
3263 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
3264 }
3265 direction = static_cast<GradientDirection>(directionValue);
3266 }
3267 }
3268 if (static_cast<int32_t>(fractionStops.size()) <= 1) {
3269 fractionStops.clear();
3270 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
3271 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
3272 }
3273 // Parse direction
3274 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
3275 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
3276 SetLinearGradientBlur(blurPara);
3277 }
3278
JsDynamicLightUp(const JSCallbackInfo & info)3279 void JSViewAbstract::JsDynamicLightUp(const JSCallbackInfo& info)
3280 {
3281 if (info.Length() == 0) {
3282 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
3283 return;
3284 }
3285 if (!info[0]->IsObject()) {
3286 LOGE("arg is not a object.");
3287 return;
3288 }
3289 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3290 if (!argsPtrItem || argsPtrItem->IsNull()) {
3291 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
3292 return;
3293 }
3294
3295 double rate = 0.0;
3296 double lightUpDegree = 0.0;
3297 if (!ParseJsonDouble(argsPtrItem->GetValue("rate"), rate)) {
3298 LOGE("Js Parse double failed. rate is not double.");
3299 return;
3300 }
3301 if (!ParseJsonDouble(argsPtrItem->GetValue("lightUpDegree"), lightUpDegree)) {
3302 LOGE("Js Parse double failed. lightUpDegree is not double.");
3303 return;
3304 }
3305 SetDynamicLightUp(rate, lightUpDegree);
3306 }
3307
JsWindowBlur(const JSCallbackInfo & info)3308 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
3309 {
3310 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3311 if (!CheckJSCallbackInfo("JsWindowBlur", info, checkList)) {
3312 return;
3313 }
3314
3315 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3316 if (!argsPtrItem || argsPtrItem->IsNull()) {
3317 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
3318 return;
3319 }
3320 double progress = 0.0;
3321 ParseJsonDouble(argsPtrItem->GetValue("percent"), progress);
3322 auto style = argsPtrItem->GetInt("style", static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
3323
3324 progress = std::clamp(progress, 0.0, 1.0);
3325 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
3326 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
3327
3328 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
3329 info.SetReturnValue(info.This());
3330 }
3331
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)3332 bool JSViewAbstract::ParseJsDimensionNG(
3333 const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
3334 {
3335 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
3336 return false;
3337 }
3338
3339 if (jsValue->IsNumber()) {
3340 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
3341 return true;
3342 }
3343 if (jsValue->IsString()) {
3344 auto value = jsValue->ToString();
3345 if (value.back() == '%' && !isSupportPercent) {
3346 return false;
3347 }
3348 return StringUtils::StringToCalcDimensionNG(jsValue->ToString(), result, false, defaultUnit);
3349 }
3350 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3351 JSRef<JSVal> resId = jsObj->GetProperty("id");
3352 if (!resId->IsNumber()) {
3353 return false;
3354 }
3355 auto themeConstants = GetThemeConstants(jsObj);
3356 if (!themeConstants) {
3357 return false;
3358 }
3359 auto resIdNum = resId->ToNumber<int32_t>();
3360 if (resIdNum == -1) {
3361 if (!IsGetResourceByName(jsObj)) {
3362 return false;
3363 }
3364 JSRef<JSVal> args = jsObj->GetProperty("params");
3365 if (!args->IsArray()) {
3366 return false;
3367 }
3368 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3369 auto param = params->GetValueAt(0);
3370 result = themeConstants->GetDimensionByName(param->ToString());
3371 return true;
3372 }
3373
3374 JSRef<JSVal> type = jsObj->GetProperty("type");
3375 if (!type->IsNull() && type->IsNumber() &&
3376 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
3377 auto value = themeConstants->GetString(resId->ToNumber<uint32_t>());
3378 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
3379 }
3380 if (!type->IsNull() && type->IsNumber() &&
3381 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTEGER)) {
3382 auto value = std::to_string(themeConstants->GetInt(resId->ToNumber<uint32_t>()));
3383 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
3384 return true;
3385 }
3386
3387 if (!type->IsNull() && type->IsNumber() &&
3388 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::FLOAT)) {
3389 result = themeConstants->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
3390 return true;
3391 }
3392
3393 return false;
3394 }
3395
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)3396 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
3397 {
3398 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
3399 return false;
3400 }
3401
3402 if (jsValue->IsNumber()) {
3403 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
3404 return true;
3405 }
3406 if (jsValue->IsString()) {
3407 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
3408 return true;
3409 }
3410 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3411 JSRef<JSVal> resId = jsObj->GetProperty("id");
3412 if (!resId->IsNumber()) {
3413 LOGD("resId is not number");
3414 return false;
3415 }
3416 auto themeConstants = GetThemeConstants(jsObj);
3417 if (!themeConstants) {
3418 LOGE("themeConstants is nullptr");
3419 return false;
3420 }
3421 auto resIdNum = resId->ToNumber<int32_t>();
3422 if (resIdNum == -1) {
3423 if (!IsGetResourceByName(jsObj)) {
3424 return false;
3425 }
3426 JSRef<JSVal> args = jsObj->GetProperty("params");
3427 if (!args->IsArray()) {
3428 LOGE("params is not array.");
3429 return false;
3430 }
3431 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3432 auto param = params->GetValueAt(0);
3433 result = themeConstants->GetDimensionByName(param->ToString());
3434 return true;
3435 }
3436
3437 JSRef<JSVal> type = jsObj->GetProperty("type");
3438 if (!type->IsNull() && type->IsNumber() &&
3439 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
3440 auto value = themeConstants->GetString(resId->ToNumber<uint32_t>());
3441 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
3442 return true;
3443 }
3444 if (!type->IsNull() && type->IsNumber() &&
3445 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTEGER)) {
3446 auto value = std::to_string(themeConstants->GetInt(resId->ToNumber<uint32_t>()));
3447 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
3448 return true;
3449 }
3450 result = themeConstants->GetDimension(resId->ToNumber<uint32_t>());
3451 return true;
3452 }
3453
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)3454 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
3455 {
3456 // 'vp' -> the value varies with pixel density of device.
3457 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
3458 }
3459
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)3460 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
3461 {
3462 // 'vp' -> the value varies with pixel density of device.
3463 return ParseJsDimension(jsValue, result, DimensionUnit::VP);
3464 }
3465
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)3466 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
3467 {
3468 // the 'fp' unit is used for text scenes.
3469 return ParseJsDimension(jsValue, result, DimensionUnit::FP);
3470 }
3471
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)3472 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
3473 {
3474 return ParseJsDimension(jsValue, result, DimensionUnit::PX);
3475 }
3476
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)3477 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
3478 {
3479 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3480 if (jsObj->IsEmpty()) {
3481 LOGW("jsObj is nullptr");
3482 return false;
3483 }
3484 JSRef<JSVal> id = jsObj->GetProperty("id");
3485 JSRef<JSVal> type = jsObj->GetProperty("type");
3486 if (!id->IsNumber() || !type->IsNumber()) {
3487 LOGW("at least one of id and type is not number");
3488 return false;
3489 }
3490 auto themeConstants = GetThemeConstants(jsObj);
3491 auto resId = id->ToNumber<int32_t>();
3492 auto resType = type->ToNumber<uint32_t>();
3493 if (!themeConstants) {
3494 LOGW("themeConstants is nullptr");
3495 return false;
3496 }
3497 if (resId == -1) {
3498 if (!IsGetResourceByName(jsObj)) {
3499 return false;
3500 }
3501 JSRef<JSVal> args = jsObj->GetProperty("params");
3502 if (!args->IsArray()) {
3503 return false;
3504 }
3505 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3506 auto param = params->GetValueAt(0);
3507 if (resType == static_cast<uint32_t>(ResourceType::STRING)) {
3508 auto numberString = themeConstants->GetStringByName(param->ToString());
3509 return StringUtils::StringToDouble(numberString, result);
3510 }
3511 if (resType == static_cast<uint32_t>(ResourceType::INTEGER)) {
3512 result = themeConstants->GetIntByName(param->ToString());
3513 return true;
3514 }
3515 if (resType == static_cast<uint32_t>(ResourceType::FLOAT)) {
3516 result = themeConstants->GetDoubleByName(param->ToString());
3517 return true;
3518 }
3519 return false;
3520 }
3521 if (resType == static_cast<uint32_t>(ResourceType::STRING)) {
3522 auto numberString = themeConstants->GetString(resId);
3523 return StringUtils::StringToDouble(numberString, result);
3524 }
3525 if (resType == static_cast<uint32_t>(ResourceType::INTEGER)) {
3526 result = themeConstants->GetInt(resId);
3527 return true;
3528 }
3529 if (resType == static_cast<uint32_t>(ResourceType::FLOAT)) {
3530 result = themeConstants->GetDouble(resId);
3531 return true;
3532 }
3533 return false;
3534 }
3535
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)3536 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
3537 {
3538 if (jsValue->IsNumber()) {
3539 result = jsValue->ToNumber<double>();
3540 return true;
3541 }
3542 if (jsValue->IsString()) {
3543 return StringUtils::StringToDouble(jsValue->ToString(), result);
3544 }
3545 if (jsValue->IsObject()) {
3546 return ParseResourceToDouble(jsValue, result);
3547 }
3548 return false;
3549 }
3550
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)3551 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
3552 {
3553 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
3554 return false;
3555 }
3556 if (jsValue->IsNumber()) {
3557 result = jsValue->ToNumber<int32_t>();
3558 return true;
3559 }
3560 if (jsValue->IsString()) {
3561 result = StringUtils::StringToInt(jsValue->ToString());
3562 return true;
3563 }
3564 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3565 JSRef<JSVal> resId = jsObj->GetProperty("id");
3566 if (!resId->IsNumber()) {
3567 LOGW("resId is not number");
3568 return false;
3569 }
3570
3571 auto themeConstants = GetThemeConstants(jsObj);
3572 if (!themeConstants) {
3573 LOGW("themeConstants is nullptr");
3574 return false;
3575 }
3576 auto resIdNum = resId->ToNumber<int32_t>();
3577 if (resIdNum == -1) {
3578 if (!IsGetResourceByName(jsObj)) {
3579 return false;
3580 }
3581 JSRef<JSVal> args = jsObj->GetProperty("params");
3582 if (!args->IsArray()) {
3583 return false;
3584 }
3585 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3586 auto param = params->GetValueAt(0);
3587 result = themeConstants->GetIntByName(param->ToString());
3588 return true;
3589 }
3590 result = themeConstants->GetInt(resId->ToNumber<uint32_t>());
3591 return true;
3592 }
3593
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)3594 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
3595 {
3596 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3597 JSRef<JSVal> resId = jsObj->GetProperty("id");
3598 if (!resId->IsNumber()) {
3599 LOGW("resId is not number");
3600 return false;
3601 }
3602
3603 auto themeConstants = GetThemeConstants(jsObj);
3604 if (!themeConstants) {
3605 LOGW("themeConstants is nullptr");
3606 return false;
3607 }
3608 auto resIdNum = resId->ToNumber<int32_t>();
3609 if (resIdNum == -1) {
3610 if (!IsGetResourceByName(jsObj)) {
3611 return false;
3612 }
3613 JSRef<JSVal> args = jsObj->GetProperty("params");
3614 if (!args->IsArray()) {
3615 return false;
3616 }
3617 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3618 auto param = params->GetValueAt(0);
3619 result = themeConstants->GetColorByName(param->ToString());
3620 return true;
3621 }
3622 JSRef<JSVal> type = jsObj->GetProperty("type");
3623 if (!type->IsNull() && type->IsNumber() &&
3624 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
3625 auto value = themeConstants->GetString(resId->ToNumber<uint32_t>());
3626 return Color::ParseColorString(value, result);
3627 }
3628 if (!type->IsNull() && type->IsNumber() &&
3629 type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTEGER)) {
3630 auto value = themeConstants->GetInt(resId->ToNumber<uint32_t>());
3631 result = Color(ColorAlphaAdapt(value));
3632 return true;
3633 }
3634 result = themeConstants->GetColor(resId->ToNumber<uint32_t>());
3635 return true;
3636 }
3637
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)3638 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
3639 {
3640 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
3641 return false;
3642 }
3643 if (jsValue->IsNumber()) {
3644 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
3645 return true;
3646 }
3647 if (jsValue->IsString()) {
3648 return Color::ParseColorString(jsValue->ToString(), result);
3649 }
3650 return ParseJsColorFromResource(jsValue, result);
3651 }
3652
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)3653 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
3654 {
3655 if (!jsValue->IsString()) {
3656 return false;
3657 }
3658 if (jsValue->IsString()) {
3659 std::string colorStr = jsValue->ToString();
3660 // Remove all " ".
3661 colorStr.erase(std::remove(colorStr.begin(), colorStr.end(), ' '), colorStr.end());
3662 std::transform(colorStr.begin(), colorStr.end(), colorStr.begin(), ::tolower);
3663 if (colorStr.compare("invert") == 0) {
3664 strategy = ForegroundColorStrategy::INVERT;
3665 return true;
3666 }
3667 }
3668 return false;
3669 }
3670
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)3671 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
3672 {
3673 result.clear();
3674 if (!jsValue->IsString() && !jsValue->IsObject()) {
3675 LOGE("arg is not String or Object.");
3676 return false;
3677 }
3678 if (jsValue->IsString()) {
3679 result = ConvertStrToFontFamilies(jsValue->ToString());
3680 return true;
3681 }
3682 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3683 JSRef<JSVal> resId = jsObj->GetProperty("id");
3684 if (!resId->IsNumber()) {
3685 LOGW("resId is not number");
3686 return false;
3687 }
3688
3689 auto themeConstants = GetThemeConstants(jsObj);
3690 if (!themeConstants) {
3691 LOGW("themeConstants is nullptr");
3692 return false;
3693 }
3694 auto resIdNum = resId->ToNumber<int32_t>();
3695 if (resIdNum == -1) {
3696 if (!IsGetResourceByName(jsObj)) {
3697 return false;
3698 }
3699 JSRef<JSVal> args = jsObj->GetProperty("params");
3700 if (!args->IsArray()) {
3701 return false;
3702 }
3703 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3704 auto param = params->GetValueAt(0);
3705 result.emplace_back(themeConstants->GetStringByName(param->ToString()));
3706 return true;
3707 }
3708 result.emplace_back(themeConstants->GetString(resId->ToNumber<uint32_t>()));
3709 return true;
3710 }
3711
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)3712 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
3713 {
3714 if (!jsValue->IsString() && !jsValue->IsObject()) {
3715 LOGD("arg is not String or Object.");
3716 return false;
3717 }
3718
3719 if (jsValue->IsString()) {
3720 LOGD("jsValue->IsString()");
3721 result = jsValue->ToString();
3722 return true;
3723 }
3724
3725 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3726 JSRef<JSVal> type = jsObj->GetProperty("type");
3727 if (!type->IsNumber()) {
3728 LOGD("type is not number");
3729 return false;
3730 }
3731
3732 JSRef<JSVal> resId = jsObj->GetProperty("id");
3733 if (!resId->IsNumber()) {
3734 LOGD("resId is not number");
3735 return false;
3736 }
3737
3738 auto themeConstants = GetThemeConstants(jsObj);
3739 if (!themeConstants) {
3740 LOGW("themeConstants is nullptr");
3741 return false;
3742 }
3743
3744 JSRef<JSVal> args = jsObj->GetProperty("params");
3745 if (!args->IsArray()) {
3746 LOGW("args is not array");
3747 return false;
3748 }
3749
3750 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3751 auto resIdNum = resId->ToNumber<int32_t>();
3752 if (resIdNum == -1) {
3753 if (!IsGetResourceByName(jsObj)) {
3754 return false;
3755 }
3756 auto param = params->GetValueAt(0);
3757 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
3758 auto originStr = themeConstants->GetStringByName(param->ToString());
3759 ReplaceHolder(originStr, params, 0);
3760 result = originStr;
3761 } else if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::PLURAL)) {
3762 auto countJsVal = params->GetValueAt(1);
3763 int count = 0;
3764 if (!countJsVal->IsNumber()) {
3765 LOGW("pluralString, pluralnumber is not number");
3766 return false;
3767 }
3768 count = countJsVal->ToNumber<int>();
3769 auto pluralStr = themeConstants->GetPluralStringByName(param->ToString(), count);
3770 ReplaceHolder(pluralStr, params, 2);
3771 result = pluralStr;
3772 } else {
3773 return false;
3774 }
3775 return true;
3776 }
3777 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
3778 auto originStr = themeConstants->GetString(resId->ToNumber<uint32_t>());
3779 ReplaceHolder(originStr, params, 0);
3780 result = originStr;
3781 } else if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::PLURAL)) {
3782 auto countJsVal = params->GetValueAt(0);
3783 int count = 0;
3784 if (!countJsVal->IsNumber()) {
3785 LOGW("pluralString, pluralnumber is not number");
3786 return false;
3787 }
3788 count = countJsVal->ToNumber<int>();
3789 auto pluralStr = themeConstants->GetPluralString(resId->ToNumber<uint32_t>(), count);
3790 ReplaceHolder(pluralStr, params, 1);
3791 result = pluralStr;
3792 } else if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::FLOAT)) {
3793 result = std::to_string(themeConstants->GetDouble(resId->ToNumber<uint32_t>()));
3794 } else if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTEGER)) {
3795 result = std::to_string(themeConstants->GetInt(resId->ToNumber<uint32_t>()));
3796 } else {
3797 return false;
3798 }
3799 return true;
3800 }
3801
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)3802 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
3803 {
3804 if (!jsValue->IsObject() && !jsValue->IsString()) {
3805 LOGE("arg is not Object and String.");
3806 return false;
3807 }
3808 if (jsValue->IsString()) {
3809 result = jsValue->ToString();
3810 return true;
3811 }
3812 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3813 JSRef<JSVal> type = jsObj->GetProperty("type");
3814 JSRef<JSVal> resId = jsObj->GetProperty("id");
3815 if (!resId->IsNull() && !type->IsNull() && type->IsNumber() && resId->IsNumber()) {
3816 auto themeConstants = GetThemeConstants(jsObj);
3817 if (!themeConstants) {
3818 LOGW("themeConstants is nullptr");
3819 return false;
3820 }
3821 if (type->ToNumber<int32_t>() == static_cast<int32_t>(ResourceType::RAWFILE)) {
3822 JSRef<JSVal> args = jsObj->GetProperty("params");
3823 if (!args->IsArray()) {
3824 LOGW("args is not Array");
3825 return false;
3826 }
3827 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3828 auto fileName = params->GetValueAt(0);
3829 if (!fileName->IsString()) {
3830 LOGW("fileName is not String");
3831 return false;
3832 }
3833 result = themeConstants->GetRawfile(fileName->ToString());
3834 return true;
3835 }
3836 auto resIdNum = resId->ToNumber<int32_t>();
3837 if (resIdNum == -1) {
3838 if (!IsGetResourceByName(jsObj)) {
3839 return false;
3840 }
3841 JSRef<JSVal> args = jsObj->GetProperty("params");
3842 if (!args->IsArray()) {
3843 return false;
3844 }
3845 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3846 auto param = params->GetValueAt(0);
3847 if (type->ToNumber<int32_t>() == static_cast<int32_t>(ResourceType::MEDIA)) {
3848 result = themeConstants->GetMediaPathByName(param->ToString());
3849 return true;
3850 }
3851 LOGE("JSImage::Create ParseJsMedia type is wrong");
3852 return false;
3853 }
3854 if (type->ToNumber<int32_t>() == static_cast<int32_t>(ResourceType::MEDIA)) {
3855 result = themeConstants->GetMediaPath(resId->ToNumber<uint32_t>());
3856 return true;
3857 }
3858 LOGE("JSImage::Create ParseJsMedia type is wrong");
3859 return false;
3860 }
3861 LOGD("input value is not string or number, using PixelMap");
3862 return false;
3863 }
3864
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)3865 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
3866 {
3867 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
3868 LOGE("arg is not bool or Object.");
3869 return false;
3870 }
3871
3872 if (jsValue->IsBoolean()) {
3873 LOGD("jsValue->IsBoolean()");
3874 result = jsValue->ToBoolean();
3875 return true;
3876 }
3877
3878 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3879 JSRef<JSVal> type = jsObj->GetProperty("type");
3880 if (!type->IsNumber()) {
3881 LOGW("type is not number");
3882 return false;
3883 }
3884
3885 JSRef<JSVal> resId = jsObj->GetProperty("id");
3886 if (!resId->IsNumber()) {
3887 LOGW("resId is not number");
3888 return false;
3889 }
3890
3891 auto themeConstants = GetThemeConstants(jsObj);
3892 if (!themeConstants) {
3893 LOGW("themeConstants is nullptr");
3894 return false;
3895 }
3896
3897 auto resIdNum = resId->ToNumber<int32_t>();
3898 if (resIdNum == -1) {
3899 if (!IsGetResourceByName(jsObj)) {
3900 return false;
3901 }
3902 JSRef<JSVal> args = jsObj->GetProperty("params");
3903 if (!args->IsArray()) {
3904 LOGE("params is not array.");
3905 return false;
3906 }
3907 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3908 auto param = params->GetValueAt(0);
3909 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::BOOLEAN)) {
3910 result = themeConstants->GetBooleanByName(param->ToString());
3911 return true;
3912 }
3913 return false;
3914 }
3915
3916 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::BOOLEAN)) {
3917 result = themeConstants->GetBoolean(resId->ToNumber<uint32_t>());
3918 return true;
3919 }
3920 return false;
3921 }
3922
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)3923 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
3924 {
3925 return ParseJsInteger<uint32_t>(jsValue, result);
3926 }
3927
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)3928 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
3929 {
3930 return ParseJsInteger<int32_t>(jsValue, result);
3931 }
3932
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)3933 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
3934 {
3935 if (!jsValue->IsArray() && !jsValue->IsObject()) {
3936 LOGE("arg is not array or Object.");
3937 return false;
3938 }
3939
3940 if (jsValue->IsArray()) {
3941 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
3942 for (size_t i = 0; i < array->Length(); i++) {
3943 JSRef<JSVal> value = array->GetValueAt(i);
3944 if (value->IsNumber()) {
3945 result.emplace_back(value->ToNumber<uint32_t>());
3946 } else if (value->IsObject()) {
3947 uint32_t singleResInt;
3948 if (ParseJsInteger(value, singleResInt)) {
3949 result.emplace_back(singleResInt);
3950 } else {
3951 return false;
3952 }
3953 } else {
3954 return false;
3955 }
3956 }
3957 return true;
3958 }
3959
3960 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3961 JSRef<JSVal> type = jsObj->GetProperty("type");
3962 if (!type->IsNumber()) {
3963 LOGW("type is not number");
3964 return false;
3965 }
3966
3967 JSRef<JSVal> resId = jsObj->GetProperty("id");
3968 if (!resId->IsNumber()) {
3969 LOGW("resId is not number");
3970 return false;
3971 }
3972
3973 auto themeConstants = GetThemeConstants(jsObj);
3974 if (!themeConstants) {
3975 LOGW("themeConstants is nullptr");
3976 return false;
3977 }
3978
3979 auto resIdNum = resId->ToNumber<int32_t>();
3980 if (resIdNum == -1) {
3981 if (!IsGetResourceByName(jsObj)) {
3982 return false;
3983 }
3984 JSRef<JSVal> args = jsObj->GetProperty("params");
3985 if (!args->IsArray()) {
3986 return false;
3987 }
3988 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3989 auto param = params->GetValueAt(0);
3990 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTARRAY)) {
3991 result = themeConstants->GetIntArrayByName(param->ToString());
3992 return true;
3993 }
3994 return false;
3995 }
3996
3997 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTARRAY)) {
3998 result = themeConstants->GetIntArray(resId->ToNumber<uint32_t>());
3999 return true;
4000 }
4001 return false;
4002 }
4003
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)4004 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
4005 {
4006 if (!jsValue->IsArray() && !jsValue->IsObject()) {
4007 LOGE("arg is not array or Object.");
4008 return false;
4009 }
4010
4011 if (jsValue->IsArray()) {
4012 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
4013 for (size_t i = 0; i < array->Length(); i++) {
4014 JSRef<JSVal> value = array->GetValueAt(i);
4015 if (value->IsString()) {
4016 result.emplace_back(value->ToString());
4017 } else if (value->IsObject()) {
4018 std::string singleResStr;
4019 if (ParseJsString(value, singleResStr)) {
4020 result.emplace_back(singleResStr);
4021 } else {
4022 return false;
4023 }
4024 } else {
4025 return false;
4026 }
4027 }
4028 return true;
4029 }
4030
4031 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4032 JSRef<JSVal> type = jsObj->GetProperty("type");
4033 if (!type->IsNumber()) {
4034 LOGW("type is not number");
4035 return false;
4036 }
4037
4038 JSRef<JSVal> resId = jsObj->GetProperty("id");
4039 if (!resId->IsNumber()) {
4040 LOGW("resId is not number");
4041 return false;
4042 }
4043
4044 auto themeConstants = GetThemeConstants(jsObj);
4045 if (!themeConstants) {
4046 LOGW("themeConstants is nullptr");
4047 return false;
4048 }
4049
4050 auto resIdNum = resId->ToNumber<int32_t>();
4051 if (resIdNum == -1) {
4052 if (!IsGetResourceByName(jsObj)) {
4053 return false;
4054 }
4055 JSRef<JSVal> args = jsObj->GetProperty("params");
4056 if (!args->IsArray()) {
4057 return false;
4058 }
4059 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4060 auto param = params->GetValueAt(0);
4061 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRARRAY)) {
4062 result = themeConstants->GetStringArrayByName(param->ToString());
4063 return true;
4064 }
4065 return false;
4066 }
4067
4068 if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRARRAY)) {
4069 result = themeConstants->GetStringArray(resId->ToNumber<uint32_t>());
4070 return true;
4071 }
4072 return false;
4073 }
4074
IsGetResourceByName(const JSRef<JSObject> & jsObj)4075 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
4076 {
4077 JSRef<JSVal> args = jsObj->GetProperty("params");
4078 if (!args->IsArray()) {
4079 LOGW("args is not array");
4080 return false;
4081 }
4082 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
4083 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
4084 if (!bundleName->IsString() || !moduleName->IsString()) {
4085 LOGW("bundleName or moduleName is not string");
4086 return false;
4087 }
4088 if (!bundleName->ToString().empty() || !moduleName->ToString().empty()) {
4089 LOGW("bundleName or moduleName is not empty");
4090 return false;
4091 }
4092 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4093 if (params->IsEmpty()) {
4094 LOGW("params is empty");
4095 return false;
4096 }
4097 return true;
4098 }
4099
ParseSize(const JSCallbackInfo & info)4100 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
4101 {
4102 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4103 if (!CheckJSCallbackInfo("ParseSize", info, checkList)) {
4104 return std::pair<CalcDimension, CalcDimension>();
4105 }
4106 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4107 if (!argsPtrItem || argsPtrItem->IsNull()) {
4108 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
4109 info.SetReturnValue(info.This());
4110 return std::pair<CalcDimension, CalcDimension>();
4111 }
4112 CalcDimension width;
4113 CalcDimension height;
4114 if (!ParseJsonDimensionVp(argsPtrItem->GetValue("width"), width) ||
4115 !ParseJsonDimensionVp(argsPtrItem->GetValue("height"), height)) {
4116 return std::pair<CalcDimension, CalcDimension>();
4117 }
4118 LOGD("JsSize width = %lf unit = %d, height = %lf unit = %d", width.Value(), width.Unit(), height.Value(),
4119 height.Unit());
4120 info.SetReturnValue(info.This());
4121 return std::pair<CalcDimension, CalcDimension>(width, height);
4122 }
4123
JsUseAlign(const JSCallbackInfo & info)4124 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
4125 {
4126 if (info.Length() < 2) {
4127 LOGE("The arg is wrong, it is supposed to have atleast 2 arguments");
4128 return;
4129 }
4130
4131 if (!info[0]->IsObject() && !info[1]->IsObject()) {
4132 LOGE("arg is not IsObject.");
4133 return;
4134 }
4135
4136 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
4137 if (declaration == nullptr) {
4138 LOGE("declaration is nullptr");
4139 return;
4140 }
4141
4142 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
4143 JSRef<JSVal> side = obj->GetProperty("side");
4144 JSRef<JSVal> offset = obj->GetProperty("offset");
4145
4146 if (!side->IsNumber()) {
4147 LOGE("side is not Number [%s]", side->ToString().c_str());
4148 return;
4149 }
4150
4151 auto sideValue = side->ToNumber<int32_t>();
4152
4153 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
4154 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
4155 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
4156 LOGE("side should be Edge.Start Edge.Middle or Edge.End with HorizontalAlignDeclaration");
4157 return;
4158 }
4159 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
4160 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
4161 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
4162 LOGE("side should be Edge.Top Edge.Center Edge.Bottom or Edge.Baseline with VerticalAlignDeclaration");
4163 return;
4164 }
4165 }
4166
4167 std::optional<CalcDimension> optOffset;
4168 CalcDimension offsetDimension;
4169 if (ParseJsDimensionVp(offset, offsetDimension)) {
4170 optOffset = offsetDimension;
4171 }
4172 ViewAbstractModel::GetInstance()->SetUseAlign(
4173 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
4174 }
4175
JsGridSpan(const JSCallbackInfo & info)4176 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
4177 {
4178 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
4179 if (!CheckJSCallbackInfo("JsGridSpan", info, checkList)) {
4180 return;
4181 }
4182 auto span = info[0]->ToNumber<int32_t>();
4183 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
4184 }
4185
JsGridOffset(const JSCallbackInfo & info)4186 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
4187 {
4188 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
4189 if (!CheckJSCallbackInfo("JsGridOffset", info, checkList)) {
4190 return;
4191 }
4192 auto offset = info[0]->ToNumber<int32_t>();
4193 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
4194 }
4195
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)4196 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
4197 {
4198 // {lg: 4}
4199 if (val->IsNumber()) {
4200 span = val->ToNumber<uint32_t>();
4201 return true;
4202 }
4203
4204 if (!val->IsObject()) {
4205 LOGE("The argument is not object or number.");
4206 return false;
4207 }
4208
4209 // {lg: {span: 1, offset: 2}}
4210 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
4211 span = obj->GetProperty("span")->ToNumber<uint32_t>();
4212 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
4213 return true;
4214 }
4215
JsUseSizeType(const JSCallbackInfo & info)4216 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
4217 {
4218 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4219 if (!CheckJSCallbackInfo("JsUseSizeType", info, checkList)) {
4220 return;
4221 }
4222 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
4223 for (auto values : SCREEN_SIZE_VALUES) {
4224 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
4225 if (val->IsNull() || val->IsEmpty()) {
4226 continue;
4227 }
4228 uint32_t span = 0;
4229 int32_t offset = 0;
4230 if (ParseSpanAndOffset(val, span, offset)) {
4231 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
4232 }
4233 }
4234 }
4235
JsZIndex(const JSCallbackInfo & info)4236 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
4237 {
4238 if (info.Length() < 1) {
4239 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
4240 return;
4241 }
4242
4243 int zIndex = 0;
4244 if (info[0]->IsNumber()) {
4245 zIndex = info[0]->ToNumber<int>();
4246 }
4247
4248 ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
4249 }
4250
Pop()4251 void JSViewAbstract::Pop()
4252 {
4253 ViewStackModel::GetInstance()->Pop();
4254 }
4255
JsSetDraggable(bool draggable)4256 void JSViewAbstract::JsSetDraggable(bool draggable)
4257 {
4258 ViewAbstractModel::GetInstance()->SetDraggable(draggable);
4259 }
4260
JsOnDragStart(const JSCallbackInfo & info)4261 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
4262 {
4263 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4264 if (!CheckJSCallbackInfo("JsOnDragStart", info, checkList)) {
4265 return;
4266 }
4267
4268 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4269
4270 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc)](
4271 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
4272 NG::DragDropBaseInfo dragDropInfo;
4273 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
4274
4275 auto ret = func->Execute(info, extraParams);
4276 if (!ret->IsObject()) {
4277 LOGE("NG: builder param is not an object.");
4278 return dragDropInfo;
4279 }
4280
4281 auto node = ParseDragNode(ret);
4282 if (node) {
4283 LOGI("use custom builder param.");
4284 dragDropInfo.node = node;
4285 return dragDropInfo;
4286 }
4287
4288 auto builderObj = JSRef<JSObject>::Cast(ret);
4289 #if defined(PIXEL_MAP_SUPPORTED)
4290 auto pixmap = builderObj->GetProperty("pixelMap");
4291 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
4292 #endif
4293 auto extraInfo = builderObj->GetProperty("extraInfo");
4294 ParseJsString(extraInfo, dragDropInfo.extraInfo);
4295 node = ParseDragNode(builderObj->GetProperty("builder"));
4296 dragDropInfo.node = node;
4297 return dragDropInfo;
4298 };
4299 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
4300 }
4301
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)4302 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
4303 {
4304 auto node = ParseDragNode(info);
4305 if (!node) {
4306 return false;
4307 }
4308 dragInfo.node = node;
4309 return true;
4310 }
4311
ParseDragNode(const JSRef<JSVal> & info)4312 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
4313 {
4314 auto builderFunc = ParseDragStartBuilderFunc(info);
4315 if (!builderFunc) {
4316 return nullptr;
4317 }
4318 // use another VSP instance while executing the builder function
4319 ViewStackModel::GetInstance()->NewScope();
4320 {
4321 ACE_SCORING_EVENT("onDragStart.builder");
4322 builderFunc->Execute();
4323 }
4324
4325 return ViewStackModel::GetInstance()->Finish();
4326 }
4327
JsOnDragEnter(const JSCallbackInfo & info)4328 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
4329 {
4330 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4331 if (!CheckJSCallbackInfo("JsOnDragEnter", info, checkList)) {
4332 return;
4333 }
4334 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4335
4336 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
4337 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
4338 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4339 ACE_SCORING_EVENT("onDragEnter");
4340 func->Execute(info, extraParams);
4341 };
4342
4343 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
4344 }
4345
JsOnDragEnd(const JSCallbackInfo & info)4346 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
4347 {
4348 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4349 if (!CheckJSCallbackInfo("JsOnDragEnd", info, checkList)) {
4350 return;
4351 }
4352 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4353
4354 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc)](
4355 const RefPtr<OHOS::Ace::DragEvent>& info) {
4356 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4357 ACE_SCORING_EVENT("onDragEnd");
4358 func->Execute(info);
4359 };
4360
4361 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
4362 }
4363
JsOnDragMove(const JSCallbackInfo & info)4364 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
4365 {
4366 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4367 if (!CheckJSCallbackInfo("JsOnDragMove", info, checkList)) {
4368 return;
4369 }
4370 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4371
4372 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
4373 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
4374 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4375 ACE_SCORING_EVENT("onDragMove");
4376 func->Execute(info, extraParams);
4377 };
4378
4379 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
4380 }
4381
JsOnDragLeave(const JSCallbackInfo & info)4382 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
4383 {
4384 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4385 if (!CheckJSCallbackInfo("JsOnDragLeave", info, checkList)) {
4386 return;
4387 }
4388 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4389
4390 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
4391 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
4392 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4393 ACE_SCORING_EVENT("onDragLeave");
4394 func->Execute(info, extraParams);
4395 };
4396
4397 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
4398 }
4399
JsOnDrop(const JSCallbackInfo & info)4400 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
4401 {
4402 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4403 if (!CheckJSCallbackInfo("JsOnDrop", info, checkList)) {
4404 return;
4405 }
4406 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4407
4408 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
4409 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
4410 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4411 ACE_SCORING_EVENT("onDrop");
4412 func->Execute(info, extraParams);
4413 };
4414
4415 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
4416 }
4417
JsOnAreaChange(const JSCallbackInfo & info)4418 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
4419 {
4420 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
4421 LOGD("JsOnAreaChange callback is undefined");
4422 ViewAbstractModel::GetInstance()->DisableOnAreaChange();
4423 return;
4424 }
4425 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4426 if (!CheckJSCallbackInfo("JsOnAreaChange", info, checkList)) {
4427 return;
4428 }
4429 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(info[0]));
4430
4431 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction)](
4432 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
4433 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4434 ACE_SCORING_EVENT("onAreaChange");
4435 func->Execute(oldRect, oldOrigin, rect, origin);
4436 };
4437 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
4438 }
4439
4440 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)4441 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
4442 {
4443 if (info.Length() < 2) {
4444 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
4445 return;
4446 }
4447
4448 if (!info[0]->IsBoolean() && !info[0]->IsObject()) {
4449 LOGE("The first param type is not bool or object, invalid.");
4450 return;
4451 }
4452
4453 if (!info[1]->IsObject()) {
4454 LOGE("The second param type is not object, invalid.");
4455 return;
4456 }
4457
4458 auto popupParam = AceType::MakeRefPtr<PopupParam>();
4459 // Set IsShow to popupParam
4460 if (info[0]->IsBoolean()) {
4461 popupParam->SetIsShow(info[0]->ToBoolean());
4462 } else {
4463 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
4464 auto callback = ParseDoubleBindCallback(info, showObj);
4465 popupParam->SetOnStateChange(std::move(callback));
4466 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
4467 }
4468
4469 // Set popup to popupParam
4470 auto popupObj = JSRef<JSObject>::Cast(info[1]);
4471
4472 if (popupObj->GetProperty("message")->IsString()) {
4473 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
4474 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
4475 } else if (!popupObj->GetProperty("builder").IsEmpty()) {
4476 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
4477 auto builderValue = popupObj->GetProperty("builder");
4478 if (!builderValue->IsObject()) {
4479 LOGE("builder param is not an object.");
4480 return;
4481 }
4482
4483 JSRef<JSObject> builderObj;
4484 builderObj = JSRef<JSObject>::Cast(builderValue);
4485 auto builder = builderObj->GetProperty("builder");
4486 if (!builder->IsFunction()) {
4487 LOGE("builder param is not a function.");
4488 return;
4489 }
4490 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
4491 CHECK_NULL_VOID(builderFunc);
4492 ViewStackModel::GetInstance()->NewScope();
4493 builderFunc->Execute();
4494 auto customNode = ViewStackModel::GetInstance()->Finish();
4495 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
4496 } else {
4497 LOGE("BindPop info is invalid");
4498 return;
4499 }
4500 }
4501 #endif
4502
JsLinearGradient(const JSCallbackInfo & info)4503 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
4504 {
4505 if (info.Length() < 1) {
4506 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
4507 return;
4508 }
4509 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4510 if (!CheckJSCallbackInfo("LinearGradient", info, checkList)) {
4511 NG::Gradient newGradient;
4512 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4513 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
4514 return;
4515 }
4516 if (!info[0]->IsObject()) {
4517 LOGE("arg is not a object.");
4518 return;
4519 }
4520 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4521 if (!argsPtrItem || argsPtrItem->IsNull()) {
4522 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
4523 info.ReturnSelf();
4524 return;
4525 }
4526 NG::Gradient newGradient;
4527 NewJsLinearGradient(info, newGradient);
4528 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
4529 }
4530
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)4531 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
4532 {
4533 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4534 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4535 // angle
4536 std::optional<float> degree;
4537 GetAngle("angle", argsPtrItem, degree);
4538 if (degree) {
4539 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
4540 degree.reset();
4541 }
4542 // direction
4543 auto direction =
4544 static_cast<GradientDirection>(argsPtrItem->GetInt("direction", static_cast<int32_t>(GradientDirection::NONE)));
4545 switch (direction) {
4546 case GradientDirection::LEFT:
4547 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4548 break;
4549 case GradientDirection::RIGHT:
4550 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4551 break;
4552 case GradientDirection::TOP:
4553 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4554 break;
4555 case GradientDirection::BOTTOM:
4556 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4557 break;
4558 case GradientDirection::LEFT_TOP:
4559 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4560 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4561 break;
4562 case GradientDirection::LEFT_BOTTOM:
4563 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4564 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4565 break;
4566 case GradientDirection::RIGHT_TOP:
4567 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4568 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4569 break;
4570 case GradientDirection::RIGHT_BOTTOM:
4571 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4572 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4573 break;
4574 case GradientDirection::NONE:
4575 case GradientDirection::START_TO_END:
4576 case GradientDirection::END_TO_START:
4577 default:
4578 break;
4579 }
4580 auto repeating = argsPtrItem->GetBool("repeating", false);
4581 newGradient.SetRepeat(repeating);
4582 NewGetGradientColorStops(newGradient, argsPtrItem->GetValue("colors"));
4583 }
4584
JsRadialGradient(const JSCallbackInfo & info)4585 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
4586 {
4587 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4588 if (!CheckJSCallbackInfo("JsRadialGradient", info, checkList)) {
4589 NG::Gradient newGradient;
4590 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
4591 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
4592 return;
4593 }
4594
4595 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4596 if (!argsPtrItem || argsPtrItem->IsNull()) {
4597 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
4598 info.ReturnSelf();
4599 return;
4600 }
4601 NG::Gradient newGradient;
4602 NewJsRadialGradient(info, newGradient);
4603 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
4604 }
4605
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)4606 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
4607 {
4608 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4609 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
4610 // center
4611 auto center = argsPtrItem->GetValue("center");
4612 if (center && !center->IsNull() && center->IsArray() && center->GetArraySize() == 2) {
4613 CalcDimension value;
4614 if (ParseJsonDimensionVp(center->GetArrayItem(0), value)) {
4615 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
4616 if (value.Unit() == DimensionUnit::PERCENT) {
4617 // [0,1] -> [0, 100]
4618 newGradient.GetRadialGradient()->radialCenterX =
4619 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
4620 }
4621 }
4622 if (ParseJsonDimensionVp(center->GetArrayItem(1), value)) {
4623 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
4624 if (value.Unit() == DimensionUnit::PERCENT) {
4625 // [0,1] -> [0, 100]
4626 newGradient.GetRadialGradient()->radialCenterY =
4627 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
4628 }
4629 }
4630 }
4631 // radius
4632 CalcDimension radius;
4633 if (ParseJsonDimensionVp(argsPtrItem->GetValue("radius"), radius)) {
4634 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
4635 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
4636 }
4637 // repeating
4638 auto repeating = argsPtrItem->GetBool("repeating", false);
4639 newGradient.SetRepeat(repeating);
4640 // color stops
4641 NewGetGradientColorStops(newGradient, argsPtrItem->GetValue("colors"));
4642 }
4643
JsSweepGradient(const JSCallbackInfo & info)4644 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
4645 {
4646 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4647 if (!CheckJSCallbackInfo("JsSweepGradient", info, checkList)) {
4648 NG::Gradient newGradient;
4649 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
4650 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
4651 return;
4652 }
4653
4654 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4655 if (!argsPtrItem || argsPtrItem->IsNull()) {
4656 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
4657 info.ReturnSelf();
4658 return;
4659 }
4660
4661 NG::Gradient newGradient;
4662 NewJsSweepGradient(info, newGradient);
4663 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
4664 }
4665
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)4666 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
4667 {
4668 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4669 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
4670 // center
4671 auto center = argsPtrItem->GetValue("center");
4672 if (center && !center->IsNull() && center->IsArray() && center->GetArraySize() == 2) {
4673 CalcDimension value;
4674 if (ParseJsonDimensionVp(center->GetArrayItem(0), value)) {
4675 newGradient.GetSweepGradient()->centerX = CalcDimension(value);
4676 if (value.Unit() == DimensionUnit::PERCENT) {
4677 // [0,1] -> [0, 100]
4678 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
4679 }
4680 }
4681 if (ParseJsonDimensionVp(center->GetArrayItem(1), value)) {
4682 newGradient.GetSweepGradient()->centerY = CalcDimension(value);
4683 if (value.Unit() == DimensionUnit::PERCENT) {
4684 // [0,1] -> [0, 100]
4685 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
4686 }
4687 }
4688 }
4689 std::optional<float> degree;
4690 // start
4691 GetAngle("start", argsPtrItem, degree);
4692 if (degree) {
4693 CheckAngle(degree);
4694 newGradient.GetSweepGradient()->startAngle = CalcDimension(degree.value(), DimensionUnit::PX);
4695 degree.reset();
4696 }
4697 // end
4698 GetAngle("end", argsPtrItem, degree);
4699 if (degree) {
4700 CheckAngle(degree);
4701 newGradient.GetSweepGradient()->endAngle = CalcDimension(degree.value(), DimensionUnit::PX);
4702 degree.reset();
4703 }
4704 // rotation
4705 GetAngle("rotation", argsPtrItem, degree);
4706 if (degree) {
4707 CheckAngle(degree);
4708 newGradient.GetSweepGradient()->rotation = CalcDimension(degree.value(), DimensionUnit::PX);
4709 degree.reset();
4710 }
4711 // repeating
4712 auto repeating = argsPtrItem->GetBool("repeating", false);
4713 newGradient.SetRepeat(repeating);
4714 // color stops
4715 NewGetGradientColorStops(newGradient, argsPtrItem->GetValue("colors"));
4716 }
4717
JsMotionPath(const JSCallbackInfo & info)4718 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
4719 {
4720 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4721 if (!CheckJSCallbackInfo("JsMotionPath", info, checkList)) {
4722 LOGW("motionPath is not object");
4723 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
4724 return;
4725 }
4726 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4727 MotionPathOption motionPathOption;
4728 if (ParseMotionPath(argsPtrItem, motionPathOption)) {
4729 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
4730 } else {
4731 LOGW("parse motionPath failed. %{public}s", info[0]->ToString().c_str());
4732 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
4733 }
4734 }
4735
JsShadow(const JSCallbackInfo & info)4736 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
4737 {
4738 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
4739 if (!CheckJSCallbackInfo("JsShadow", info, checkList)) {
4740 Shadow shadow;
4741 std::vector<Shadow> shadows { shadow };
4742 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
4743 return;
4744 }
4745
4746 int32_t shadowStyle = 0;
4747 if (ParseJsInteger<int32_t>(info[0], shadowStyle)) {
4748 auto style = static_cast<ShadowStyle>(shadowStyle);
4749 Shadow shadow = Shadow::CreateShadow(style);
4750 std::vector<Shadow> shadows = { shadow };
4751 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
4752 return;
4753 }
4754 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
4755 if (!argsPtrItem || argsPtrItem->IsNull()) {
4756 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
4757 info.ReturnSelf();
4758 return;
4759 }
4760 double radius = 0.0;
4761 ParseJsonDouble(argsPtrItem->GetValue("radius"), radius);
4762 if (LessNotEqual(radius, 0.0)) {
4763 radius = 0.0;
4764 }
4765 std::vector<Shadow> shadows(1);
4766 shadows.begin()->SetBlurRadius(radius);
4767 CalcDimension offsetX;
4768 if (ParseJsonDimensionVp(argsPtrItem->GetValue("offsetX"), offsetX)) {
4769 shadows.begin()->SetOffsetX(offsetX.Value());
4770 }
4771 CalcDimension offsetY;
4772 if (ParseJsonDimensionVp(argsPtrItem->GetValue("offsetY"), offsetY)) {
4773 shadows.begin()->SetOffsetY(offsetY.Value());
4774 }
4775 Color color;
4776 if (ParseJsonColor(argsPtrItem->GetValue("color"), color)) {
4777 shadows.begin()->SetColor(color);
4778 }
4779 auto type = argsPtrItem->GetInt("type", static_cast<int32_t>(ShadowType::COLOR));
4780 type = std::clamp(type, static_cast<int32_t>(ShadowType::COLOR), static_cast<int32_t>(ShadowType::BLUR));
4781 shadows.begin()->SetShadowType(static_cast<ShadowType>(type));
4782 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
4783 }
4784
JsGrayScale(const JSCallbackInfo & info)4785 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
4786 {
4787 if (info.Length() < 1) {
4788 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
4789 return;
4790 }
4791
4792 CalcDimension value;
4793 if (!ParseJsDimensionVp(info[0], value)) {
4794 value.SetValue(0.0);
4795 ViewAbstractModel::GetInstance()->SetGrayScale(value);
4796 return;
4797 }
4798
4799 if (LessNotEqual(value.Value(), 0.0)) {
4800 value.SetValue(0.0);
4801 }
4802
4803 if (GreatNotEqual(value.Value(), 1.0)) {
4804 value.SetValue(1.0);
4805 }
4806
4807 ViewAbstractModel::GetInstance()->SetGrayScale(value);
4808 }
4809
JsBrightness(const JSCallbackInfo & info)4810 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
4811 {
4812 if (info.Length() < 1) {
4813 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
4814 return;
4815 }
4816
4817 CalcDimension value;
4818 if (!ParseJsDimensionVp(info[0], value)) {
4819 value.SetValue(1.0);
4820 ViewAbstractModel::GetInstance()->SetBrightness(value);
4821 return;
4822 }
4823
4824 ViewAbstractModel::GetInstance()->SetBrightness(value);
4825 }
4826
JsContrast(const JSCallbackInfo & info)4827 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
4828 {
4829 if (info.Length() < 1) {
4830 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
4831 return;
4832 }
4833
4834 CalcDimension value;
4835 if (!ParseJsDimensionVp(info[0], value)) {
4836 value.SetValue(1.0);
4837 ViewAbstractModel::GetInstance()->SetContrast(value);
4838 return;
4839 }
4840
4841 if (LessNotEqual(value.Value(), 0.0)) {
4842 value.SetValue(0.0);
4843 }
4844
4845 ViewAbstractModel::GetInstance()->SetContrast(value);
4846 }
4847
JsSaturate(const JSCallbackInfo & info)4848 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
4849 {
4850 if (info.Length() < 1) {
4851 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
4852 return;
4853 }
4854 CalcDimension value;
4855 if (!ParseJsDimensionVp(info[0], value)) {
4856 value.SetValue(1.0);
4857 ViewAbstractModel::GetInstance()->SetSaturate(value);
4858 return;
4859 }
4860
4861 if (LessNotEqual(value.Value(), 0.0)) {
4862 value.SetValue(0.0);
4863 }
4864
4865 ViewAbstractModel::GetInstance()->SetSaturate(value);
4866 }
4867
JsSepia(const JSCallbackInfo & info)4868 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
4869 {
4870 if (info.Length() < 1) {
4871 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
4872 return;
4873 }
4874
4875 CalcDimension value;
4876 if (!ParseJsDimensionVp(info[0], value)) {
4877 value.SetValue(0.0);
4878 ViewAbstractModel::GetInstance()->SetSepia(value);
4879 return;
4880 }
4881
4882 if (LessNotEqual(value.Value(), 0.0)) {
4883 value.SetValue(0.0);
4884 }
4885
4886 ViewAbstractModel::GetInstance()->SetSepia(value);
4887 }
4888
JsInvert(const JSCallbackInfo & info)4889 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
4890 {
4891 if (info.Length() < 1) {
4892 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
4893 return;
4894 }
4895 CalcDimension value;
4896 if (!ParseJsDimensionVp(info[0], value)) {
4897 value.SetValue(0.0);
4898 ViewAbstractModel::GetInstance()->SetInvert(value);
4899 return;
4900 }
4901 if (LessNotEqual(value.Value(), 0.0)) {
4902 value.SetValue(0.0);
4903 }
4904
4905 ViewAbstractModel::GetInstance()->SetInvert(value);
4906 }
4907
JsHueRotate(const JSCallbackInfo & info)4908 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
4909 {
4910 std::optional<float> degree;
4911 if (info.Length() < 1) {
4912 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
4913 return;
4914 }
4915 if (info[0]->IsString()) {
4916 degree = static_cast<float>(StringUtils::StringToDegree(info[0]->ToString()));
4917 } else if (info[0]->IsNumber()) {
4918 degree = static_cast<float>(info[0]->ToNumber<int32_t>());
4919 } else {
4920 LOGE("Invalid value type");
4921 ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
4922 return;
4923 }
4924 float deg = 0.0f;
4925 if (degree) {
4926 deg = degree.value();
4927 degree.reset();
4928 }
4929 deg = std::fmod(deg, ROUND_UNIT);
4930 if (deg < 0.0f) {
4931 deg += ROUND_UNIT;
4932 }
4933 ViewAbstractModel::GetInstance()->SetHueRotate(deg);
4934 }
4935
JsClip(const JSCallbackInfo & info)4936 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
4937 {
4938 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
4939 CHECK_NULL_VOID(frameNode);
4940 auto renderContext = frameNode->GetRenderContext();
4941 if (info[0]->IsUndefined() && !renderContext->GetClipEdge().has_value()) {
4942 ViewAbstractModel::GetInstance()->SetClipEdge(false);
4943 return;
4944 }
4945 if (info[0]->IsObject()) {
4946 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
4947 if (clipShape == nullptr) {
4948 LOGE("clipShape is null");
4949 return;
4950 }
4951 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
4952 } else if (info[0]->IsBoolean()) {
4953 ViewAbstractModel::GetInstance()->SetClipEdge(info[0]->ToBoolean());
4954 }
4955 }
4956
JsMask(const JSCallbackInfo & info)4957 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
4958 {
4959 if (info.Length() <= 0) {
4960 return;
4961 }
4962
4963 if (!info[0]->IsObject()) {
4964 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
4965 progressMask->SetColor(Color::TRANSPARENT);
4966 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
4967 return;
4968 }
4969 auto paramObject = JSRef<JSObject>::Cast(info[0]);
4970 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
4971 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
4972 typeParam->ToString() == "ProgressMask") {
4973 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
4974 JSRef<JSVal> jValue = paramObject->GetProperty("value");
4975 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
4976 if (value < 0.0f) {
4977 value = 0.0f;
4978 }
4979 progressMask->SetValue(value);
4980 JSRef<JSVal> jTotal = paramObject->GetProperty("total");
4981 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
4982 if (total < 0.0f) {
4983 total = DEFAULT_PROGRESS_TOTAL;
4984 }
4985 progressMask->SetMaxValue(total);
4986 JSRef<JSVal> jColor = paramObject->GetProperty("color");
4987 Color colorVal;
4988 if (ParseJsColor(jColor, colorVal)) {
4989 progressMask->SetColor(colorVal);
4990 } else {
4991 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
4992 progressMask->SetColor(theme->GetMaskColor());
4993 }
4994 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
4995 } else {
4996 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
4997 if (maskShape == nullptr) {
4998 return;
4999 };
5000 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
5001 }
5002 }
5003
JsFocusable(const JSCallbackInfo & info)5004 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
5005 {
5006 if (!info[0]->IsBoolean()) {
5007 LOGE("The info is wrong, it is supposed to be an boolean");
5008 return;
5009 }
5010 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
5011 }
5012
JsOnFocusMove(const JSCallbackInfo & args)5013 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
5014 {
5015 if (args[0]->IsFunction()) {
5016 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
5017 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove)](int info) {
5018 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5019 ACE_SCORING_EVENT("onFocusMove");
5020 func->Execute(info);
5021 };
5022 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
5023 }
5024 }
5025
JsOnKeyEvent(const JSCallbackInfo & args)5026 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
5027 {
5028 if (args[0]->IsUndefined() && IsDisableEventVersion()) {
5029 LOGD("JsOnKeyEvent callback is undefined");
5030 ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
5031 return;
5032 }
5033 if (!args[0]->IsFunction()) {
5034 LOGE("OnKeyEvent args need a function.");
5035 return;
5036 }
5037 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(args[0]));
5038 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent)](KeyEventInfo& info) {
5039 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5040 ACE_SCORING_EVENT("onKey");
5041 func->Execute(info);
5042 };
5043 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
5044 }
5045
JsOnFocus(const JSCallbackInfo & args)5046 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
5047 {
5048 if (args[0]->IsUndefined() && IsDisableEventVersion()) {
5049 LOGD("JsOnFocus callback is undefined");
5050 ViewAbstractModel::GetInstance()->DisableOnFocus();
5051 return;
5052 }
5053 if (!args[0]->IsFunction()) {
5054 LOGE("OnFocus args need a function.");
5055 return;
5056 }
5057 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
5058 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus)]() {
5059 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5060 ACE_SCORING_EVENT("onFocus");
5061 func->Execute();
5062 };
5063
5064 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
5065 }
5066
JsOnBlur(const JSCallbackInfo & args)5067 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
5068 {
5069 if (args[0]->IsUndefined() && IsDisableEventVersion()) {
5070 LOGD("JsOnBlur callback is undefined");
5071 ViewAbstractModel::GetInstance()->DisableOnBlur();
5072 return;
5073 }
5074 if (!args[0]->IsFunction()) {
5075 LOGE("OnBlur args need a function.");
5076 return;
5077 }
5078 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
5079 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur)]() {
5080 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5081 ACE_SCORING_EVENT("onBlur");
5082 func->Execute();
5083 };
5084
5085 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
5086 }
5087
JsTabIndex(const JSCallbackInfo & info)5088 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
5089 {
5090 if (!info[0]->IsNumber()) {
5091 LOGE("Param is wrong, it is supposed to be a number");
5092 return;
5093 }
5094 ViewAbstractModel::GetInstance()->SetTabIndex(info[0]->ToNumber<int32_t>());
5095 }
5096
JsFocusOnTouch(const JSCallbackInfo & info)5097 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
5098 {
5099 if (!info[0]->IsBoolean()) {
5100 LOGE("Param is wrong, it is supposed to be a boolean");
5101 return;
5102 }
5103 auto isFocusOnTouch = info[0]->ToBoolean();
5104 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
5105 }
5106
JsDefaultFocus(const JSCallbackInfo & info)5107 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
5108 {
5109 if (!info[0]->IsBoolean()) {
5110 LOGE("Param is wrong, it is supposed to be a boolean");
5111 return;
5112 }
5113 auto isDefaultFocus = info[0]->ToBoolean();
5114 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
5115 }
5116
JsGroupDefaultFocus(const JSCallbackInfo & info)5117 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
5118 {
5119 if (!info[0]->IsBoolean()) {
5120 LOGE("Param is wrong, it is supposed to be a boolean");
5121 return;
5122 }
5123 auto isGroupDefaultFocus = info[0]->ToBoolean();
5124 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
5125 }
5126
JsKey(const std::string & key)5127 void JSViewAbstract::JsKey(const std::string& key)
5128 {
5129 ViewAbstractModel::GetInstance()->SetInspectorId(key);
5130 }
5131
JsId(const JSCallbackInfo & info)5132 void JSViewAbstract::JsId(const JSCallbackInfo& info)
5133 {
5134 if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
5135 LOGE("Param is wrong, it is supposed to be a string");
5136 return;
5137 }
5138 std::string id = info[0]->ToString();
5139 if (id.empty()) {
5140 LOGE("string is empty");
5141 return;
5142 }
5143 JsKey(id);
5144 }
5145
JsRestoreId(int32_t restoreId)5146 void JSViewAbstract::JsRestoreId(int32_t restoreId)
5147 {
5148 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
5149 }
5150
5151 #if defined(PREVIEW)
JsDebugLine(const JSCallbackInfo & info)5152 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
5153 {
5154 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
5155 if (!CheckJSCallbackInfo("JsDebugLine", info, checkList)) {
5156 return;
5157 }
5158
5159 ViewAbstractModel::GetInstance()->SetDebugLine(info[0]->ToString());
5160 }
5161 #endif
5162
JsOpacityPassThrough(const JSCallbackInfo & info)5163 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
5164 {
5165 if (info.Length() < 1) {
5166 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
5167 return;
5168 }
5169
5170 double opacity = 0.0;
5171 if (!ParseJsDouble(info[0], opacity)) {
5172 return;
5173 }
5174
5175 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
5176 LOGD("set opacity to %{public}f, over range, set to default opacity", opacity);
5177 opacity = 1.0;
5178 }
5179
5180 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
5181 }
5182
JsTransitionPassThrough(const JSCallbackInfo & info)5183 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
5184 {
5185 if (info.Length() > 1) {
5186 LOGE("Too many arguments");
5187 return;
5188 }
5189 if (info.Length() == 0) {
5190 ViewAbstractModel::GetInstance()->SetTransition(
5191 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
5192 return;
5193 }
5194 if (!info[0]->IsObject()) {
5195 LOGE("arg is not Object.");
5196 return;
5197 }
5198 auto obj = JSRef<JSObject>::Cast(info[0]);
5199 if (!obj->GetProperty("successor_")->IsUndefined()) {
5200 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
5201 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect);
5202 return;
5203 }
5204 auto transitionArgs = JsonUtil::ParseJsonString(info[0]->ToString());
5205 auto options = ParseTransition(transitionArgs);
5206 ViewAbstractModel::GetInstance()->SetTransition(options, true);
5207 }
5208
JsAccessibilityGroup(bool accessible)5209 void JSViewAbstract::JsAccessibilityGroup(bool accessible)
5210 {
5211 ViewAbstractModel::GetInstance()->SetAccessibilityGroup(accessible);
5212 }
5213
JsAccessibilityText(const std::string & text)5214 void JSViewAbstract::JsAccessibilityText(const std::string& text)
5215 {
5216 ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
5217 }
5218
JsAccessibilityDescription(const std::string & description)5219 void JSViewAbstract::JsAccessibilityDescription(const std::string& description)
5220 {
5221 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
5222 }
5223
JsAccessibilityImportance(const std::string & importance)5224 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
5225 {
5226 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
5227 }
5228
JsAccessibilityLevel(const std::string & level)5229 void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
5230 {
5231 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
5232 }
5233
JsBackground(const JSCallbackInfo & info)5234 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
5235 {
5236 // Check the parameters
5237 if (info.Length() <= 0 || !info[0]->IsObject()) {
5238 LOGE("Builder param is invalid, not an object.");
5239 return;
5240 }
5241 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
5242 auto builder = backgroundObj->GetProperty("builder");
5243 if (!builder->IsFunction()) {
5244 LOGE("builder param is not a function.");
5245 return;
5246 }
5247 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5248 CHECK_NULL_VOID(builderFunc);
5249 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
5250 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5251 ACE_SCORING_EVENT("BindBackground");
5252 func->Execute();
5253 };
5254 Alignment alignment = Alignment::CENTER;
5255 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
5256 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
5257 auto align = object->GetProperty("align");
5258 auto value = align->ToNumber<int32_t>();
5259 alignment = ParseAlignment(value);
5260 }
5261 ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
5262 }
5263
JsBindContextMenu(const JSCallbackInfo & info)5264 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
5265 {
5266 // Check the parameters
5267 if (info.Length() <= 0 || !info[0]->IsObject()) {
5268 LOGE("Builder param is invalid, not an object.");
5269 return;
5270 }
5271 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[0]);
5272 auto builder = menuObj->GetProperty("builder");
5273 if (!builder->IsFunction()) {
5274 LOGE("builder param is not a function.");
5275 return;
5276 }
5277 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5278 CHECK_NULL_VOID(builderFunc);
5279
5280 ResponseType responseType = ResponseType::LONG_PRESS;
5281 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
5282 auto response = info[1]->ToNumber<int32_t>();
5283 LOGI("Set the responseType is %{public}d.", response);
5284 responseType = static_cast<ResponseType>(response);
5285 }
5286 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
5287 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5288 ACE_SCORING_EVENT("BuildContextMenu");
5289 func->Execute();
5290 };
5291
5292 NG::MenuParam menuParam;
5293 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
5294 ParseBindContentOptionParam(info, info[2], menuParam);
5295 }
5296
5297 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam);
5298 }
5299
JsBindContentCover(const JSCallbackInfo & info)5300 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
5301 {
5302 // parse isShow
5303 bool isShow = false;
5304 DoubleBindCallback callback = nullptr;
5305 if (info[0]->IsBoolean()) {
5306 isShow = info[0]->ToBoolean();
5307 } else if (info[0]->IsObject()) {
5308 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
5309 callback = ParseDoubleBindCallback(info, callbackObj);
5310 auto isShowObj = callbackObj->GetProperty("value");
5311 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
5312 }
5313
5314 // parse builder
5315 if (!info[1]->IsObject()) {
5316 LOGE("builder is invalid.");
5317 return;
5318 }
5319 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5320 auto builder = obj->GetProperty("builder");
5321 if (!builder->IsFunction()) {
5322 LOGE("builder param is not a function.");
5323 return;
5324 }
5325 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5326 CHECK_NULL_VOID(builderFunc);
5327 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
5328 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5329 ACE_SCORING_EVENT("BindContentCover");
5330 func->Execute();
5331 };
5332
5333 // parse ModalTransition
5334 NG::ModalStyle modalStyle;
5335 modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
5336 std::function<void()> onShowCallback;
5337 std::function<void()> onDismissCallback;
5338 if (info.Length() == 3) {
5339 if (info[2]->IsObject()) {
5340 ParseOverlayCallback(info[2], onShowCallback, onDismissCallback);
5341 ParseModalStyle(info[2], modalStyle);
5342 } else if (info[2]->IsNumber()) {
5343 auto transitionNumber = info[2]->ToNumber<int32_t>();
5344 if (transitionNumber >= 0 && transitionNumber <= 2) {
5345 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
5346 }
5347 }
5348 }
5349 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
5350 std::move(onShowCallback), std::move(onDismissCallback));
5351 }
5352
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)5353 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
5354 {
5355 auto modalTransition = paramObj->GetProperty("modalTransition");
5356 auto backgroundColor = paramObj->GetProperty("backgroundColor");
5357 if (modalTransition->IsNumber()) {
5358 auto transitionNumber = modalTransition->ToNumber<int32_t>();
5359 if (transitionNumber >= 0 && transitionNumber <= 2) {
5360 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
5361 }
5362 }
5363 Color color;
5364 if (ParseJsColor(backgroundColor, color)) {
5365 modalStyle.backgroundColor = color;
5366 }
5367 }
5368
JsBindSheet(const JSCallbackInfo & info)5369 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
5370 {
5371 // parse isShow
5372 bool isShow = false;
5373 DoubleBindCallback callback = nullptr;
5374 if (info[0]->IsBoolean()) {
5375 isShow = info[0]->ToBoolean();
5376 } else if (info[0]->IsObject()) {
5377 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
5378 callback = ParseDoubleBindCallback(info, callbackObj);
5379 auto isShowObj = callbackObj->GetProperty("value");
5380 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
5381 }
5382
5383 // parse builder
5384 if (!info[1]->IsObject()) {
5385 LOGE("builder is invalid.");
5386 return;
5387 }
5388 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5389 auto builder = obj->GetProperty("builder");
5390 if (!builder->IsFunction()) {
5391 LOGE("builder param is not a function.");
5392 return;
5393 }
5394 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5395 CHECK_NULL_VOID(builderFunc);
5396 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
5397 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5398 ACE_SCORING_EVENT("BindSheet");
5399 func->Execute();
5400 };
5401
5402 // parse SheetStyle and callbacks
5403 NG::SheetStyle sheetStyle;
5404 sheetStyle.sheetMode = NG::SheetMode::LARGE;
5405 sheetStyle.showDragBar = true;
5406 std::function<void()> onShowCallback;
5407 std::function<void()> onDismissCallback;
5408 if (info.Length() == 3) {
5409 if (info[2]->IsObject()) {
5410 ParseOverlayCallback(info[2], onShowCallback, onDismissCallback);
5411 ParseSheetStyle(info[2], sheetStyle);
5412 }
5413 }
5414 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc), sheetStyle,
5415 std::move(onShowCallback), std::move(onDismissCallback));
5416 }
5417
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)5418 void JSViewAbstract::ParseSheetStyle(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
5419 {
5420 auto height = paramObj->GetProperty("height");
5421 auto showDragBar = paramObj->GetProperty("dragBar");
5422 auto backgroundColor = paramObj->GetProperty("backgroundColor");
5423 auto maskColor = paramObj->GetProperty("maskColor");
5424 if (showDragBar->IsNull() || showDragBar->IsUndefined()) {
5425 sheetStyle.showDragBar = true;
5426 } else {
5427 if (showDragBar->IsBoolean()) {
5428 sheetStyle.showDragBar = showDragBar->ToBoolean();
5429 } else {
5430 LOGW("show drag indicator failed.");
5431 }
5432 }
5433 Color color;
5434 if (ParseJsColor(backgroundColor, color)) {
5435 sheetStyle.backgroundColor = color;
5436 }
5437 // parse maskColor
5438 Color parseMaskColor;
5439 if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
5440 sheetStyle.maskColor = std::move(parseMaskColor);
5441 }
5442 CalcDimension sheetHeight;
5443 if (height->IsString()) {
5444 std::string heightStr = height->ToString();
5445 // Remove all " ".
5446 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
5447 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
5448 if (heightStr == SHEET_HEIGHT_MEDIUM) {
5449 sheetStyle.sheetMode = NG::SheetMode::MEDIUM;
5450 sheetStyle.height.reset();
5451 return;
5452 }
5453 if (heightStr == SHEET_HEIGHT_LARGE) {
5454 sheetStyle.sheetMode = NG::SheetMode::LARGE;
5455 sheetStyle.height.reset();
5456 return;
5457 }
5458 if (heightStr == SHEET_HEIGHT_AUTO) {
5459 sheetStyle.sheetMode = NG::SheetMode::AUTO;
5460 sheetStyle.height.reset();
5461 return;
5462 }
5463 if (heightStr.find("calc") != std::string::npos) {
5464 LOGI("calc value = %{public}s", heightStr.c_str());
5465 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
5466 } else {
5467 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
5468 }
5469 if (sheetHeight.Value() < 0) {
5470 sheetStyle.sheetMode = NG::SheetMode::LARGE;
5471 sheetStyle.height.reset();
5472 return;
5473 }
5474 }
5475 if (!ParseJsDimensionVp(height, sheetHeight)) {
5476 sheetStyle.sheetMode = NG::SheetMode::LARGE;
5477 sheetStyle.height.reset();
5478 LOGW("Parse to dimension VP failed, set default mode.");
5479 } else {
5480 sheetStyle.height = sheetHeight;
5481 sheetStyle.sheetMode.reset();
5482 }
5483 }
5484
ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear)5485 void JSViewAbstract::ParseOverlayCallback(
5486 const JSRef<JSObject>& paramObj, std::function<void()>& onAppear, std::function<void()>& onDisappear)
5487 {
5488 auto showCallback = paramObj->GetProperty("onAppear");
5489 auto dismissCallback = paramObj->GetProperty("onDisappear");
5490 if (showCallback->IsFunction()) {
5491 RefPtr<JsFunction> jsFunc =
5492 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
5493 onAppear = [func = std::move(jsFunc)]() { func->Execute(); };
5494 }
5495 if (dismissCallback->IsFunction()) {
5496 RefPtr<JsFunction> jsFunc =
5497 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
5498 onDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
5499 }
5500 }
5501
JSCreateAnimatableProperty(const JSCallbackInfo & info)5502 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
5503 {
5504 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
5505 LOGE("JSCreateAnimatableProperty: The arg is invalid.");
5506 return;
5507 }
5508
5509 JSRef<JSVal> callback = info[2]; /* 2:args index */
5510 if (!callback->IsFunction()) {
5511 LOGE("JSCreateAnimatableProperty: callback function type is invalid.");
5512 return;
5513 }
5514
5515 std::string propertyName = info[0]->ToString();
5516 if (info[1]->IsNumber()) {
5517 float numValue = info[1]->ToNumber<float>();
5518 std::function<void(float)> onCallbackEvent;
5519 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
5520 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId()](
5521 const float val) {
5522 ContainerScope scope(id);
5523 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5524 LOGD("onCallbackEvent(number) execute js func. val: %f", val);
5525 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
5526 func->ExecuteJS(1, &newJSVal);
5527 };
5528 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
5529 } else if (info[1]->IsObject()) {
5530 LOGD("JSCreateAnimatableProperty handle animatable arithmetic");
5531 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5532 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
5533 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
5534 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
5535 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
5536 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
5537 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
5538 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId()](
5539 const RefPtr<NG::CustomAnimatableArithmetic>& value) {
5540 ContainerScope scope(id);
5541 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
5542 if (!impl) {
5543 return;
5544 }
5545 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5546 auto newJSVal = JSRef<JSVal>(impl->GetObject());
5547 func->ExecuteJS(1, &newJSVal);
5548 };
5549 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
5550 propertyName, animatableArithmetic, onCallbackEvent);
5551 } else {
5552 LOGE("JSCreateAnimatableProperty: The value param type is invalid.");
5553 }
5554 }
5555
JSUpdateAnimatableProperty(const JSCallbackInfo & info)5556 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
5557 {
5558 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
5559 LOGE("JSUpdateAnimatableProperty: The arg is invalid.");
5560 return;
5561 }
5562
5563 std::string propertyName = info[0]->ToString();
5564 float numValue = 0.0;
5565 if (info[1]->IsNumber()) {
5566 numValue = info[1]->ToNumber<float>();
5567 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
5568 } else if (info[1]->IsObject()) {
5569 LOGD("JSUpdateAnimatableProperty handle animatable arithmetic");
5570 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5571 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
5572 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
5573 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
5574 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
5575 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
5576 } else {
5577 LOGE("JSUpdateAnimatableProperty: The value param type is invalid.");
5578 }
5579 }
5580
JsExpandSafeArea(const JSCallbackInfo & info)5581 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
5582 {
5583 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
5584 if (info.Length() >= 1 && info[0]->IsArray()) {
5585 auto paramArray = JSRef<JSArray>::Cast(info[0]);
5586 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
5587 for (size_t i = 0; i < paramArray->Length(); ++i) {
5588 if (!paramArray->GetValueAt(i)->IsNumber() ||
5589 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
5590 LOGW("Safe area type parameter is wrong, use default value SAFE_AREA_TYPE_ALL.");
5591 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
5592 break;
5593 }
5594 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
5595 }
5596 opts.type = safeAreaType;
5597 }
5598 if (info.Length() >= 2 && info[1]->IsArray()) {
5599 auto paramArray = JSRef<JSArray>::Cast(info[1]);
5600 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
5601 for (size_t i = 0; i < paramArray->Length(); ++i) {
5602 if (!paramArray->GetValueAt(i)->IsNumber() ||
5603 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
5604 LOGW("Safe area edge parameter is wrong, use default value SAFE_AREA_EDGE_ALL.");
5605 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
5606 break;
5607 }
5608 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
5609 }
5610 opts.edges = safeAreaEdge;
5611 }
5612
5613 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
5614 }
5615
JSBind(BindingTarget globalObj)5616 void JSViewAbstract::JSBind(BindingTarget globalObj)
5617 {
5618 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
5619
5620 // static methods
5621 MethodOptions opt = MethodOptions::NONE;
5622 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
5623
5624 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
5625 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
5626 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
5627 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
5628 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
5629 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
5630 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
5631 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
5632
5633 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
5634 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
5635 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
5636 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
5637 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
5638
5639 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
5640 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
5641 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
5642 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
5643 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
5644
5645 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
5646 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
5647 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
5648 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
5649 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
5650 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
5651 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
5652 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
5653 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
5654 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
5655 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
5656 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
5657 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
5658 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
5659 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
5660 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
5661 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
5662
5663 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
5664 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
5665 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
5666 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
5667 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
5668 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
5669 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
5670 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
5671 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
5672 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
5673 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
5674 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
5675
5676 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
5677 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
5678 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
5679 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
5680 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
5681 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
5682 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
5683
5684 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
5685 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
5686 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
5687 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
5688 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
5689 JSClass<JSViewAbstract>::StaticMethod("dynamicLightUp", &JSViewAbstract::JsDynamicLightUp);
5690 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
5691 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
5692 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
5693 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
5694 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
5695 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
5696 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
5697 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
5698 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
5699 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
5700 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
5701 #ifndef WEARABLE_PRODUCT
5702 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
5703 #endif
5704
5705 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
5706 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
5707 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
5708 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
5709 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
5710 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
5711 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
5712 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
5713 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
5714 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
5715 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
5716 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
5717
5718 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
5719 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
5720 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
5721 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
5722 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
5723 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
5724 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
5725 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
5726 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
5727 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
5728 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
5729 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
5730 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
5731 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
5732 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
5733 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
5734 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
5735 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
5736 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
5737 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
5738 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
5739 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
5740 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
5741 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
5742 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
5743 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
5744 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
5745 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
5746 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
5747 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
5748 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
5749 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
5750 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
5751 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
5752 #if defined(PREVIEW)
5753 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
5754 #endif
5755 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
5756 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
5757 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
5758
5759 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
5760 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
5761 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
5762 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
5763 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
5764 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
5765 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
5766 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
5767 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
5768 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
5769 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
5770 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
5771
5772 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
5773 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
5774 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
5775 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
5776
5777 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
5778
5779 JSClass<JSViewAbstract>::Bind(globalObj);
5780 }
JsAllowDrop(const JSCallbackInfo & info)5781 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
5782 {
5783 if (!info[0]->IsArray()) {
5784 LOGE("JsAllowDrop: The param type is invalid.");
5785 return;
5786 }
5787
5788 auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
5789 std::set<std::string> allowDropSet;
5790 allowDropSet.clear();
5791 std::string allowDrop;
5792 for (size_t i = 0; i < allowDropArray->Length(); i++) {
5793 allowDrop = allowDropArray->GetValueAt(i)->ToString();
5794 allowDropSet.insert(allowDrop);
5795 }
5796 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
5797 }
5798
JsAlignRules(const JSCallbackInfo & info)5799 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
5800 {
5801 if (info.Length() < 1) {
5802 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
5803 return;
5804 }
5805 if (!info[0]->IsObject()) {
5806 LOGE("arg is not Object or String.");
5807 return;
5808 }
5809
5810 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
5811 if (valueObj->IsEmpty()) {
5812 LOGE("Align rule is empty");
5813 return;
5814 }
5815 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom" };
5816 std::map<AlignDirection, AlignRule> alignRules;
5817 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
5818 auto rule = valueObj->GetProperty(keys[i]);
5819 if (rule->IsObject()) {
5820 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
5821 JSRef<JSVal> align = val->GetProperty("align");
5822 AlignRule alignRule;
5823 alignRule.anchor = val->GetProperty("anchor")->ToString();
5824 if (i < DIRECTION_RANGE) {
5825 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
5826 } else {
5827 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
5828 }
5829 alignRules[static_cast<AlignDirection>(i)] = alignRule;
5830 }
5831 }
5832
5833 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
5834 }
5835
SetMarginTop(const JSCallbackInfo & info)5836 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
5837 {
5838 if (info.Length() < 1) {
5839 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5840 return;
5841 }
5842 CalcDimension value;
5843 if (!ParseJsDimensionVp(info[0], value)) {
5844 return;
5845 }
5846 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
5847 }
5848
SetMarginBottom(const JSCallbackInfo & info)5849 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
5850 {
5851 if (info.Length() < 1) {
5852 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5853 return;
5854 }
5855 CalcDimension value;
5856 if (!ParseJsDimensionVp(info[0], value)) {
5857 return;
5858 }
5859 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
5860 }
5861
SetMarginLeft(const JSCallbackInfo & info)5862 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
5863 {
5864 if (info.Length() < 1) {
5865 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5866 return;
5867 }
5868 CalcDimension value;
5869 if (!ParseJsDimensionVp(info[0], value)) {
5870 return;
5871 }
5872 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
5873 }
5874
SetMarginRight(const JSCallbackInfo & info)5875 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
5876 {
5877 if (info.Length() < 1) {
5878 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5879 return;
5880 }
5881 CalcDimension value;
5882 if (!ParseJsDimensionVp(info[0], value)) {
5883 return;
5884 }
5885 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
5886 }
5887
SetPaddingTop(const JSCallbackInfo & info)5888 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
5889 {
5890 if (info.Length() < 1) {
5891 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5892 return;
5893 }
5894 CalcDimension value;
5895 if (!ParseJsDimensionVp(info[0], value)) {
5896 return;
5897 }
5898 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
5899 }
5900
SetPaddingBottom(const JSCallbackInfo & info)5901 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
5902 {
5903 if (info.Length() < 1) {
5904 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5905 return;
5906 }
5907 CalcDimension value;
5908 if (!ParseJsDimensionVp(info[0], value)) {
5909 return;
5910 }
5911 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
5912 }
5913
SetPaddingLeft(const JSCallbackInfo & info)5914 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
5915 {
5916 if (info.Length() < 1) {
5917 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5918 return;
5919 }
5920 CalcDimension value;
5921 if (!ParseJsDimensionVp(info[0], value)) {
5922 return;
5923 }
5924 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
5925 }
5926
SetPaddingRight(const JSCallbackInfo & info)5927 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
5928 {
5929 if (info.Length() < 1) {
5930 LOGE("The arg is wrong, it is supposed to have at least 1 argument");
5931 return;
5932 }
5933 CalcDimension value;
5934 if (!ParseJsDimensionVp(info[0], value)) {
5935 return;
5936 }
5937 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
5938 }
5939
SetBlur(float radius)5940 void JSViewAbstract::SetBlur(float radius)
5941 {
5942 CalcDimension dimensionRadius(radius, DimensionUnit::PX);
5943 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius);
5944 }
5945
SetColorBlend(Color color)5946 void JSViewAbstract::SetColorBlend(Color color)
5947 {
5948 ViewAbstractModel::GetInstance()->SetColorBlend(color);
5949 }
5950
SetBackdropBlur(float radius)5951 void JSViewAbstract::SetBackdropBlur(float radius)
5952 {
5953 CalcDimension dimensionRadius(radius, DimensionUnit::PX);
5954 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius);
5955 }
5956
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)5957 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
5958 {
5959 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
5960 }
5961
SetDynamicLightUp(float rate,float lightUpDegree)5962 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
5963 {
5964 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
5965 }
5966
SetWindowBlur(float progress,WindowBlurStyle blurStyle)5967 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
5968 {
5969 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
5970 }
5971
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)5972 bool JSViewAbstract::ParseJsonDimension(
5973 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
5974 {
5975 if (!jsonValue || jsonValue->IsNull()) {
5976 LOGD("invalid json value");
5977 return false;
5978 }
5979 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
5980 LOGE("json value is not number, string or object");
5981 return false;
5982 }
5983 if (jsonValue->IsNumber()) {
5984 result = Dimension(jsonValue->GetDouble(), defaultUnit);
5985 return true;
5986 }
5987 if (jsonValue->IsString()) {
5988 if (checkIllegal) {
5989 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
5990 }
5991 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
5992 return true;
5993 }
5994 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
5995 auto resId = resVal->GetValue("id");
5996 if (!resId || !resId->IsNumber()) {
5997 LOGE("invalid resource id");
5998 return false;
5999 }
6000 auto themeConstants = GetThemeConstants();
6001 if (!themeConstants) {
6002 LOGE("themeConstants is nullptr");
6003 return false;
6004 }
6005 result = themeConstants->GetDimension(resId->GetUInt());
6006 return true;
6007 }
6008
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)6009 bool JSViewAbstract::ParseJsonDimensionVp(
6010 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
6011 {
6012 if (PipelineBase::GetCurrentContext() &&
6013 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
6014 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
6015 }
6016 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
6017 }
6018
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)6019 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
6020 {
6021 if (!jsonValue || jsonValue->IsNull()) {
6022 LOGD("invalid json value");
6023 return false;
6024 }
6025 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
6026 LOGE("json value is not number, string or object");
6027 return false;
6028 }
6029 if (jsonValue->IsNumber()) {
6030 result = jsonValue->GetDouble();
6031 return true;
6032 }
6033 if (jsonValue->IsString()) {
6034 result = StringUtils::StringToDouble(jsonValue->GetString());
6035 return true;
6036 }
6037 // parse json Resource
6038 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
6039 auto resId = resVal->GetValue("id");
6040 CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
6041 auto id = resId->GetUInt();
6042 auto resType = resVal->GetValue("type");
6043 CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
6044 auto type = resType->GetUInt();
6045
6046 auto themeConstants = GetThemeConstants();
6047 CHECK_NULL_RETURN(themeConstants, false);
6048 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
6049 auto numberString = themeConstants->GetString(id);
6050 return StringUtils::StringToDouble(numberString, result);
6051 }
6052 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
6053 result = themeConstants->GetInt(id);
6054 return true;
6055 }
6056 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
6057 result = themeConstants->GetDouble(id);
6058 return true;
6059 }
6060 return false;
6061 }
6062
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)6063 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
6064 {
6065 if (!jsonValue || jsonValue->IsNull()) {
6066 LOGD("invalid json value");
6067 return false;
6068 }
6069 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
6070 LOGE("json value is not number, string or object");
6071 return false;
6072 }
6073 if (jsonValue->IsNumber()) {
6074 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
6075 return true;
6076 }
6077 if (jsonValue->IsString()) {
6078 result = Color::FromString(jsonValue->GetString());
6079 return true;
6080 }
6081 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
6082 auto resId = resVal->GetValue("id");
6083 if (!resId || !resId->IsNumber()) {
6084 LOGE("invalid resource id");
6085 return false;
6086 }
6087 auto themeConstants = GetThemeConstants();
6088 if (!themeConstants) {
6089 LOGW("themeConstants is nullptr");
6090 return false;
6091 }
6092 result = themeConstants->GetColor(resId->GetUInt());
6093 return true;
6094 }
6095
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)6096 void JSViewAbstract::GetAngle(
6097 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
6098 {
6099 auto value = jsonValue->GetValue(key);
6100 if (value && value->IsString()) {
6101 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
6102 } else if (value && value->IsNumber()) {
6103 angle = static_cast<float>(value->GetDouble());
6104 } else {
6105 LOGE("Invalid value type");
6106 }
6107 }
6108
CheckAngle(std::optional<float> & angle)6109 void JSViewAbstract::CheckAngle(std::optional<float>& angle)
6110 {
6111 if (LessNotEqual(angle.value(), 0.0f)) {
6112 angle = 0.0f;
6113 } else if (GreatNotEqual(angle.value(), MAX_ANGLE)) {
6114 angle = MAX_ANGLE;
6115 }
6116 }
6117
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)6118 void JSViewAbstract::GetPerspective(
6119 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
6120 {
6121 auto value = jsonValue->GetValue(key);
6122 if (value && value->IsNumber()) {
6123 perspective = static_cast<float>(value->GetDouble());
6124 }
6125 }
6126
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)6127 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
6128 {
6129 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
6130 return;
6131 }
6132
6133 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
6134 GradientColor gradientColor;
6135 auto item = colorStops->GetArrayItem(i);
6136 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
6137 auto colorParams = item->GetArrayItem(0);
6138 // color
6139 Color color;
6140 if (!ParseJsonColor(colorParams, color)) {
6141 LOGE("parse colorParams failed");
6142 continue;
6143 }
6144 gradientColor.SetColor(color);
6145 gradientColor.SetHasValue(false);
6146 // stop value
6147 if (item->GetArraySize() <= 1) {
6148 continue;
6149 }
6150 auto stopValue = item->GetArrayItem(1);
6151 double value = 0.0;
6152 if (ParseJsonDouble(stopValue, value)) {
6153 value = std::clamp(value, 0.0, 1.0);
6154 gradientColor.SetHasValue(true);
6155 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
6156 }
6157 gradient.AddColor(gradientColor);
6158 }
6159 }
6160 }
6161
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)6162 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
6163 {
6164 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
6165 return;
6166 }
6167
6168 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
6169 NG::GradientColor gradientColor;
6170 auto item = colorStops->GetArrayItem(i);
6171 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
6172 auto colorParams = item->GetArrayItem(0);
6173 // color
6174 Color color;
6175 if (!ParseJsonColor(colorParams, color)) {
6176 LOGE("parse colorParams failed");
6177 continue;
6178 }
6179 gradientColor.SetColor(color);
6180 gradientColor.SetHasValue(false);
6181 // stop value
6182 if (item->GetArraySize() <= 1) {
6183 continue;
6184 }
6185 auto stopValue = item->GetArrayItem(1);
6186 double value = 0.0;
6187 if (ParseJsonDouble(stopValue, value)) {
6188 value = std::clamp(value, 0.0, 1.0);
6189 gradientColor.SetHasValue(true);
6190 // [0, 1] -> [0, 100.0];
6191 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
6192 }
6193 gradient.AddColor(gradientColor);
6194 }
6195 }
6196 }
6197
SetDirection(const std::string & dir)6198 void JSViewAbstract::SetDirection(const std::string& dir)
6199 {
6200 TextDirection direction = TextDirection::AUTO;
6201 if (dir == "Ltr") {
6202 direction = TextDirection::LTR;
6203 } else if (dir == "Rtl") {
6204 direction = TextDirection::RTL;
6205 } else if (dir == "Auto") {
6206 direction = TextDirection::AUTO;
6207 } else if (dir == "undefined" && PipelineBase::GetCurrentContext() &&
6208 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
6209 direction = TextDirection::AUTO;
6210 }
6211 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
6212 }
6213
GetThemeConstants(const JSRef<JSObject> & jsObj)6214 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
6215 {
6216 std::string bundleName;
6217 std::string moduleName;
6218 if (!jsObj->IsUndefined()) {
6219 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
6220 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
6221 if (bundle->IsString() && module->IsString()) {
6222 bundleName = bundle->ToString();
6223 moduleName = module->ToString();
6224 }
6225 }
6226
6227 auto cardId = CardScope::CurrentId();
6228 if (cardId != INVALID_CARD_ID) {
6229 auto container = Container::Current();
6230 auto weak = container->GetCardPipeline(cardId);
6231 auto cardPipelineContext = weak.Upgrade();
6232 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
6233 auto cardThemeManager = cardPipelineContext->GetThemeManager();
6234 CHECK_NULL_RETURN(cardThemeManager, nullptr);
6235 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
6236 }
6237
6238 #ifdef PLUGIN_COMPONENT_SUPPORTED
6239 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
6240 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
6241 if (!pluginContainer) {
6242 LOGW("pluginContainer is null");
6243 return nullptr;
6244 }
6245 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
6246 if (!pluginPipelineContext) {
6247 LOGE("pluginPipelineContext is null!");
6248 return nullptr;
6249 }
6250 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
6251 if (!pluginThemeManager) {
6252 LOGE("pluginThemeManager is null!");
6253 return nullptr;
6254 }
6255 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
6256 }
6257 #endif
6258 auto container = Container::Current();
6259 CHECK_NULL_RETURN(container, nullptr);
6260 auto pipelineContext = container->GetPipelineContext();
6261 CHECK_NULL_RETURN(pipelineContext, nullptr);
6262 auto themeManager = pipelineContext->GetThemeManager();
6263 CHECK_NULL_RETURN(themeManager, nullptr);
6264 return themeManager->GetThemeConstants(bundleName, moduleName);
6265 }
6266
JsHoverEffect(const JSCallbackInfo & info)6267 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
6268 {
6269 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6270 if (!CheckJSCallbackInfo("HoverEffect", info, checkList)) {
6271 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
6272 return;
6273 }
6274 if (!info[0]->IsNumber()) {
6275 LOGE("info[0] is not a number");
6276 return;
6277 }
6278 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(info[0]->ToNumber<int32_t>()));
6279 }
6280
JsOnMouse(const JSCallbackInfo & info)6281 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
6282 {
6283 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
6284 LOGD("JsOnMouse callback is undefined");
6285 ViewAbstractModel::GetInstance()->DisableOnMouse();
6286 return;
6287 }
6288 if (!info[0]->IsFunction()) {
6289 LOGE("the param is not a function");
6290 return;
6291 }
6292
6293 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
6294 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc)](MouseInfo& mouseInfo) {
6295 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6296 ACE_SCORING_EVENT("onMouse");
6297 func->Execute(mouseInfo);
6298 };
6299 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
6300 }
6301
JsOnHover(const JSCallbackInfo & info)6302 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
6303 {
6304 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
6305 LOGD("JsOnHover callback is undefined");
6306 ViewAbstractModel::GetInstance()->DisableOnHover();
6307 return;
6308 }
6309 if (!info[0]->IsFunction()) {
6310 LOGE("the param is not a function");
6311 return;
6312 }
6313
6314 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
6315 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc)](
6316 bool isHover, HoverInfo& hoverInfo) {
6317 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6318 ACE_SCORING_EVENT("onHover");
6319 func->HoverExecute(isHover, hoverInfo);
6320 };
6321 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
6322 }
6323
JsOnClick(const JSCallbackInfo & info)6324 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
6325 {
6326 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
6327 LOGD("JsOnClick callback is undefined");
6328 ViewAbstractModel::GetInstance()->DisableOnClick();
6329 return;
6330 }
6331 if (!info[0]->IsFunction()) {
6332 LOGW("the info is not click function");
6333 return;
6334 }
6335
6336 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
6337 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc)](GestureEvent& info) {
6338 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6339 ACE_SCORING_EVENT("onClick");
6340 func->Execute(info);
6341 };
6342 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc](const ClickInfo* info) {
6343 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6344 ACE_SCORING_EVENT("onClick");
6345 func->Execute(*info);
6346 };
6347 ViewAbstractModel::GetInstance()->SetOnClick(std::move(onTap), std::move(onClick));
6348 }
6349
JsClickEffect(const JSCallbackInfo & info)6350 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
6351 {
6352 if (info.Length() < 1) {
6353 LOGW("clickEffect needs at least 1 parameter.");
6354 return;
6355 }
6356 if (info[0]->IsUndefined() || info[0]->IsNull()) {
6357 LOGD("Parameter value error, not set effect.");
6358 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
6359 return;
6360 }
6361 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
6362 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
6363 int32_t clickEffectLevelValue = 0;
6364 if (clickEffectLevel->IsNumber()) {
6365 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
6366 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
6367 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
6368 LOGW("clickEffectLevel over range, use default value.");
6369 clickEffectLevelValue = 0;
6370 }
6371 }
6372
6373 JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
6374 float scaleNumberValue = DEFAULT_SCALE_LIGHT;
6375 if (!scaleNumber->IsNumber()) {
6376 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
6377 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
6378 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
6379 }
6380 ViewAbstractModel::GetInstance()->SetClickEffectLevel(
6381 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
6382 return;
6383 }
6384
6385 scaleNumberValue = scaleNumber->ToNumber<float>();
6386 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
6387 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
6388 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
6389 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
6390 } else {
6391 scaleNumberValue = DEFAULT_SCALE_LIGHT;
6392 }
6393 }
6394
6395 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
6396 }
6397
JsOnVisibleAreaChange(const JSCallbackInfo & info)6398 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
6399 {
6400 if (info.Length() != 2) {
6401 LOGE("JsOnVisibleAreaChange: The arg is wrong, it is supposed to have 2 arguments");
6402 return;
6403 }
6404
6405 if (!info[0]->IsArray() || !info[1]->IsFunction()) {
6406 LOGE("JsOnVisibleAreaChange: The param type is invalid.");
6407 return;
6408 }
6409
6410 auto ratioArray = JSRef<JSArray>::Cast(info[0]);
6411 size_t size = ratioArray->Length();
6412 std::vector<double> ratioVec(size);
6413 ratioVec.clear();
6414 for (size_t i = 0; i < size; i++) {
6415 double ratio = 0.0;
6416 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
6417 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
6418 ratio = VISIBLE_RATIO_MIN;
6419 }
6420
6421 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
6422 ratio = VISIBLE_RATIO_MAX;
6423 }
6424 ratioVec.push_back(ratio);
6425 }
6426
6427 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
6428 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
6429 bool visible, double ratio) {
6430 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6431 ACE_SCORING_EVENT("onVisibleAreaChange");
6432
6433 JSRef<JSVal> params[2];
6434 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
6435 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
6436 func->ExecuteJS(2, params);
6437 };
6438 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
6439 }
6440
JsHitTestBehavior(const JSCallbackInfo & info)6441 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
6442 {
6443 if (info.Length() != 1) {
6444 LOGE("JsHitTestBehavior: The arg is wrong, it is supposed to have 1 arguments");
6445 return;
6446 }
6447
6448 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
6449 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
6450 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
6451 }
6452
JsForegroundColor(const JSCallbackInfo & info)6453 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
6454 {
6455 if (info.Length() < 1) {
6456 LOGE("The argv is wrong, it is supposed to have at least 1 argument");
6457 return;
6458 }
6459 Color foregroundColor;
6460 ForegroundColorStrategy strategy;
6461 if (ParseJsColorStrategy(info[0], strategy)) {
6462 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
6463 return;
6464 }
6465 if (!ParseJsColor(info[0], foregroundColor)) {
6466 return;
6467 }
6468 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
6469 }
6470
JsKeyboardShortcut(const JSCallbackInfo & info)6471 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
6472 {
6473 // KeyboardShortcut only allows 2 or 3 params.
6474 if (info.Length() < 2 || info.Length() > 3) {
6475 LOGE("JsKeyboardShortcut: The arg is wrong, it is supposed to have 2 or 3 arguments");
6476 return;
6477 }
6478 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
6479 LOGE("JsKeyboardShortcut: The param type is invalid.");
6480 ViewAbstractModel::GetInstance()->SetKeyboardShortcut("", std::vector<ModifierKey>(), nullptr);
6481 return;
6482 }
6483
6484 std::string value;
6485 if (info[0]->IsString()) {
6486 value = info[0]->ToString();
6487 if (value.empty() || value.size() > 1) {
6488 LOGE("KeyboardShortcut value arg is wrong, return");
6489 ViewAbstractModel::GetInstance()->SetKeyboardShortcut("", std::vector<ModifierKey>(), nullptr);
6490 return;
6491 }
6492 } else {
6493 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
6494 value = GetFunctionKeyName(functionkey);
6495 }
6496
6497 auto keysArray = JSRef<JSArray>::Cast(info[1]);
6498 size_t size = keysArray->Length();
6499 std::vector<ModifierKey> keys(size);
6500 keys.clear();
6501 for (size_t i = 0; i < size; i++) {
6502 JSRef<JSVal> key = keysArray->GetValueAt(i);
6503 if (key->IsNumber()) {
6504 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
6505 }
6506 }
6507
6508 // KeyboardShortcut allows 3 params, the third param is function callback.
6509 if (info.Length() == 3 && info[2]->IsFunction()) {
6510 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
6511 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)]() {
6512 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6513 ACE_SCORING_EVENT("onKeyboardShortcutAction");
6514 func->ExecuteJS();
6515 };
6516 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
6517 return;
6518 }
6519 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
6520 }
6521
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)6522 bool JSViewAbstract::CheckColor(
6523 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
6524 {
6525 // Color is undefined or null
6526 if (jsValue->IsUndefined() || jsValue->IsNull()) {
6527 return false;
6528 }
6529 // input type is not in [number, string, Resource]
6530 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
6531 return false;
6532 }
6533 // Correct type, incorrect value parsing
6534 if (!ParseJsColor(jsValue, result)) {
6535 return false;
6536 }
6537 return true;
6538 }
6539
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)6540 bool JSViewAbstract::CheckLength(
6541 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
6542 {
6543 // Length is undefined or null
6544 if (jsValue->IsUndefined() || jsValue->IsNull()) {
6545 return false;
6546 }
6547 // input type is not in [number, string, Resource]
6548 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
6549 return false;
6550 }
6551 if (PipelineBase::GetCurrentContext() &&
6552 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
6553 return ParseJsDimensionVpNG(jsValue, result);
6554 }
6555 // Correct type, incorrect value parsing
6556 if (!ParseJsDimensionVp(jsValue, result)) {
6557 return false;
6558 }
6559 return true;
6560 }
6561
JsObscured(const JSCallbackInfo & info)6562 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
6563 {
6564 if (info[0]->IsUndefined()) {
6565 std::vector<ObscuredReasons> reasons(0);
6566 ViewAbstractModel::GetInstance()->SetObscured(reasons);
6567 return;
6568 }
6569 if (!info[0]->IsArray()) {
6570 return;
6571 }
6572
6573 auto obscuredArray = JSRef<JSArray>::Cast(info[0]);
6574 size_t size = obscuredArray->Length();
6575 std::vector<ObscuredReasons> reasons(size);
6576 reasons.clear();
6577 for (size_t i = 0; i < size; i++) {
6578 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
6579 if (reason->IsNumber()) {
6580 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
6581 }
6582 }
6583
6584 ViewAbstractModel::GetInstance()->SetObscured(reasons);
6585 }
6586
JSRenderGroup(const JSCallbackInfo & info)6587 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
6588 {
6589 if (info.Length() != 1) {
6590 LOGW("renderGroup needs one parameter");
6591 return;
6592 }
6593 bool isRenderGroup = false;
6594 if (info[0]->IsBoolean()) {
6595 isRenderGroup = info[0]->ToBoolean();
6596 }
6597 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
6598 }
6599
JSRenderFit(const JSCallbackInfo & info)6600 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
6601 {
6602 if (info.Length() != 1) {
6603 LOGW("renderFit needs one parameter");
6604 return;
6605 }
6606 RenderFit renderFit = RenderFit::TOP_LEFT;
6607 if (info[0]->IsNumber()) {
6608 int32_t fitNumber = info[0]->ToNumber<int32_t>();
6609 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
6610 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
6611 renderFit = static_cast<RenderFit>(fitNumber);
6612 }
6613 }
6614 // how content fills the node duration implicit animation
6615 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
6616 }
6617
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)6618 void JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
6619 {
6620 if (!jsValue->IsObject() || jsValue->IsString()) {
6621 return;
6622 }
6623 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6624 if (!jsObj->IsUndefined()) {
6625 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
6626 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
6627 if (bundle->IsString() && module->IsString()) {
6628 bundleName = bundle->ToString();
6629 moduleName = module->ToString();
6630 }
6631 }
6632 }
6633 } // namespace OHOS::Ace::Framework
6634