• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
17 
18 #include <algorithm>
19 #include <regex>
20 #include <vector>
21 
22 #include "base/json/json_util.h"
23 #include "bridge/common/utils/utils.h"
24 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
25 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
26 #include "bridge/declarative_frontend/engine/functions/js_function.h"
27 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
28 #include "bridge/declarative_frontend/jsview/js_utils.h"
29 #include "core/components_v2/extensions/events/on_area_change_extension.h"
30 #ifdef USE_V8_ENGINE
31 #include "bridge/declarative_frontend/engine/v8/functions/v8_function.h"
32 #endif
33 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
34 #include "bridge/declarative_frontend/jsview/js_view_register.h"
35 #include "bridge/declarative_frontend/view_stack_processor.h"
36 #include "core/common/ace_application_info.h"
37 #include "core/components/box/box_component_helper.h"
38 #include "core/components/common/layout/align_declaration.h"
39 #include "core/components/common/properties/motion_path_option.h"
40 #include "core/components/menu/menu_component.h"
41 #include "core/components/option/option_component.h"
42 #include "core/gestures/long_press_gesture.h"
43 #include "frameworks/base/memory/referenced.h"
44 #include "frameworks/bridge/declarative_frontend/engine/functions/js_click_function.h"
45 #include "frameworks/bridge/declarative_frontend/jsview/js_shape_abstract.h"
46 #include "frameworks/core/components/text/text_component.h"
47 
48 namespace OHOS::Ace::Framework {
49 namespace {
50 
51 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
52 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
53 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
54 constexpr int32_t MAX_ALIGN_VALUE = 8;
55 constexpr int32_t DEFAULT_LONG_PRESS_FINGER = 1;
56 constexpr int32_t DEFAULT_LONG_PRESS_DURATION = 500;
57 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
58 constexpr double FULL_DIMENSION = 100.0;
59 constexpr double HALF_DIMENSION = 50.0;
60 
CheckJSCallbackInfo(const std::string & callerName,const JSCallbackInfo & info,std::vector<JSCallbackInfoType> & infoTypes)61 bool CheckJSCallbackInfo(const std::string& callerName, const JSCallbackInfo& info,
62     std::vector<JSCallbackInfoType>& infoTypes)
63 {
64     if (info.Length() < 1) {
65         LOGE("%{public}s: The arg is supposed to have at least one argument", callerName.c_str());
66         return false;
67     }
68     bool typeVerified = false;
69     std::string unrecognizedType;
70     for (const auto& infoType : infoTypes) {
71         switch (infoType) {
72             case JSCallbackInfoType::STRING:
73                 if (info[0]->IsString()) {
74                     typeVerified = true;
75                 } else {
76                     unrecognizedType += "string|";
77                 }
78                 break;
79             case JSCallbackInfoType::NUMBER:
80                 if (info[0]->IsNumber()) {
81                     typeVerified = true;
82                 } else {
83                     unrecognizedType += "number|";
84                 }
85                 break;
86             case JSCallbackInfoType::OBJECT:
87                 if (info[0]->IsObject()) {
88                     typeVerified = true;
89                 } else {
90                     unrecognizedType += "object|";
91                 }
92                 break;
93             case JSCallbackInfoType::FUNCTION:
94                 if (info[0]->IsFunction()) {
95                     typeVerified = true;
96                 } else {
97                     unrecognizedType += "Function|";
98                 }
99                 break;
100             default:
101                 break;
102         }
103     }
104     if (!typeVerified) {
105         LOGE("%{public}s: info[0] is not a [%{public}s]",
106             callerName.c_str(), unrecognizedType.substr(0, unrecognizedType.size()-1).c_str());
107     }
108     return typeVerified || infoTypes.size() == 0;
109 }
110 
ParseJsScale(std::unique_ptr<JsonValue> & argsPtrItem,float & scaleX,float & scaleY,float & scaleZ,Dimension & centerX,Dimension & centerY)111 void ParseJsScale(std::unique_ptr<JsonValue>& argsPtrItem, float& scaleX, float& scaleY, float& scaleZ,
112     Dimension& centerX, Dimension& centerY)
113 {
114     double xVal = 1.0;
115     double yVal = 1.0;
116     double zVal = 1.0;
117     JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), xVal);
118     JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), yVal);
119     JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), zVal);
120     scaleX = static_cast<float>(xVal);
121     scaleY = static_cast<float>(yVal);
122     scaleZ = static_cast<float>(zVal);
123     // if specify centerX
124     Dimension length;
125     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length)) {
126         centerX = length;
127     }
128     // if specify centerY
129     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length)) {
130         centerY = length;
131     }
132 }
133 
ParseJsTranslate(std::unique_ptr<JsonValue> & argsPtrItem,Dimension & translateX,Dimension & translateY,Dimension & translateZ)134 void ParseJsTranslate(
135     std::unique_ptr<JsonValue>& argsPtrItem, Dimension& translateX, Dimension& translateY, Dimension& translateZ)
136 {
137     Dimension length;
138     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("x"), length)) {
139         translateX = length;
140     }
141     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("y"), length)) {
142         translateY = length;
143     }
144     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("z"), length)) {
145         translateZ = length;
146     }
147 }
148 
ParseJsRotate(std::unique_ptr<JsonValue> & argsPtrItem,float & dx,float & dy,float & dz,Dimension & centerX,Dimension & centerY,std::optional<float> & angle)149 void ParseJsRotate(std::unique_ptr<JsonValue>& argsPtrItem, float& dx, float& dy, float& dz, Dimension& centerX,
150     Dimension& centerY, std::optional<float>& angle)
151 {
152     // default: dx, dy, dz (0.0, 0.0, 0.0)
153     double dxVal = 0.0;
154     double dyVal = 0.0;
155     double dzVal = 0.0;
156     JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), dxVal);
157     JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), dyVal);
158     JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), dzVal);
159     dx = static_cast<float>(dxVal);
160     dy = static_cast<float>(dyVal);
161     dz = static_cast<float>(dzVal);
162     // if specify centerX
163     Dimension length;
164     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length)) {
165         centerX = length;
166     }
167     // if specify centerY
168     if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length)) {
169         centerY = length;
170     }
171     // if specify angle
172     JSViewAbstract::GetAngle("angle", argsPtrItem, angle);
173 }
174 
SetDefaultTransition(TransitionType transitionType)175 void SetDefaultTransition(TransitionType transitionType)
176 {
177     auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
178     if (!display) {
179         LOGE("display component is null.");
180         return;
181     }
182     LOGI("JsTransition with default");
183     display->SetTransition(transitionType, 0.0);
184 }
185 
ParseAndSetOpacityTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)186 bool ParseAndSetOpacityTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
187 {
188     if (transitionArgs->Contains("opacity")) {
189         double opacity = 0.0;
190         JSViewAbstract::ParseJsonDouble(transitionArgs->GetValue("opacity"), opacity);
191         auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
192         if (!display) {
193             LOGE("display component is null.");
194             return true;
195         }
196         LOGI("JsTransition with type: %{public}d, opacity: %{public}.2f", transitionType, opacity);
197         display->SetTransition(transitionType, opacity);
198         return true;
199     }
200     return false;
201 }
202 
ParseAndSetRotateTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)203 bool ParseAndSetRotateTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
204 {
205     if (transitionArgs->Contains("rotate")) {
206         auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
207         if (!transform) {
208             LOGE("transform component is null.");
209             return true;
210         }
211         auto rotateArgs = transitionArgs->GetObject("rotate");
212         // default: dx, dy, dz (0.0, 0.0, 0.0)
213         float dx = 0.0f;
214         float dy = 0.0f;
215         float dz = 0.0f;
216         // default centerX, centerY 50% 50%;
217         Dimension centerX = 0.5_pct;
218         Dimension centerY = 0.5_pct;
219         std::optional<float> angle;
220         ParseJsRotate(rotateArgs, dx, dy, dz, centerX, centerY, angle);
221         if (angle) {
222             transform->SetRotateTransition(transitionType, dx, dy, dz, angle.value());
223             transform->SetOriginDimension(DimensionOffset(centerX, centerY));
224             LOGI("JsTransition with type: %{public}d. rotate: [%.2f, %.2f, %.2f] [%.2f, %.2f] %.2f", transitionType, dx,
225                 dy, dz, centerX.Value(), centerY.Value(), angle.value());
226         }
227         return true;
228     }
229     return false;
230 }
231 
ParseAndSetScaleTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)232 bool ParseAndSetScaleTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
233 {
234     if (transitionArgs->Contains("scale")) {
235         auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
236         if (!transform) {
237             LOGE("transform component is null.");
238             return true;
239         }
240         auto scaleArgs = transitionArgs->GetObject("scale");
241         // default: x, y, z (1.0, 1.0, 1.0)
242         auto scaleX = 1.0f;
243         auto scaleY = 1.0f;
244         auto scaleZ = 1.0f;
245         // default centerX, centerY 50% 50%;
246         Dimension centerX = 0.5_pct;
247         Dimension centerY = 0.5_pct;
248         ParseJsScale(scaleArgs, scaleX, scaleY, scaleZ, centerX, centerY);
249         transform->SetScaleTransition(transitionType, scaleX, scaleY, scaleZ);
250         transform->SetOriginDimension(DimensionOffset(centerX, centerY));
251         LOGI("JsTransition with type: %{public}d. scale: [%.2f, %.2f, %.2f] [%.2f, %.2f]", transitionType, scaleX,
252             scaleY, scaleZ, centerX.Value(), centerY.Value());
253         return true;
254     }
255     return false;
256 }
257 
ParseAndSetTranslateTransition(const std::unique_ptr<JsonValue> & transitionArgs,TransitionType transitionType)258 bool ParseAndSetTranslateTransition(const std::unique_ptr<JsonValue>& transitionArgs, TransitionType transitionType)
259 {
260     if (transitionArgs->Contains("translate")) {
261         auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
262         if (!transform) {
263             LOGE("transform component is null.");
264             return true;
265         }
266         auto translateArgs = transitionArgs->GetObject("translate");
267         // default: x, y, z (0.0, 0.0, 0.0)
268         auto translateX = Dimension(0.0);
269         auto translateY = Dimension(0.0);
270         auto translateZ = Dimension(0.0);
271         ParseJsTranslate(translateArgs, translateX, translateY, translateZ);
272         transform->SetTranslateTransition(transitionType, translateX, translateY, translateZ);
273         LOGI("JsTransition with type: %{public}d. translate: [%.2f, %.2f, %.2f]", transitionType, translateX.Value(),
274             translateY.Value(), translateZ.Value());
275         return true;
276     }
277     return false;
278 }
279 
ParseMotionPath(const std::unique_ptr<JsonValue> & argsPtrItem,MotionPathOption & option)280 bool ParseMotionPath(const std::unique_ptr<JsonValue>& argsPtrItem, MotionPathOption& option)
281 {
282     if (argsPtrItem && !argsPtrItem->IsNull()) {
283         auto path = argsPtrItem->GetString("path", "");
284         if (!path.empty()) {
285             option.SetPath(path);
286             double from = 0.0;
287             double to = 1.0;
288             JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("from"), from);
289             JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("to"), to);
290             option.SetBegin(static_cast<float>(from));
291             option.SetEnd(static_cast<float>(to));
292             option.SetRotate(argsPtrItem->GetBool("rotatable", false));
293             return true;
294         }
295     }
296     return false;
297 }
298 
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)299 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY,
300     const double valueX, const double valueY, BackgroundImagePosition& bgImgPosition)
301 {
302     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
303     bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
304     bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
305 }
306 
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)307 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
308 {
309     JSRef<JSVal> item = params->GetValueAt(pos + containCount);
310     if (type == "d") {
311         if (item->IsNumber()) {
312             return std::to_string(item->ToNumber<uint32_t>());
313         }
314     } else if (type == "s") {
315         if (item->IsString()) {
316             return item->ToString();
317         }
318     } else if (type == "f") {
319         if (item->IsNumber()) {
320             return std::to_string(item->ToNumber<float>());
321         }
322     }
323     return std::string();
324 }
325 
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)326 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
327 {
328     auto size = static_cast<int32_t>(params->Length());
329     if (containCount == size) {
330         return;
331     }
332     std::string::const_iterator start = originStr.begin();
333     std::string::const_iterator end = originStr.end();
334     std::smatch matchs;
335     bool shortHolderType = false;
336     bool firstMatch = true;
337     int searchTime = 0;
338     while (std::regex_search(start, end, matchs, RESOURCE_APP_STRING_PLACEHOLDER)) {
339         std::string pos = matchs[2];
340         std::string type = matchs[4];
341         if (firstMatch) {
342             firstMatch = false;
343             shortHolderType = pos.length() == 0;
344         } else {
345             if (shortHolderType ^ (pos.length() == 0)) {
346                 LOGE("wrong place holder,stop parse string");
347                 return;
348             }
349         }
350 
351         std::string replaceContentStr;
352         if (shortHolderType) {
353             replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
354         } else {
355             replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
356         }
357 
358         originStr.replace(matchs[0].first - originStr.begin(), matchs[0].length(), replaceContentStr);
359         start = originStr.begin() + matchs.prefix().length() + replaceContentStr.length();
360         end = originStr.end();
361         searchTime++;
362     }
363 }
364 
ParseLocationProps(const JSCallbackInfo & info,AnimatableDimension & x,AnimatableDimension & y)365 bool ParseLocationProps(const JSCallbackInfo& info, AnimatableDimension& x, AnimatableDimension& y)
366 {
367     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
368     if (!CheckJSCallbackInfo("ParseLocationProps", info, checkList)) {
369         return false;
370     }
371     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
372     JSRef<JSVal> xVal = sizeObj->GetProperty("x");
373     JSRef<JSVal> yVal = sizeObj->GetProperty("y");
374     bool hasX = JSViewAbstract::ParseJsAnimatableDimensionVp(xVal, x);
375     bool hasY = JSViewAbstract::ParseJsAnimatableDimensionVp(yVal, y);
376     return hasX || hasY;
377 }
378 
379 #ifndef WEARABLE_PRODUCT
380 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
381     Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT };
382 
ParseShowObject(const JSCallbackInfo & info,const JSRef<JSObject> & showObj,const RefPtr<PopupComponentV2> & popupComponent)383 void ParseShowObject(
384     const JSCallbackInfo& info, const JSRef<JSObject>& showObj, const RefPtr<PopupComponentV2>& popupComponent)
385 {
386     JSRef<JSVal> changeEventVal = showObj->GetProperty("changeEvent");
387     if (changeEventVal->IsFunction()) {
388         RefPtr<JsFunction> jsFunc =
389             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
390         auto eventMarker = EventMarker(
391             [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
392                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
393                 ACE_SCORING_EVENT("Popup.onStateChange");
394 
395                 if (param != "true" && param != "false") {
396                     LOGE("param is not equal true or fasle, invaild.");
397                     return;
398                 }
399 
400                 bool newValue = StringToBool(param);
401                 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
402                 func->ExecuteJS(1, &newJSVal);
403             });
404         popupComponent->SetChangeEvent(eventMarker);
405     }
406 }
407 
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupComponentV2> & popupComponent)408 void ParsePopupParam(
409     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupComponentV2>& popupComponent)
410 {
411     JSRef<JSVal> messageVal = popupObj->GetProperty("message");
412     popupComponent->SetMessage(messageVal->ToString());
413 
414     JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
415     if (placementOnTopVal->IsBoolean()) {
416         popupComponent->SetPlacementOnTop(placementOnTopVal->ToBoolean());
417     }
418 
419     JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
420     if (onStateChangeVal->IsFunction()) {
421         std::vector<std::string> keys = { "isVisible" };
422         RefPtr<JsFunction> jsFunc =
423             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
424         auto eventMarker = EventMarker(
425             [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](const std::string& param) {
426                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
427                 ACE_SCORING_EVENT("Popup.onStateChange");
428                 func->Execute(keys, param);
429             });
430         popupComponent->SetOnStateChange(eventMarker);
431     }
432 
433     JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
434     if (primaryButtonVal->IsObject()) {
435         ButtonProperties properties;
436         JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
437         JSRef<JSVal> value = obj->GetProperty("value");
438         if (value->IsString()) {
439             properties.value = value->ToString();
440         }
441 
442         JSRef<JSVal> actionValue = obj->GetProperty("action");
443         if (actionValue->IsFunction()) {
444             auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
445             EventMarker actionId([execCtx = info.GetExecutionContext(), func = std::move(actionFunc)]() {
446                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
447                 ACE_SCORING_EVENT("primaryButton.action");
448                 func->Execute();
449             });
450             properties.actionId = actionId;
451         }
452         properties.showButton = true;
453         popupComponent->SetPrimaryButtonProperties(properties);
454     }
455 
456     JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
457     if (secondaryButtonVal->IsObject()) {
458         ButtonProperties properties;
459         JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
460         JSRef<JSVal> value = obj->GetProperty("value");
461         if (value->IsString()) {
462             properties.value = value->ToString();
463         }
464 
465         JSRef<JSVal> actionValue = obj->GetProperty("action");
466         if (actionValue->IsFunction()) {
467             auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
468             EventMarker actionId([execCtx = info.GetExecutionContext(), func = std::move(actionFunc)]() {
469                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
470                 ACE_SCORING_EVENT("secondaryButton.action");
471                 func->Execute();
472             });
473             properties.actionId = actionId;
474         }
475         properties.showButton = true;
476         popupComponent->SetSecondaryButtonProperties(properties);
477     }
478 }
479 
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupComponentV2> & popupComponent)480 void ParseCustomPopupParam(
481     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupComponentV2>& popupComponent)
482 {
483     RefPtr<Component> customComponent;
484     auto builderValue = popupObj->GetProperty("builder");
485     if (!builderValue->IsObject()) {
486         LOGE("builder param is not an object.");
487         return;
488     }
489 
490     JSRef<JSObject> builderObj;
491     builderObj = JSRef<JSObject>::Cast(builderValue);
492     auto builder = builderObj->GetProperty("builder");
493     if (!builder->IsFunction()) {
494         LOGE("builder param is not a function.");
495         return;
496     }
497     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
498     if (!builderFunc) {
499         LOGE("builder function is null.");
500         return;
501     }
502     // use another VSP instance while executing the builder function
503     ScopedViewStackProcessor builderViewStackProcessor;
504     {
505         ACE_SCORING_EVENT("popup.builder");
506         builderFunc->Execute();
507     }
508     customComponent = ViewStackProcessor::GetInstance()->Finish();
509     popupComponent->SetCustomComponent(customComponent);
510 
511     auto popupParam = popupComponent->GetPopupParam();
512     popupParam->SetUseCustomComponent(true);
513     auto placementValue = popupObj->GetProperty("placement");
514     if (placementValue->IsNumber()) {
515         auto placement = placementValue->ToNumber<int32_t>();
516         if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
517             popupParam->SetPlacement(PLACEMENT[placement]);
518         }
519     }
520 
521     auto maskColorValue = popupObj->GetProperty("maskColor");
522     Color maskColor;
523     if (JSViewAbstract::ParseJsColor(maskColorValue, maskColor)) {
524         popupParam->SetMaskColor(maskColor);
525     }
526 
527     auto popupColorValue = popupObj->GetProperty("popupColor");
528     Color backgroundColor;
529     if (JSViewAbstract::ParseJsColor(popupColorValue, backgroundColor)) {
530         popupParam->SetBackgroundColor(backgroundColor);
531     }
532 
533     auto enableArrowValue = popupObj->GetProperty("enableArrow");
534     if (enableArrowValue->IsBoolean()) {
535         popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
536     }
537 
538     auto autoCancelValue = popupObj->GetProperty("autoCancel");
539     if (autoCancelValue->IsBoolean()) {
540         popupParam->SetHasAction(!autoCancelValue->ToBoolean());
541     }
542 
543     JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
544     if (onStateChangeVal->IsFunction()) {
545         std::vector<std::string> keys = { "isVisible" };
546         RefPtr<JsFunction> jsFunc =
547             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
548         auto eventMarker = EventMarker(
549             [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys](const std::string& param) {
550                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
551                 ACE_SCORING_EVENT("popup.onStateChange");
552                 func->Execute(keys, param);
553             });
554         popupComponent->SetOnStateChange(eventMarker);
555     }
556 }
557 #endif
558 
559 } // namespace
560 
ColorAlphaAdapt(uint32_t origin)561 uint32_t ColorAlphaAdapt(uint32_t origin)
562 {
563     uint32_t result = origin;
564     if (origin >> COLOR_ALPHA_OFFSET == 0) {
565         result = origin | COLOR_ALPHA_VALUE;
566     }
567     return result;
568 }
569 
JsScale(const JSCallbackInfo & info)570 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
571 {
572     LOGD("JsScale");
573     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
574     if (!CheckJSCallbackInfo("JsScale", info, checkList)) {
575         return;
576     }
577 
578     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
579     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
580     if (info[0]->IsObject()) {
581         auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
582         if (!argsPtrItem || argsPtrItem->IsNull()) {
583             LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
584             return;
585         }
586         if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
587             // default: x, y, z (1.0, 1.0, 1.0)
588             auto scaleX = 1.0f;
589             auto scaleY = 1.0f;
590             auto scaleZ = 1.0f;
591             // default centerX, centerY 50% 50%;
592             Dimension centerX = 0.5_pct;
593             Dimension centerY = 0.5_pct;
594             ParseJsScale(argsPtrItem, scaleX, scaleY, scaleZ, centerX, centerY);
595             transform->Scale(scaleX, scaleY, scaleZ, option);
596             transform->SetOriginDimension(DimensionOffset(centerX, centerY));
597             return;
598         }
599     }
600     double scale;
601     if (ParseJsDouble(info[0], scale)) {
602         transform->Scale(scale, option);
603     }
604 }
605 
JsScaleX(const JSCallbackInfo & info)606 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
607 {
608     LOGD("JsScaleX");
609     if (info.Length() < 1) {
610         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
611         return;
612     }
613 
614     double scaleVal = 0.0;
615     if (!ParseJsDouble(info[0], scaleVal)) {
616         return;
617     }
618 
619     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
620     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
621     transform->ScaleX(scaleVal, option);
622 }
623 
JsScaleY(const JSCallbackInfo & info)624 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
625 {
626     LOGD("JsScaleY");
627     if (info.Length() < 1) {
628         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
629         return;
630     }
631 
632     double scaleVal = 0.0;
633     if (!ParseJsDouble(info[0], scaleVal)) {
634         return;
635     }
636 
637     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
638     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
639     transform->ScaleY(scaleVal, option);
640 }
641 
JsOpacity(const JSCallbackInfo & info)642 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
643 {
644     LOGD("js_opacity");
645     if (info.Length() < 1) {
646         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
647         return;
648     }
649 
650     double opacity = 0.0;
651     if (!ParseJsDouble(info[0], opacity)) {
652         return;
653     }
654 
655     auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
656     auto stack = ViewStackProcessor::GetInstance();
657     auto option = stack->GetImplicitAnimationOption();
658     if (!stack->IsVisualStateSet()) {
659         display->SetOpacity(opacity, option);
660     } else {
661         display->GetStateAttributes()->AddAttribute<AnimatableDouble>(DisplayStateAttribute::OPACITY,
662             AnimatableDouble(opacity, option), stack->GetVisualState());
663         if (!display->GetStateAttributes()->
664             HasAttribute(DisplayStateAttribute::OPACITY, VisualState::NORMAL)) {
665             display->GetStateAttributes()->AddAttribute<AnimatableDouble>(DisplayStateAttribute::OPACITY,
666                 AnimatableDouble(display->GetOpacity(), option), VisualState::NORMAL);
667         }
668     }
669 }
670 
JsTranslate(const JSCallbackInfo & info)671 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
672 {
673     LOGD("JsTranslate");
674     std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
675         JSCallbackInfoType::OBJECT };
676     if (!CheckJSCallbackInfo("JsTranslate", info, checkList)) {
677         return;
678     }
679 
680     Dimension value;
681     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
682     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
683     if (info[0]->IsObject()) {
684         auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
685         if (!argsPtrItem || argsPtrItem->IsNull()) {
686             LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
687             return;
688         }
689         if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
690             // default: x, y, z (0.0, 0.0, 0.0)
691             auto translateX = Dimension(0.0);
692             auto translateY = Dimension(0.0);
693             auto translateZ = Dimension(0.0);
694             ParseJsTranslate(argsPtrItem, translateX, translateY, translateZ);
695             transform->Translate(translateX, translateY, translateZ, option);
696             return;
697         }
698     }
699     if (ParseJsDimensionVp(info[0], value)) {
700         transform->Translate(value, value, option);
701     }
702 }
703 
JsTranslateX(const JSCallbackInfo & info)704 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
705 {
706     LOGD("JsTranslateX");
707     if (info.Length() < 1) {
708         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
709         return;
710     }
711     Dimension value;
712     if (!ParseJsDimensionVp(info[0], value)) {
713         return;
714     }
715 
716     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
717     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
718     transform->TranslateX(value, option);
719 }
720 
JsTranslateY(const JSCallbackInfo & info)721 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
722 {
723     LOGD("JsTranslateY");
724     if (info.Length() < 1) {
725         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
726         return;
727     }
728     Dimension value;
729     if (!ParseJsDimensionVp(info[0], value)) {
730         return;
731     }
732     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
733     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
734     transform->TranslateY(value, option);
735 }
736 
JsRotate(const JSCallbackInfo & info)737 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
738 {
739     LOGD("JsRotate");
740     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
741     if (!CheckJSCallbackInfo("JsRotate", info, checkList)) {
742         return;
743     }
744 
745     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
746     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
747     if (info[0]->IsObject()) {
748         auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
749         if (!argsPtrItem || argsPtrItem->IsNull()) {
750             LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
751             return;
752         }
753         if (argsPtrItem->Contains("x") || argsPtrItem->Contains("y") || argsPtrItem->Contains("z")) {
754             // default: dx, dy, dz (0.0, 0.0, 0.0)
755             float dx = 0.0f;
756             float dy = 0.0f;
757             float dz = 0.0f;
758             // default centerX, centerY 50% 50%;
759             Dimension centerX = 0.5_pct;
760             Dimension centerY = 0.5_pct;
761             std::optional<float> angle;
762             ParseJsRotate(argsPtrItem, dx, dy, dz, centerX, centerY, angle);
763             if (angle) {
764                 transform->Rotate(dx, dy, dz, angle.value(), option);
765                 transform->SetOriginDimension(DimensionOffset(centerX, centerY));
766             } else {
767                 LOGE("Js JsRotate failed, not specify angle");
768             }
769             return;
770         }
771     }
772     double rotateZ;
773     if (ParseJsDouble(info[0], rotateZ)) {
774         transform->RotateZ(rotateZ, option);
775     }
776 }
777 
JsRotateX(const JSCallbackInfo & info)778 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
779 {
780     LOGD("JsRotateX");
781     if (info.Length() < 1) {
782         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
783         return;
784     }
785 
786     double rotateVal = 0.0;
787     if (!ParseJsDouble(info[0], rotateVal)) {
788         return;
789     }
790 
791     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
792     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
793     transform->RotateX(rotateVal, option);
794 }
795 
JsRotateY(const JSCallbackInfo & info)796 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
797 {
798     LOGD("JsRotateX");
799     if (info.Length() < 1) {
800         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
801         return;
802     }
803 
804     double rotateVal = 0.0;
805     if (!ParseJsDouble(info[0], rotateVal)) {
806         return;
807     }
808 
809     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
810     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
811     transform->RotateY(rotateVal, option);
812 }
813 
JsTransform(const JSCallbackInfo & info)814 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
815 {
816     LOGD("JsTransform");
817     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
818     if (!CheckJSCallbackInfo("JsTransform", info, checkList)) {
819         return;
820     }
821     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
822     if (!argsPtrItem || argsPtrItem->IsNull()) {
823         LOGE("Js Parse object failed. argsPtr is null. %{public}s", info[0]->ToString().c_str());
824         return;
825     }
826     auto array = argsPtrItem->GetValue("matrix4x4");
827     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
828     if (!array || array->IsNull() || !array->IsArray() || array->GetArraySize() != matrix4Len) {
829         LOGE("Js Parse object failed, matrix4x4 is null or not Array");
830         return;
831     }
832     std::vector<float> matrix(matrix4Len);
833     for (int32_t i = 0; i < matrix4Len; i++) {
834         double value = 0.0;
835         ParseJsonDouble(array->GetArrayItem(i), value);
836         matrix[i] = static_cast<float>(value);
837     }
838     auto transform = ViewStackProcessor::GetInstance()->GetTransformComponent();
839     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
840     transform->Matrix3d(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7],
841         matrix[8], matrix[9], matrix[10], matrix[11], matrix[12], matrix[13], matrix[14], matrix[15], option);
842 }
843 
JsTransition(const JSCallbackInfo & info)844 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
845 {
846     LOGD("JsTransition");
847     if (info.Length() > 1) {
848         LOGE("Too many arguments");
849         return;
850     }
851     if (info.Length() == 0) {
852         SetDefaultTransition(TransitionType::ALL);
853         return;
854     }
855     if (!info[0]->IsObject()) {
856         LOGE("arg is not Object.");
857         return;
858     }
859     auto transitionArgs = JsonUtil::ParseJsonString(info[0]->ToString());
860     ParseAndSetTransitionOption(transitionArgs);
861 }
862 
ParseAndSetTransitionOption(std::unique_ptr<JsonValue> & transitionArgs)863 void JSViewAbstract::ParseAndSetTransitionOption(std::unique_ptr<JsonValue>& transitionArgs)
864 {
865     TransitionType transitionType = ParseTransitionType(transitionArgs->GetString("type", "All"));
866     bool hasEffect = false;
867     hasEffect = ParseAndSetOpacityTransition(transitionArgs, transitionType) || hasEffect;
868     hasEffect = ParseAndSetTranslateTransition(transitionArgs, transitionType) || hasEffect;
869     hasEffect = ParseAndSetScaleTransition(transitionArgs, transitionType) || hasEffect;
870     hasEffect = ParseAndSetRotateTransition(transitionArgs, transitionType) || hasEffect;
871     if (!hasEffect) {
872         SetDefaultTransition(transitionType);
873     }
874 }
875 
JsWidth(const JSCallbackInfo & info)876 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
877 {
878     if (info.Length() < 1) {
879         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
880         return;
881     }
882 
883     JsWidth(info[0]);
884 }
885 
JsWidth(const JSRef<JSVal> & jsValue)886 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
887 {
888     Dimension value;
889     if (!ParseJsDimensionVp(jsValue, value)) {
890         return false;
891     }
892 
893     if (LessNotEqual(value.Value(), 0.0)) {
894         value.SetValue(0.0);
895     }
896 
897     bool isPercentSize = value.Unit() == DimensionUnit::PERCENT ? true : false;
898     if (isPercentSize) {
899         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
900         auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
901         if (renderComponent) {
902             renderComponent->SetIsPercentSize(isPercentSize);
903         }
904     }
905 
906     auto stack = ViewStackProcessor::GetInstance();
907     auto box = stack->GetBoxComponent();
908     auto option = stack->GetImplicitAnimationOption();
909     if (!stack->IsVisualStateSet()) {
910         box->SetWidth(value, option);
911     } else {
912         box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::WIDTH,
913             AnimatableDimension(value, option), stack->GetVisualState());
914         if (!box->GetStateAttributes()->
915             HasAttribute(BoxStateAttribute::WIDTH, VisualState::NORMAL)) {
916             box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::WIDTH,
917                 AnimatableDimension(box->GetWidth(), option), VisualState::NORMAL);
918         }
919     }
920     return true;
921 }
922 
JsHeight(const JSCallbackInfo & info)923 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
924 {
925     if (info.Length() < 1) {
926         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
927         return;
928     }
929 
930     JsHeight(info[0]);
931 }
932 
JsHeight(const JSRef<JSVal> & jsValue)933 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
934 {
935     Dimension value;
936     if (!ParseJsDimensionVp(jsValue, value)) {
937         return false;
938     }
939 
940     if (LessNotEqual(value.Value(), 0.0)) {
941         value.SetValue(0.0);
942     }
943 
944     bool isPercentSize = value.Unit() == DimensionUnit::PERCENT ? true : false;
945     if (isPercentSize) {
946         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
947         auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
948         if (renderComponent) {
949             renderComponent->SetIsPercentSize(isPercentSize);
950         }
951     }
952 
953     auto stack = ViewStackProcessor::GetInstance();
954     auto box = stack->GetBoxComponent();
955     auto option = stack->GetImplicitAnimationOption();
956     if (!stack->IsVisualStateSet()) {
957         box->SetHeight(value, option);
958     } else {
959         box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::HEIGHT,
960             AnimatableDimension(value, option), stack->GetVisualState());
961         if (!box->GetStateAttributes()->
962             HasAttribute(BoxStateAttribute::HEIGHT, VisualState::NORMAL)) {
963             box->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::HEIGHT,
964                 AnimatableDimension(box->GetHeight(), option), VisualState::NORMAL);
965         }
966     }
967     return true;
968 }
969 
JsResponseRegion(const JSCallbackInfo & info)970 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
971 {
972     if (info.Length() < 1) {
973         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
974         return;
975     }
976 
977     std::vector<DimensionRect> result;
978     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
979         return;
980     }
981 
982     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
983     auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
984     if (renderComponent) {
985         renderComponent->SetResponseRegion(result);
986         renderComponent->MarkResponseRegion(true);
987     }
988     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
989     box->SetResponseRegion(result);
990     box->MarkResponseRegion(true);
991     if (ViewStackProcessor::GetInstance()->HasClickGestureListenerComponent()) {
992         auto click = ViewStackProcessor::GetInstance()->GetClickGestureListenerComponent();
993         click->SetResponseRegion(result);
994         click->MarkResponseRegion(true);
995     }
996     if (ViewStackProcessor::GetInstance()->HasTouchListenerComponent()) {
997         auto touch = ViewStackProcessor::GetInstance()->GetTouchListenerComponent();
998         touch->SetResponseRegion(result);
999         touch->MarkResponseRegion(true);
1000     }
1001 }
1002 
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)1003 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
1004 {
1005     if (!jsValue->IsObject()) {
1006         LOGE("arg is not Object.");
1007         return false;
1008     }
1009 
1010     JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
1011     JSRef<JSVal> x = obj->GetProperty("x");
1012     JSRef<JSVal> y = obj->GetProperty("y");
1013     JSRef<JSVal> width = obj->GetProperty("width");
1014     JSRef<JSVal> height = obj->GetProperty("height");
1015     Dimension xDimen = result.GetOffset().GetX();
1016     Dimension yDimen = result.GetOffset().GetY();
1017     Dimension widthDimen = result.GetWidth();
1018     Dimension heightDimen = result.GetHeight();
1019 
1020     if (ParseJsDimension(x, xDimen, DimensionUnit::VP)) {
1021         auto offset = result.GetOffset();
1022         offset.SetX(xDimen);
1023         result.SetOffset(offset);
1024     }
1025     if (ParseJsDimension(y, yDimen, DimensionUnit::VP)) {
1026         auto offset = result.GetOffset();
1027         offset.SetY(yDimen);
1028         result.SetOffset(offset);
1029     }
1030     if (ParseJsDimension(width, widthDimen, DimensionUnit::VP)) {
1031         if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
1032             return true;
1033         }
1034         result.SetWidth(widthDimen);
1035     }
1036     if (ParseJsDimension(height, heightDimen, DimensionUnit::VP)) {
1037         if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
1038             return true;
1039         }
1040         result.SetHeight(heightDimen);
1041     }
1042     return true;
1043 }
1044 
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)1045 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
1046 {
1047     if (!jsValue->IsArray() && !jsValue->IsObject()) {
1048         LOGE("arg is not array or Object.");
1049         return false;
1050     }
1051 
1052     if (jsValue->IsArray()) {
1053         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
1054         for (size_t i = 0; i < array->Length(); i++) {
1055             Dimension xDimen = Dimension(0.0, DimensionUnit::VP);
1056             Dimension yDimen = Dimension(0.0, DimensionUnit::VP);
1057             Dimension widthDimen = Dimension(1, DimensionUnit::PERCENT);
1058             Dimension heightDimen = Dimension(1, DimensionUnit::PERCENT);
1059             DimensionOffset offsetDimen(xDimen, yDimen);
1060             DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1061             if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
1062                 result.emplace_back(dimenRect);
1063             } else {
1064                 LOGE("Array element is not Object.");
1065                 return false;
1066             }
1067         }
1068         return true;
1069     }
1070 
1071     Dimension xDimen = Dimension(0.0, DimensionUnit::VP);
1072     Dimension yDimen = Dimension(0.0, DimensionUnit::VP);
1073     Dimension widthDimen = Dimension(1, DimensionUnit::PERCENT);
1074     Dimension heightDimen = Dimension(1, DimensionUnit::PERCENT);
1075     DimensionOffset offsetDimen(xDimen, yDimen);
1076     DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1077     if (ParseJsDimensionRect(jsValue, dimenRect)) {
1078         result.emplace_back(dimenRect);
1079         return true;
1080     } else {
1081         LOGE("Array element is not Object.");
1082         return false;
1083     }
1084 }
1085 
JsSize(const JSCallbackInfo & info)1086 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
1087 {
1088     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
1089     if (!CheckJSCallbackInfo("JsSize", info, checkList)) {
1090         return;
1091     }
1092 
1093     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1094     JsWidth(sizeObj->GetProperty("width"));
1095     JsHeight(sizeObj->GetProperty("height"));
1096 }
1097 
JsConstraintSize(const JSCallbackInfo & info)1098 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
1099 {
1100     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
1101     if (!CheckJSCallbackInfo("JsConstraintSize", info, checkList)) {
1102         return;
1103     }
1104 
1105     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
1106     auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1107     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1108 
1109     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
1110     Dimension minWidth;
1111     if (ParseJsDimensionVp(minWidthValue, minWidth)) {
1112         box->SetMinWidth(minWidth);
1113         flexItem->SetMinWidth(minWidth);
1114     }
1115 
1116     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
1117     Dimension maxWidth;
1118     if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
1119         box->SetMaxWidth(maxWidth);
1120         flexItem->SetMaxWidth(maxWidth);
1121     }
1122 
1123     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
1124     Dimension minHeight;
1125     if (ParseJsDimensionVp(minHeightValue, minHeight)) {
1126         box->SetMinHeight(minHeight);
1127         flexItem->SetMinHeight(minHeight);
1128     }
1129 
1130     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
1131     Dimension maxHeight;
1132     if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
1133         box->SetMaxHeight(maxHeight);
1134         flexItem->SetMaxHeight(maxHeight);
1135     }
1136 }
1137 
JsLayoutPriority(const JSCallbackInfo & info)1138 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
1139 {
1140     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER};
1141     if (!CheckJSCallbackInfo("JsLayoutPriority", info, checkList)) {
1142         return;
1143     }
1144 
1145     int32_t priority;
1146     if (info[0]->IsNumber()) {
1147         priority = info[0]->ToNumber<int32_t>();
1148     } else {
1149         priority = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1150     }
1151 
1152     auto flex = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1153     flex->SetDisplayIndex(priority);
1154 }
1155 
JsLayoutWeight(const JSCallbackInfo & info)1156 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
1157 {
1158     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER};
1159     if (!CheckJSCallbackInfo("JsLayoutWeight", info, checkList)) {
1160         return;
1161     }
1162 
1163     int32_t value;
1164     if (info[0]->IsNumber()) {
1165         value = info[0]->ToNumber<int32_t>();
1166     } else {
1167         value = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1168     }
1169 
1170     auto flex = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1171     flex->SetFlexWeight(value);
1172 }
1173 
JsAlign(const JSCallbackInfo & info)1174 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
1175 {
1176     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER};
1177     if (!CheckJSCallbackInfo("JsAlign", info, checkList)) {
1178         return;
1179     }
1180     auto value = info[0]->ToNumber<int32_t>();
1181     Alignment alignment = ParseAlignment(value);
1182     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
1183     box->SetAlignment(alignment);
1184 }
1185 
JsPosition(const JSCallbackInfo & info)1186 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
1187 {
1188     AnimatableDimension x;
1189     AnimatableDimension y;
1190     if (ParseLocationProps(info, x, y)) {
1191         auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1192         flexItemComponent->SetLeft(x);
1193         flexItemComponent->SetTop(y);
1194         flexItemComponent->SetPositionType(PositionType::ABSOLUTE);
1195     }
1196 }
1197 
JsMarkAnchor(const JSCallbackInfo & info)1198 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
1199 {
1200     AnimatableDimension x;
1201     AnimatableDimension y;
1202     if (ParseLocationProps(info, x, y)) {
1203         auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1204         flexItemComponent->SetAnchorX(x);
1205         flexItemComponent->SetAnchorY(y);
1206     }
1207 }
1208 
JsOffset(const JSCallbackInfo & info)1209 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
1210 {
1211     AnimatableDimension x;
1212     AnimatableDimension y;
1213     if (ParseLocationProps(info, x, y)) {
1214         auto flexItemComponent = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1215         flexItemComponent->SetLeft(x);
1216         flexItemComponent->SetTop(y);
1217         flexItemComponent->SetPositionType(PositionType::OFFSET);
1218     }
1219 }
1220 
JsEnabled(const JSCallbackInfo & info)1221 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
1222 {
1223     if (info.Length() < 1) {
1224         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1225         return;
1226     }
1227 
1228     if (!info[0]->IsBoolean()) {
1229         LOGE("arg is not bool.");
1230         return;
1231     }
1232 
1233     auto rootComponent = ViewStackProcessor::GetInstance()->GetRootComponent();
1234     rootComponent->SetDisabledStatus(!(info[0]->ToBoolean()));
1235 }
1236 
JsAspectRatio(const JSCallbackInfo & info)1237 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
1238 {
1239     if (info.Length() < 1) {
1240         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1241         return;
1242     }
1243 
1244     double value = 0.0;
1245     if (!ParseJsDouble(info[0], value)) {
1246         return;
1247     }
1248     auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
1249     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
1250     boxComponent->SetAspectRatio(value, option);
1251 }
1252 
JsOverlay(const JSCallbackInfo & info)1253 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
1254 {
1255     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
1256     if (!CheckJSCallbackInfo("JsOverlay", info, checkList)) {
1257         return;
1258     }
1259 
1260     auto coverageComponent = ViewStackProcessor::GetInstance()->GetCoverageComponent();
1261     std::string text = info[0]->ToString();
1262     coverageComponent->SetTextVal(text);
1263     coverageComponent->SetIsOverLay(true);
1264 
1265     if (info.Length() > 1 && !info[1]->IsNull()) {
1266         JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
1267         JSRef<JSVal> alignVal = optionObj->GetProperty("align");
1268         auto value = alignVal->ToNumber<int32_t>();
1269         Alignment alignment = ParseAlignment(value);
1270         coverageComponent->SetAlignment(alignment);
1271 
1272         JSRef<JSVal> val = optionObj->GetProperty("offset");
1273         if (val->IsObject()) {
1274             JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
1275             JSRef<JSVal> xVal = offsetObj->GetProperty("x");
1276             Dimension x;
1277             if (ParseJsDimensionVp(xVal, x)) {
1278                 coverageComponent->SetX(x);
1279             }
1280             JSRef<JSVal> yVal = offsetObj->GetProperty("y");
1281             Dimension y;
1282             if (ParseJsDimensionVp(yVal, y)) {
1283                 coverageComponent->SetY(y);
1284             }
1285         }
1286     }
1287 }
1288 
ParseAlignment(int32_t align)1289 Alignment JSViewAbstract::ParseAlignment(int32_t align)
1290 {
1291     Alignment alignment = Alignment::CENTER;
1292     switch (align) {
1293         case 0:
1294             alignment = Alignment::TOP_LEFT;
1295             break;
1296         case 1:
1297             alignment = Alignment::TOP_CENTER;
1298             break;
1299         case 2:
1300             alignment = Alignment::TOP_RIGHT;
1301             break;
1302         case 3:
1303             alignment = Alignment::CENTER_LEFT;
1304             break;
1305         case 4:
1306             alignment = Alignment::CENTER;
1307             break;
1308         case 5:
1309             alignment = Alignment::CENTER_RIGHT;
1310             break;
1311         case 6:
1312             alignment = Alignment::BOTTOM_LEFT;
1313             break;
1314         case 7:
1315             alignment = Alignment::BOTTOM_CENTER;
1316             break;
1317         case 8:
1318             alignment = Alignment::BOTTOM_RIGHT;
1319             break;
1320         default:
1321             LOGE("Invaild value for alignment");
1322     }
1323     return alignment;
1324 }
1325 
SetVisibility(int value)1326 void JSViewAbstract::SetVisibility(int value)
1327 {
1328     auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
1329     display->SetVisible(VisibleType(value));
1330 }
1331 
JsFlexBasis(const JSCallbackInfo & info)1332 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
1333 {
1334     if (info.Length() < 1) {
1335         LOGE("JsFlexBasis: The arg is wrong, it is supposed to have at least 1 arguments");
1336         return;
1337     }
1338     Dimension value;
1339     if (!ParseJsDimensionVp(info[0], value)) {
1340         return;
1341     }
1342     auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1343     flexItem->SetFlexBasis(value);
1344 }
1345 
JsFlexGrow(const JSCallbackInfo & info)1346 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
1347 {
1348     if (info.Length() < 1) {
1349         LOGE("JsFlexGrow: The arg is wrong, it is supposed to have at least 1 arguments");
1350         return;
1351     }
1352     double value = 0.0;
1353     if (!ParseJsDouble(info[0], value)) {
1354         return;
1355     }
1356     auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1357     flexItem->SetFlexGrow(value);
1358 }
1359 
JsFlexShrink(const JSCallbackInfo & info)1360 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
1361 {
1362     if (info.Length() < 1) {
1363         LOGE("JsFlexShrink: The arg is wrong, it is supposed to have at least 1 arguments");
1364         return;
1365     }
1366     double value = 0.0;
1367     if (!ParseJsDouble(info[0], value)) {
1368         return;
1369     }
1370     auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1371     flexItem->SetFlexShrink(value);
1372 }
1373 
JsDisplayPriority(const JSCallbackInfo & info)1374 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
1375 {
1376     if (info.Length() < 1) {
1377         LOGE("JsDisplayPriority: The arg is wrong, it is supposed to have at least 1 arguments");
1378         return;
1379     }
1380     double value = 0.0;
1381     if (!ParseJsDouble(info[0], value)) {
1382         return;
1383     }
1384     auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1385     flexItem->SetDisplayIndex(value);
1386 }
1387 
JsSharedTransition(const JSCallbackInfo & info)1388 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
1389 {
1390     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
1391     if (!CheckJSCallbackInfo("JsSharedTransition", info, checkList)) {
1392         return;
1393     }
1394     // id
1395     auto id = info[0]->ToString();
1396     if (id.empty()) {
1397         LOGE("JsSharedTransition: id is empty.");
1398         return;
1399     }
1400     auto sharedTransitionComponent = ViewStackProcessor::GetInstance()->GetSharedTransitionComponent();
1401     sharedTransitionComponent->SetShareId(id);
1402 
1403     // options
1404     if (info.Length() > 1 && info[1]->IsObject()) {
1405         auto optionsArgs = JsonUtil::ParseJsonString(info[1]->ToString());
1406         // default: duration: 1000; if not specify: duration: 0
1407         int32_t duration = 0;
1408         auto durationValue = optionsArgs->GetValue("duration");
1409         if (durationValue && durationValue->IsNumber()) {
1410             duration = durationValue->GetInt();
1411             if (duration < 0) {
1412                 duration = DEFAULT_DURATION;
1413             }
1414         }
1415         // default: delay: 0
1416         auto delay = optionsArgs->GetInt("delay", 0);
1417         if (delay < 0) {
1418             delay = 0;
1419         }
1420         // default: LinearCurve
1421         RefPtr<Curve> curve;
1422         auto curveArgs = optionsArgs->GetValue("curve");
1423         if (curveArgs->IsString()) {
1424             curve = CreateCurve(optionsArgs->GetString("curve", "linear"));
1425         } else if (curveArgs->IsObject()) {
1426             auto curveString = curveArgs->GetValue("__curveString");
1427             if (!curveString) {
1428                 return;
1429             }
1430             curve = CreateCurve(curveString->GetString());
1431         } else {
1432             curve = AceType::MakeRefPtr<LinearCurve>();
1433         }
1434         TweenOption tweenOption;
1435         tweenOption.SetCurve(curve);
1436         tweenOption.SetDuration(static_cast<int32_t>(duration));
1437         tweenOption.SetDelay(static_cast<int32_t>(delay));
1438         // motionPath
1439 
1440         if (optionsArgs->Contains("motionPath")) {
1441             MotionPathOption motionPathOption;
1442             if (ParseMotionPath(optionsArgs->GetValue("motionPath"), motionPathOption)) {
1443                 tweenOption.SetMotioPathOption(motionPathOption);
1444             }
1445         }
1446         // zIndex
1447         int32_t zIndex = 0;
1448         if (optionsArgs->Contains("zIndex")) {
1449             zIndex = optionsArgs->GetInt("zIndex", 0);
1450         }
1451         // type
1452         SharedTransitionEffectType type = SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE;
1453         if (optionsArgs->Contains("type")) {
1454             type = static_cast<SharedTransitionEffectType>(
1455                 optionsArgs->GetInt("type", static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE)));
1456         }
1457         // effect: exchange
1458         auto sharedTransitionEffect =
1459             SharedTransitionEffect::GetSharedTransitionEffect(type, sharedTransitionComponent->GetShareId());
1460         sharedTransitionComponent->SetEffect(sharedTransitionEffect);
1461         sharedTransitionComponent->SetOption(tweenOption);
1462         if (zIndex != 0) {
1463             sharedTransitionComponent->SetZIndex(zIndex);
1464         }
1465     }
1466 }
1467 
JsGeometryTransition(const JSCallbackInfo & info)1468 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
1469 {
1470     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
1471     if (!CheckJSCallbackInfo("JsGeometryTransition", info, checkList)) {
1472         return;
1473     }
1474     // id
1475     auto id = info[0]->ToString();
1476     if (id.empty()) {
1477         LOGE("JsGeometryTransition: id is empty.");
1478         return;
1479     }
1480     auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
1481     boxComponent->SetGeometryTransitionId(id);
1482 }
1483 
JsAlignSelf(const JSCallbackInfo & info)1484 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
1485 {
1486     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER};
1487     if (!CheckJSCallbackInfo("JsAlignSelf", info, checkList)) {
1488         return;
1489     }
1490     auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
1491     auto alignVal = info[0]->ToNumber<int32_t>();
1492 
1493     if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
1494         flexItem->SetAlignSelf((FlexAlign)alignVal);
1495     }
1496 }
1497 
JsBorderColor(const JSCallbackInfo & info)1498 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
1499 {
1500     if (info.Length() < 1) {
1501         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1502         return;
1503     }
1504     Color borderColor;
1505     if (!ParseJsColor(info[0], borderColor)) {
1506         return;
1507     }
1508 
1509     auto stack = ViewStackProcessor::GetInstance();
1510     auto option = stack->GetImplicitAnimationOption();
1511     if (!stack->IsVisualStateSet()) {
1512         BoxComponentHelper::SetBorderColor(GetBackDecoration(), borderColor, option);
1513     } else {
1514         auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1515         boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::BORDER_COLOR,
1516             AnimatableColor(borderColor, option), stack->GetVisualState());
1517         if (!boxComponent->GetStateAttributes()->
1518             HasAttribute(BoxStateAttribute::BORDER_COLOR, VisualState::NORMAL)) {
1519             auto c = BoxComponentHelper::GetBorderColor(GetBackDecoration());
1520             boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::BORDER_COLOR,
1521                 AnimatableColor(c, option), VisualState::NORMAL);
1522         }
1523     }
1524 }
1525 
JsBackgroundColor(const JSCallbackInfo & info)1526 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
1527 {
1528     if (info.Length() < 1) {
1529         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1530         return;
1531     }
1532     Color backgroundColor;
1533     if (!ParseJsColor(info[0], backgroundColor)) {
1534         return;
1535     }
1536 
1537     auto stack = ViewStackProcessor::GetInstance();
1538     auto boxComponent = stack->GetBoxComponent();
1539     auto option = stack->GetImplicitAnimationOption();
1540     if (!stack->IsVisualStateSet()) {
1541         boxComponent->SetColor(backgroundColor, option);
1542     } else {
1543         boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::COLOR,
1544             AnimatableColor(backgroundColor, option), stack->GetVisualState());
1545         if (!boxComponent->GetStateAttributes()->
1546             HasAttribute(BoxStateAttribute::COLOR, VisualState::NORMAL)) {
1547             Color c = boxComponent->GetColor();
1548             boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::COLOR,
1549                 AnimatableColor(c, option), VisualState::NORMAL);
1550         }
1551     }
1552 }
1553 
JsBackgroundImage(const JSCallbackInfo & info)1554 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
1555 {
1556     if (info.Length() < 1) {
1557         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
1558         return;
1559     }
1560 
1561     std::string src;
1562     if (info[0]->IsString()) {
1563         src = info[0]->ToString();
1564     } else if (!ParseJsMedia(info[0], src)) {
1565         LOGE("can not parse image src.");
1566         return;
1567     }
1568 
1569     auto decoration = GetBackDecoration();
1570     if (!decoration) {
1571         LOGE("The decoration is nullptr.");
1572         return;
1573     }
1574     auto image = decoration->GetImage();
1575     if (!image) {
1576         image = AceType::MakeRefPtr<BackgroundImage>();
1577     }
1578 
1579     if (info[0]->IsString()) {
1580         image->SetSrc(src, GetThemeConstants());
1581     } else {
1582         image->SetParsedSrc(src);
1583     }
1584 
1585     int32_t repeatIndex = 0;
1586     if (info.Length() == 2 && info[1]->IsNumber()) {
1587         repeatIndex = info[1]->ToNumber<int32_t>();
1588     }
1589     auto repeat = static_cast<ImageRepeat>(repeatIndex);
1590     image->SetImageRepeat(repeat);
1591     decoration->SetImage(image);
1592 }
1593 
JsBackgroundImageSize(const JSCallbackInfo & info)1594 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
1595 {
1596     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
1597     if (!CheckJSCallbackInfo("JsBackgroungImageSize", info, checkList)) {
1598         return;
1599     }
1600     auto decoration = GetBackDecoration();
1601     if (!decoration) {
1602         LOGE("The decoration is nullptr.");
1603         return;
1604     }
1605     auto image = decoration->GetImage();
1606     if (!image) {
1607         image = AceType::MakeRefPtr<BackgroundImage>();
1608     }
1609     BackgroundImageSize bgImgSize;
1610     if (info[0]->IsNumber()) {
1611         auto sizeType = static_cast<BackgroundImageSizeType>(info[0]->ToNumber<int32_t>());
1612         bgImgSize.SetSizeTypeX(sizeType);
1613         bgImgSize.SetSizeTypeY(sizeType);
1614     } else {
1615         auto imageArgs = JsonUtil::ParseJsonString(info[0]->ToString());
1616         if (imageArgs->IsNull()) {
1617             LOGE("Js Parse failed. imageArgs is null.");
1618             return;
1619         }
1620         Dimension width;
1621         Dimension height;
1622         ParseJsonDimensionVp(imageArgs->GetValue("width"), width);
1623         ParseJsonDimensionVp(imageArgs->GetValue("height"), height);
1624         double valueWidth = width.Value();
1625         double valueHeight = height.Value();
1626         BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
1627         BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
1628         if (width.Unit() == DimensionUnit::PERCENT) {
1629             typeWidth = BackgroundImageSizeType::PERCENT;
1630             valueWidth = width.Value() * FULL_DIMENSION;
1631         }
1632         if (height.Unit() == DimensionUnit::PERCENT) {
1633             typeHeight = BackgroundImageSizeType::PERCENT;
1634             valueHeight = height.Value() * FULL_DIMENSION;
1635         }
1636         bgImgSize.SetSizeTypeX(typeWidth);
1637         bgImgSize.SetSizeValueX(valueWidth);
1638         bgImgSize.SetSizeTypeY(typeHeight);
1639         bgImgSize.SetSizeValueY(valueHeight);
1640     }
1641     image->SetImageSize(bgImgSize);
1642     decoration->SetImage(image);
1643 }
1644 
JsBackgroundImagePosition(const JSCallbackInfo & info)1645 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
1646 {
1647     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT};
1648     if (!CheckJSCallbackInfo("JsBackgroundImagePosition", info, checkList)) {
1649         return;
1650     }
1651     auto decoration = GetBackDecoration();
1652     if (!decoration) {
1653         LOGE("The decoration is nullptr.");
1654         return;
1655     }
1656     auto image = decoration->GetImage();
1657     if (!image) {
1658         image = AceType::MakeRefPtr<BackgroundImage>();
1659     }
1660     BackgroundImagePosition bgImgPosition;
1661     if (info[0]->IsNumber()) {
1662         int32_t align = info[0]->ToNumber<int32_t>();
1663         switch (align) {
1664             case 0:
1665                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1666                     0.0, 0.0, bgImgPosition);
1667                 break;
1668             case 1:
1669                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1670                     HALF_DIMENSION, 0.0, bgImgPosition);
1671                 break;
1672             case 2:
1673                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1674                     FULL_DIMENSION, 0.0, bgImgPosition);
1675                 break;
1676             case 3:
1677                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1678                     0.0, HALF_DIMENSION, bgImgPosition);
1679                 break;
1680             case 4:
1681                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1682                     HALF_DIMENSION, HALF_DIMENSION, bgImgPosition);
1683                 break;
1684             case 5:
1685                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1686                     FULL_DIMENSION, HALF_DIMENSION, bgImgPosition);
1687                 break;
1688             case 6:
1689                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1690                     0.0, FULL_DIMENSION, bgImgPosition);
1691                 break;
1692             case 7:
1693                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1694                     HALF_DIMENSION, FULL_DIMENSION, bgImgPosition);
1695                 break;
1696             case 8:
1697                 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT,
1698                     FULL_DIMENSION, FULL_DIMENSION, bgImgPosition);
1699                 break;
1700             default:
1701                 break;
1702         }
1703     } else {
1704         auto imageArgs = JsonUtil::ParseJsonString(info[0]->ToString());
1705         if (imageArgs->IsNull()) {
1706             LOGE("Js Parse failed. imageArgs is null.");
1707             return;
1708         }
1709         Dimension x;
1710         Dimension y;
1711         ParseJsonDimensionVp(imageArgs->GetValue("x"), x);
1712         ParseJsonDimensionVp(imageArgs->GetValue("y"), y);
1713         double valueX = x.Value();
1714         double valueY = y.Value();
1715         DimensionUnit typeX = DimensionUnit::PX;
1716         DimensionUnit typeY = DimensionUnit::PX;
1717         if (x.Unit() == DimensionUnit::PERCENT) {
1718             valueX = x.Value() * FULL_DIMENSION;
1719             typeX = DimensionUnit::PERCENT;
1720         }
1721         if (y.Unit() == DimensionUnit::PERCENT) {
1722             valueY = y.Value() * FULL_DIMENSION;
1723             typeY = DimensionUnit::PERCENT;
1724         }
1725         SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
1726     }
1727     image->SetImagePosition(bgImgPosition);
1728     decoration->SetImage(image);
1729 }
1730 
JsBindMenu(const JSCallbackInfo & info)1731 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
1732 {
1733     ViewStackProcessor::GetInstance()->GetCoverageComponent();
1734     auto menuComponent = ViewStackProcessor::GetInstance()->GetMenuComponent(true);
1735     if (!menuComponent) {
1736         return;
1737     }
1738     auto click = ViewStackProcessor::GetInstance()->GetBoxComponent();
1739     RefPtr<Gesture> tapGesture = AceType::MakeRefPtr<TapGesture>();
1740     tapGesture->SetOnActionId([weak = WeakPtr<OHOS::Ace::MenuComponent>(menuComponent)](const GestureEvent& info) {
1741         auto refPtr = weak.Upgrade();
1742         if (!refPtr) {
1743             return;
1744         }
1745         auto showDialog = refPtr->GetTargetCallback();
1746         showDialog("BindMenu", info.GetGlobalLocation());
1747     });
1748     click->SetOnClick(tapGesture);
1749     auto menuTheme = GetTheme<SelectTheme>();
1750     menuComponent->SetTheme(menuTheme);
1751 
1752     if (info[0]->IsArray()) {
1753         auto context = info.GetExecutionContext();
1754         auto paramArray = JSRef<JSArray>::Cast(info[0]);
1755         size_t size = paramArray->Length();
1756         for (size_t i = 0; i < size; i++) {
1757             std::string value;
1758             auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
1759             auto menuValue = indexObject->GetProperty("value");
1760             auto menuAction = indexObject->GetProperty("action");
1761             ParseJsString(menuValue, value);
1762             auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(menuAction));
1763 
1764             auto optionTheme = GetTheme<SelectTheme>();
1765             auto optionComponent = AceType::MakeRefPtr<OHOS::Ace::OptionComponent>(optionTheme);
1766             auto textComponent = AceType::MakeRefPtr<OHOS::Ace::TextComponent>(value);
1767 
1768             optionComponent->SetTheme(optionTheme);
1769             optionComponent->SetText(textComponent);
1770             optionComponent->SetValue(value);
1771             optionComponent->SetCustomizedCallback([action, context] {
1772                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
1773                 ACE_SCORING_EVENT("menu.action");
1774                 action->Execute();
1775             });
1776             menuComponent->AppendOption(optionComponent);
1777         }
1778     } else {
1779         JSRef<JSObject> menuObj;
1780         if (info[0]->IsObject()) {
1781             menuObj = JSRef<JSObject>::Cast(info[0]);
1782         } else {
1783             LOGE("No param object.");
1784             return;
1785         }
1786 
1787         auto builder = menuObj->GetProperty("builder");
1788         if (!builder->IsFunction()) {
1789             LOGE("builder param is not a function.");
1790             return;
1791         }
1792         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1793         if (!builderFunc) {
1794             LOGE("builder function is null.");
1795             return;
1796         }
1797         // use another VSP instance while executing the builder function
1798         ScopedViewStackProcessor builderViewStackProcessor;
1799         {
1800             ACE_SCORING_EVENT("menu.builder");
1801             builderFunc->Execute();
1802         }
1803         auto customComponent = ViewStackProcessor::GetInstance()->Finish();
1804         if (!customComponent) {
1805             LOGE("Custom component is null.");
1806             return;
1807         }
1808 
1809         auto optionTheme = GetTheme<SelectTheme>();
1810         auto optionComponent = AceType::MakeRefPtr<OHOS::Ace::OptionComponent>(optionTheme);
1811         optionComponent->SetCustomComponent(customComponent);
1812 
1813         menuComponent->AppendOption(optionComponent);
1814     }
1815 }
1816 
JsPadding(const JSCallbackInfo & info)1817 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
1818 {
1819     ParseMarginOrPadding(info, false);
1820 }
1821 
JsMargin(const JSCallbackInfo & info)1822 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
1823 {
1824     JSViewAbstract::ParseMarginOrPadding(info, true);
1825 }
1826 
ParseMarginOrPadding(const JSCallbackInfo & info,bool isMargin)1827 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, bool isMargin)
1828 {
1829     std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1830         JSCallbackInfoType::OBJECT };
1831     if (!CheckJSCallbackInfo("ParseMarginOrPadding", info, checkList)) {
1832         return;
1833     }
1834 
1835     if (info[0]->IsObject()) {
1836         auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1837         if (!argsPtrItem || argsPtrItem->IsNull()) {
1838             LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
1839             return;
1840         }
1841         if (argsPtrItem->Contains("top") || argsPtrItem->Contains("bottom") || argsPtrItem->Contains("left") ||
1842             argsPtrItem->Contains("right")) {
1843             Dimension topDimen = Dimension(0.0, DimensionUnit::VP);
1844             Dimension bottomDimen = Dimension(0.0, DimensionUnit::VP);
1845             Dimension leftDimen = Dimension(0.0, DimensionUnit::VP);
1846             Dimension rightDimen = Dimension(0.0, DimensionUnit::VP);
1847             ParseJsonDimensionVp(argsPtrItem->GetValue("top"), topDimen);
1848             ParseJsonDimensionVp(argsPtrItem->GetValue("bottom"), bottomDimen);
1849             ParseJsonDimensionVp(argsPtrItem->GetValue("left"), leftDimen);
1850             ParseJsonDimensionVp(argsPtrItem->GetValue("right"), rightDimen);
1851             if (isMargin) {
1852                 SetMargins(topDimen, bottomDimen, leftDimen, rightDimen);
1853             } else {
1854                 SetPaddings(topDimen, bottomDimen, leftDimen, rightDimen);
1855             }
1856             return;
1857         }
1858     }
1859     AnimatableDimension length;
1860     if (!ParseJsAnimatableDimensionVp(info[0], length)) {
1861         return;
1862     }
1863     if (isMargin) {
1864         SetMargin(length);
1865     } else {
1866         SetPadding(length);
1867     }
1868 }
1869 
JsBorder(const JSCallbackInfo & info)1870 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
1871 {
1872     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
1873     if (!CheckJSCallbackInfo("JsBorder", info, checkList)) {
1874         return;
1875     }
1876     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
1877     if (!argsPtrItem || argsPtrItem->IsNull()) {
1878         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
1879         info.ReturnSelf();
1880         return;
1881     }
1882 
1883     auto stack = ViewStackProcessor::GetInstance();
1884     AnimationOption option = stack->GetImplicitAnimationOption();
1885     auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1886 
1887     Dimension width;
1888     if (argsPtrItem->Contains("width") && ParseJsonDimensionVp(argsPtrItem->GetValue("width"), width)) {
1889         if (!stack->IsVisualStateSet()) {
1890             BoxComponentHelper::SetBorderWidth(GetBackDecoration(), width, option);
1891         } else {
1892             boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>
1893                 (BoxStateAttribute::BORDER_WIDTH, AnimatableDimension(width, option), stack->GetVisualState());
1894             if (!boxComponent->GetStateAttributes()->
1895                 HasAttribute(BoxStateAttribute::BORDER_WIDTH, VisualState::NORMAL)) {
1896                 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_WIDTH,
1897                     AnimatableDimension(BoxComponentHelper::GetBorderWidth(GetBackDecoration()), option),
1898                     VisualState::NORMAL);
1899             }
1900         }
1901     }
1902     Color color;
1903     if (argsPtrItem->Contains("color") && ParseJsonColor(argsPtrItem->GetValue("color"), color)) {
1904         if (!stack->IsVisualStateSet()) {
1905             BoxComponentHelper::SetBorderColor(GetBackDecoration(), color, option);
1906         } else {
1907             boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>(BoxStateAttribute::BORDER_COLOR,
1908                 AnimatableColor(color, option), stack->GetVisualState());
1909             if (!boxComponent->GetStateAttributes()->
1910                 HasAttribute(BoxStateAttribute::BORDER_COLOR, VisualState::NORMAL)) {
1911                 Color c = BoxComponentHelper::GetBorderColor(GetBackDecoration());
1912                 boxComponent->GetStateAttributes()->AddAttribute<AnimatableColor>
1913                     (BoxStateAttribute::BORDER_COLOR, AnimatableColor(c, option), VisualState::NORMAL);
1914             }
1915         }
1916     }
1917     Dimension radius;
1918     if (argsPtrItem->Contains("radius") && ParseJsonDimensionVp(argsPtrItem->GetValue("radius"), radius)) {
1919         if (!stack->IsVisualStateSet()) {
1920             BoxComponentHelper::SetBorderRadius(GetBackDecoration(), radius, option);
1921         } else {
1922             boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1923                 AnimatableDimension(radius, option), stack->GetVisualState());
1924             if (!boxComponent->GetStateAttributes()->
1925                 HasAttribute(BoxStateAttribute::BORDER_RADIUS, VisualState::NORMAL)) {
1926                 boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1927                     AnimatableDimension(BoxComponentHelper::GetBorderRadius(GetBackDecoration()).GetX(), option),
1928                     VisualState::NORMAL);
1929             }
1930         }
1931     }
1932     if (argsPtrItem->Contains("style")) {
1933         auto borderStyle = argsPtrItem->GetInt("style", static_cast<int32_t>(BorderStyle::SOLID));
1934         SetBorderStyle(borderStyle);
1935     }
1936     info.ReturnSelf();
1937 }
1938 
JsBorderWidth(const JSCallbackInfo & info)1939 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
1940 {
1941     if (info.Length() < 1) {
1942         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1943         return;
1944     }
1945     Dimension borderWidth;
1946     if (!ParseJsDimensionVp(info[0], borderWidth)) {
1947         return;
1948     }
1949     auto stack = ViewStackProcessor::GetInstance();
1950     AnimationOption option = stack->GetImplicitAnimationOption();
1951     if (!ViewStackProcessor::GetInstance()->IsVisualStateSet()) {
1952         BoxComponentHelper::SetBorderWidth(GetBackDecoration(), borderWidth, option);
1953     } else {
1954         auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1955         boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>
1956             (BoxStateAttribute::BORDER_WIDTH, AnimatableDimension(borderWidth, option), stack->GetVisualState());
1957         if (!boxComponent->GetStateAttributes()->
1958             HasAttribute(BoxStateAttribute::BORDER_WIDTH, VisualState::NORMAL)) {
1959             boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(
1960                 BoxStateAttribute::BORDER_WIDTH,
1961                 AnimatableDimension(BoxComponentHelper::GetBorderWidth(GetBackDecoration()), option),
1962                 VisualState::NORMAL);
1963         }
1964     }
1965 }
1966 
JsBorderRadius(const JSCallbackInfo & info)1967 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
1968 {
1969     if (info.Length() < 1) {
1970         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1971         return;
1972     }
1973     Dimension borderRadius;
1974     if (!ParseJsDimensionVp(info[0], borderRadius)) {
1975         return;
1976     }
1977     auto stack = ViewStackProcessor::GetInstance();
1978     AnimationOption option = stack->GetImplicitAnimationOption();
1979     if (!stack->IsVisualStateSet()) {
1980         SetBorderRadius(borderRadius, option);
1981     } else {
1982         auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
1983         boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1984             AnimatableDimension(borderRadius, option), stack->GetVisualState());
1985         if (!boxComponent->GetStateAttributes()->
1986             HasAttribute(BoxStateAttribute::BORDER_RADIUS, VisualState::NORMAL)) {
1987             boxComponent->GetStateAttributes()->AddAttribute<AnimatableDimension>(BoxStateAttribute::BORDER_RADIUS,
1988             AnimatableDimension(
1989                 BoxComponentHelper::GetBorderRadius(GetBackDecoration()).GetX(), option), VisualState::NORMAL);
1990         }
1991     }
1992 }
1993 
JsBlur(const JSCallbackInfo & info)1994 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
1995 {
1996     if (info.Length() < 1) {
1997         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
1998         return;
1999     }
2000 
2001     double blur = 0.0;
2002     if (!ParseJsDouble(info[0], blur)) {
2003         return;
2004     }
2005     SetBlur(blur);
2006     info.SetReturnValue(info.This());
2007 }
2008 
JsColorBlend(const JSCallbackInfo & info)2009 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
2010 {
2011     if (info.Length() < 1) {
2012         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
2013         return;
2014     }
2015     Color colorBlend;
2016     if (!ParseJsColor(info[0], colorBlend)) {
2017         return;
2018     }
2019     SetColorBlend(colorBlend);
2020     info.SetReturnValue(info.This());
2021 }
2022 
JsBackdropBlur(const JSCallbackInfo & info)2023 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
2024 {
2025     if (info.Length() < 1) {
2026         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
2027         return;
2028     }
2029 
2030     double blur = 0.0;
2031     if (!ParseJsDouble(info[0], blur)) {
2032         return;
2033     }
2034     SetBackdropBlur(blur);
2035     info.SetReturnValue(info.This());
2036 }
2037 
JsWindowBlur(const JSCallbackInfo & info)2038 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
2039 {
2040     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2041     if (!CheckJSCallbackInfo("JsWindowBlur", info, checkList)) {
2042         return;
2043     }
2044 
2045     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2046     if (!argsPtrItem || argsPtrItem->IsNull()) {
2047         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2048         return;
2049     }
2050     double progress = 0.0;
2051     ParseJsonDouble(argsPtrItem->GetValue("percent"), progress);
2052     auto style = argsPtrItem->GetInt("style", static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
2053 
2054     progress = std::clamp(progress, 0.0, 1.0);
2055     style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
2056         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
2057 
2058     SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
2059     info.SetReturnValue(info.This());
2060 }
2061 
ParseJsDimension(const JSRef<JSVal> & jsValue,Dimension & result,DimensionUnit defaultUnit)2062 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, Dimension& result, DimensionUnit defaultUnit)
2063 {
2064     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
2065         LOGE("arg is not Number, String or Object.");
2066         return false;
2067     }
2068 
2069     if (jsValue->IsNumber()) {
2070         result = Dimension(jsValue->ToNumber<double>(), defaultUnit);
2071         return true;
2072     }
2073     if (jsValue->IsString()) {
2074         result = StringUtils::StringToDimensionWithUnit(jsValue->ToString(), defaultUnit);
2075         return true;
2076     }
2077     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2078     JSRef<JSVal> resId = jsObj->GetProperty("id");
2079     if (!resId->IsNumber()) {
2080         LOGW("resId is not number");
2081         return false;
2082     }
2083 
2084     auto themeConstants = GetThemeConstants();
2085     if (!themeConstants) {
2086         LOGE("themeConstants is nullptr");
2087         return false;
2088     }
2089     result = themeConstants->GetDimension(resId->ToNumber<uint32_t>());
2090     return true;
2091 }
2092 
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,Dimension & result)2093 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, Dimension& result)
2094 {
2095     // 'vp' -> the value varies with piexl density of device.
2096     return ParseJsDimension(jsValue, result, DimensionUnit::VP);
2097 }
2098 
ParseJsAnimatableDimensionVp(const JSRef<JSVal> & jsValue,AnimatableDimension & result)2099 bool JSViewAbstract::ParseJsAnimatableDimensionVp(const JSRef<JSVal>& jsValue, AnimatableDimension& result)
2100 {
2101     if (ParseJsDimensionVp(jsValue, result)) {
2102         AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
2103         result.SetAnimationOption(option);
2104         return true;
2105     }
2106     return false;
2107 }
2108 
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,Dimension & result)2109 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, Dimension& result)
2110 {
2111     // the 'fp' unit is used for text secnes.
2112     return ParseJsDimension(jsValue, result, DimensionUnit::FP);
2113 }
2114 
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,Dimension & result)2115 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, Dimension& result)
2116 {
2117     return ParseJsDimension(jsValue, result, DimensionUnit::PX);
2118 }
2119 
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)2120 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
2121 {
2122     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
2123         LOGE("arg is not Number, String or Object.");
2124         return false;
2125     }
2126     if (jsValue->IsNumber()) {
2127         result = jsValue->ToNumber<double>();
2128         return true;
2129     }
2130     if (jsValue->IsString()) {
2131         return StringUtils::StringToDouble(jsValue->ToString(), result);
2132     }
2133     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2134     JSRef<JSVal> resId = jsObj->GetProperty("id");
2135     if (!resId->IsNumber()) {
2136         LOGW("resId is not number");
2137         return false;
2138     }
2139 
2140     auto themeConstants = GetThemeConstants();
2141     if (!themeConstants) {
2142         LOGW("themeConstants is nullptr");
2143         return false;
2144     }
2145     result = themeConstants->GetDouble(resId->ToNumber<uint32_t>());
2146     return true;
2147 }
2148 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)2149 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
2150 {
2151     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
2152         LOGE("arg is not Number, String or Object.");
2153         return false;
2154     }
2155     if (jsValue->IsNumber()) {
2156         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
2157         return true;
2158     }
2159     if (jsValue->IsString()) {
2160         result = Color::FromString(jsValue->ToString());
2161         return true;
2162     }
2163     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2164     JSRef<JSVal> resId = jsObj->GetProperty("id");
2165     if (!resId->IsNumber()) {
2166         LOGW("resId is not number");
2167         return false;
2168     }
2169 
2170     auto themeConstants = GetThemeConstants();
2171     if (!themeConstants) {
2172         LOGW("themeConstants is nullptr");
2173         return false;
2174     }
2175     result = themeConstants->GetColor(resId->ToNumber<uint32_t>());
2176     return true;
2177 }
2178 
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)2179 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
2180 {
2181     result.clear();
2182     if (!jsValue->IsString() && !jsValue->IsObject()) {
2183         LOGE("arg is not String or Object.");
2184         return false;
2185     }
2186     if (jsValue->IsString()) {
2187         result = ConvertStrToFontFamilies(jsValue->ToString());
2188         return true;
2189     }
2190     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2191     JSRef<JSVal> resId = jsObj->GetProperty("id");
2192     if (!resId->IsNumber()) {
2193         LOGW("resId is not number");
2194         return false;
2195     }
2196 
2197     auto themeConstants = GetThemeConstants();
2198     if (!themeConstants) {
2199         LOGW("themeConstants is nullptr");
2200         return false;
2201     }
2202     result.emplace_back(themeConstants->GetString(resId->ToNumber<uint32_t>()));
2203     return true;
2204 }
2205 
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)2206 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
2207 {
2208     if (!jsValue->IsString() && !jsValue->IsObject()) {
2209         LOGE("arg is not String or Object.");
2210         return false;
2211     }
2212 
2213     if (jsValue->IsString()) {
2214         LOGD("jsValue->IsString()");
2215         result = jsValue->ToString();
2216         return true;
2217     }
2218 
2219     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2220     JSRef<JSVal> type = jsObj->GetProperty("type");
2221     if (!type->IsNumber()) {
2222         LOGW("type is not number");
2223         return false;
2224     }
2225 
2226     JSRef<JSVal> resId = jsObj->GetProperty("id");
2227     if (!resId->IsNumber()) {
2228         LOGW("resId is not number");
2229         return false;
2230     }
2231 
2232     auto themeConstants = GetThemeConstants();
2233     if (!themeConstants) {
2234         LOGW("themeConstants is nullptr");
2235         return false;
2236     }
2237 
2238     JSRef<JSVal> args = jsObj->GetProperty("params");
2239     if (!args->IsArray()) {
2240         LOGW("args is not array");
2241         return false;
2242     }
2243 
2244     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
2245     if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRING)) {
2246         auto originStr = themeConstants->GetString(resId->ToNumber<uint32_t>());
2247         ReplaceHolder(originStr, params, 0);
2248         result = originStr;
2249     } else if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::PLURAL)) {
2250         auto countJsVal = params->GetValueAt(0);
2251         int count = 0;
2252         if (!countJsVal->IsNumber()) {
2253             LOGW("pluralString, pluralnumber is not number");
2254             return false;
2255         }
2256         count = countJsVal->ToNumber<int>();
2257         auto pluralStr = themeConstants->GetPluralString(resId->ToNumber<uint32_t>(), count);
2258         ReplaceHolder(pluralStr, params, 1);
2259         result = pluralStr;
2260     } else {
2261         return false;
2262     }
2263 
2264     return true;
2265 }
2266 
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)2267 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
2268 {
2269     if (!jsValue->IsObject() && !jsValue->IsString()) {
2270         LOGE("arg is not Object and String.");
2271         return false;
2272     }
2273     if (jsValue->IsString()) {
2274         result = jsValue->ToString();
2275         return true;
2276     }
2277     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2278     JSRef<JSVal> type = jsObj->GetProperty("type");
2279     JSRef<JSVal> resId = jsObj->GetProperty("id");
2280     if (!resId->IsNull() && !type->IsNull() && type->IsNumber() && resId->IsNumber()) {
2281         auto themeConstants = GetThemeConstants();
2282         if (!themeConstants) {
2283             LOGW("themeConstants is nullptr");
2284             return false;
2285         }
2286         auto typeInteger = type->ToNumber<int32_t>();
2287         if (typeInteger == static_cast<int>(ResourceType::MEDIA)) {
2288             result = themeConstants->GetMediaPath(resId->ToNumber<uint32_t>());
2289             return true;
2290         }
2291         if (typeInteger == static_cast<int>(ResourceType::RAWFILE)) {
2292             JSRef<JSVal> args = jsObj->GetProperty("params");
2293             if (!args->IsArray()) {
2294                 LOGW("args is not Array");
2295                 return false;
2296             }
2297             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
2298             auto fileName = params->GetValueAt(0);
2299             if (!fileName->IsString()) {
2300                 LOGW("fileName is not String");
2301                 return false;
2302             }
2303             result = themeConstants->GetRawfile(fileName->ToString());
2304             return true;
2305         }
2306         LOGE("JSImage::Create ParseJsMedia type is wrong");
2307         return false;
2308     }
2309     LOGI("input value is not string or number, using PixelMap");
2310     return false;
2311 }
2312 
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)2313 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
2314 {
2315     if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
2316         LOGE("arg is not bool or Object.");
2317         return false;
2318     }
2319 
2320     if (jsValue->IsBoolean()) {
2321         LOGD("jsValue->IsBoolean()");
2322         result = jsValue->ToBoolean();
2323         return true;
2324     }
2325 
2326     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2327     JSRef<JSVal> type = jsObj->GetProperty("type");
2328     if (!type->IsNumber()) {
2329         LOGW("type is not number");
2330         return false;
2331     }
2332 
2333     JSRef<JSVal> resId = jsObj->GetProperty("id");
2334     if (!resId->IsNumber()) {
2335         LOGW("resId is not number");
2336         return false;
2337     }
2338 
2339     auto themeConstants = GetThemeConstants();
2340     if (!themeConstants) {
2341         LOGW("themeConstants is nullptr");
2342         return false;
2343     }
2344 
2345     if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::BOOLEAN)) {
2346         result = themeConstants->GetBoolean(resId->ToNumber<uint32_t>());
2347         return true;
2348     } else {
2349         return false;
2350     }
2351 }
2352 
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)2353 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
2354 {
2355     if (!jsValue->IsNumber() && !jsValue->IsObject()) {
2356         LOGE("arg is not number or Object.");
2357         return false;
2358     }
2359 
2360     if (jsValue->IsNumber()) {
2361         LOGD("jsValue->IsNumber()");
2362         result = jsValue->ToNumber<uint32_t>();
2363         return true;
2364     }
2365 
2366     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2367     JSRef<JSVal> type = jsObj->GetProperty("type");
2368     if (!type->IsNumber()) {
2369         LOGW("type is not number");
2370         return false;
2371     }
2372 
2373     JSRef<JSVal> resId = jsObj->GetProperty("id");
2374     if (!resId->IsNumber()) {
2375         LOGW("resId is not number");
2376         return false;
2377     }
2378 
2379     auto themeConstants = GetThemeConstants();
2380     if (!themeConstants) {
2381         LOGW("themeConstants is nullptr");
2382         return false;
2383     }
2384 
2385     if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTEGER)) {
2386         result = static_cast<uint32_t>(themeConstants->GetInt(resId->ToNumber<uint32_t>()));
2387         return true;
2388     } else {
2389         return false;
2390     }
2391 }
2392 
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)2393 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
2394 {
2395     if (!jsValue->IsArray() && !jsValue->IsObject()) {
2396         LOGE("arg is not array or Object.");
2397         return false;
2398     }
2399 
2400     if (jsValue->IsArray()) {
2401         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2402         for (size_t i = 0; i < array->Length(); i++) {
2403             JSRef<JSVal> value = array->GetValueAt(i);
2404             if (value->IsNumber()) {
2405                 result.emplace_back(value->ToNumber<uint32_t>());
2406             } else if (value->IsObject()) {
2407                 uint32_t singleResInt;
2408                 if (ParseJsInteger(value, singleResInt)) {
2409                     result.emplace_back(singleResInt);
2410                 } else {
2411                     return false;
2412                 }
2413             } else {
2414                 return false;
2415             }
2416         }
2417         return true;
2418     }
2419 
2420     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2421     JSRef<JSVal> type = jsObj->GetProperty("type");
2422     if (!type->IsNumber()) {
2423         LOGW("type is not number");
2424         return false;
2425     }
2426 
2427     JSRef<JSVal> resId = jsObj->GetProperty("id");
2428     if (!resId->IsNumber()) {
2429         LOGW("resId is not number");
2430         return false;
2431     }
2432 
2433     auto themeConstants = GetThemeConstants();
2434     if (!themeConstants) {
2435         LOGW("themeConstants is nullptr");
2436         return false;
2437     }
2438 
2439     if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::INTARRAY)) {
2440         result = themeConstants->GetIntArray(resId->ToNumber<uint32_t>());
2441         return true;
2442     } else {
2443         return false;
2444     }
2445 }
2446 
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)2447 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
2448 {
2449     if (!jsValue->IsArray() && !jsValue->IsObject()) {
2450         LOGE("arg is not array or Object.");
2451         return false;
2452     }
2453 
2454     if (jsValue->IsArray()) {
2455         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2456         for (size_t i = 0; i < array->Length(); i++) {
2457             JSRef<JSVal> value = array->GetValueAt(i);
2458             if (value->IsString()) {
2459                 result.emplace_back(value->ToString());
2460             } else if (value->IsObject()) {
2461                 std::string singleResStr;
2462                 if (ParseJsString(value, singleResStr)) {
2463                     result.emplace_back(singleResStr);
2464                 } else {
2465                     return false;
2466                 }
2467             } else {
2468                 return false;
2469             }
2470         }
2471         return true;
2472     }
2473 
2474     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
2475     JSRef<JSVal> type = jsObj->GetProperty("type");
2476     if (!type->IsNumber()) {
2477         LOGW("type is not number");
2478         return false;
2479     }
2480 
2481     JSRef<JSVal> resId = jsObj->GetProperty("id");
2482     if (!resId->IsNumber()) {
2483         LOGW("resId is not number");
2484         return false;
2485     }
2486 
2487     auto themeConstants = GetThemeConstants();
2488     if (!themeConstants) {
2489         LOGW("themeConstants is nullptr");
2490         return false;
2491     }
2492 
2493     if (type->ToNumber<uint32_t>() == static_cast<uint32_t>(ResourceType::STRARRAY)) {
2494         result = themeConstants->GetStringArray(resId->ToNumber<uint32_t>());
2495         return true;
2496     } else {
2497         return false;
2498     }
2499 }
2500 
ParseSize(const JSCallbackInfo & info)2501 std::pair<Dimension, Dimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
2502 {
2503     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2504     if (!CheckJSCallbackInfo("ParseSize", info, checkList)) {
2505         return std::pair<Dimension, Dimension>();
2506     }
2507     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2508     if (!argsPtrItem || argsPtrItem->IsNull()) {
2509         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2510         info.SetReturnValue(info.This());
2511         return std::pair<Dimension, Dimension>();
2512     }
2513     Dimension width;
2514     Dimension height;
2515     if (!ParseJsonDimensionVp(argsPtrItem->GetValue("width"), width) ||
2516         !ParseJsonDimensionVp(argsPtrItem->GetValue("height"), height)) {
2517         return std::pair<Dimension, Dimension>();
2518     }
2519     LOGD("JsSize width = %lf unit = %d, height = %lf unit = %d", width.Value(), width.Unit(), height.Value(),
2520         height.Unit());
2521     info.SetReturnValue(info.This());
2522     return std::pair<Dimension, Dimension>(width, height);
2523 }
2524 
JsUseAlign(const JSCallbackInfo & info)2525 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
2526 {
2527     if (info.Length() < 2) {
2528         LOGE("The arg is wrong, it is supposed to have atleast 2 arguments");
2529         return;
2530     }
2531 
2532     if (!info[0]->IsObject() && !info[1]->IsObject()) {
2533         LOGE("arg is not IsObject.");
2534         return;
2535     }
2536 
2537     AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
2538     if (declaration == nullptr) {
2539         LOGE("declaration is nullptr");
2540         return;
2541     }
2542 
2543     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
2544     JSRef<JSVal> side = obj->GetProperty("side");
2545     JSRef<JSVal> offset = obj->GetProperty("offset");
2546 
2547     if (!side->IsNumber()) {
2548         LOGE("side is not Number [%s]", side->ToString().c_str());
2549         return;
2550     }
2551 
2552     auto sideValue = side->ToNumber<int32_t>();
2553 
2554     if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
2555         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
2556             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
2557             LOGE("side should be Edge.Start Edge.Middle or Edge.End with HorizontalAlignDeclaration");
2558             return;
2559         }
2560     } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
2561         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
2562             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
2563             LOGE("side should be Edge.Top Edge.Center Edge.Bottom or Edge.Baseline with VerticalAlignDeclaration");
2564             return;
2565         }
2566     }
2567     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2568     box->SetAlignDeclarationPtr(declaration);
2569     box->SetUseAlignSide(static_cast<AlignDeclaration::Edge>(sideValue));
2570     Dimension offsetDimension;
2571     if (ParseJsDimensionVp(offset, offsetDimension)) {
2572         box->SetUseAlignOffset(offsetDimension);
2573     }
2574 }
2575 
JsGridSpan(const JSCallbackInfo & info)2576 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
2577 {
2578     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::NUMBER};
2579     if (!CheckJSCallbackInfo("JsGridSpan", info, checkList)) {
2580         return;
2581     }
2582     auto gridContainerInfo = JSGridContainer::GetContainer();
2583     if (gridContainerInfo != nullptr) {
2584         auto span = info[0]->ToNumber<uint32_t>();
2585         auto builder = ViewStackProcessor::GetInstance()->GetBoxComponent()->GetGridColumnInfoBuilder();
2586         builder->SetParent(gridContainerInfo);
2587         builder->SetColumns(span);
2588     }
2589 }
2590 
JsGridOffset(const JSCallbackInfo & info)2591 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
2592 {
2593     if (info.Length() < 1) {
2594         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2595         return;
2596     }
2597 
2598     auto gridContainerInfo = JSGridContainer::GetContainer();
2599     if (info[0]->IsNumber() && gridContainerInfo != nullptr) {
2600         auto builder = ViewStackProcessor::GetInstance()->GetBoxComponent()->GetGridColumnInfoBuilder();
2601         builder->SetParent(gridContainerInfo);
2602         int32_t offset = info[0]->ToNumber<int32_t>();
2603         builder->SetOffset(offset);
2604     }
2605 }
2606 
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)2607 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
2608 {
2609     // {lg: 4}
2610     if (val->IsNumber()) {
2611         span = val->ToNumber<uint32_t>();
2612         return true;
2613     }
2614 
2615     if (!val->IsObject()) {
2616         LOGE("The argument is not object or number.");
2617         return false;
2618     }
2619 
2620     // {lg: {span: 1, offset: 2}}
2621     JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
2622     span = obj->GetProperty("span")->ToNumber<uint32_t>();
2623     offset = obj->GetProperty("offset")->ToNumber<int32_t>();
2624     return true;
2625 }
2626 
JsUseSizeType(const JSCallbackInfo & info)2627 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
2628 {
2629     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2630     if (!CheckJSCallbackInfo("JsUseSizeType", info, checkList)) {
2631         return;
2632     }
2633     auto gridContainerInfo = JSGridContainer::GetContainer();
2634     if (gridContainerInfo == nullptr) {
2635         LOGE("No valid grid container.");
2636         return;
2637     }
2638     auto builder = ViewStackProcessor::GetInstance()->GetBoxComponent()->GetGridColumnInfoBuilder();
2639     builder->SetParent(gridContainerInfo);
2640 
2641     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
2642     // keys order must be strictly refer to GridSizeType
2643     const char* keys[] = { "", "xs", "sm", "md", "lg" };
2644     for (uint32_t i = 1; i < sizeof(keys) / sizeof(const char*); i++) {
2645         JSRef<JSVal> val = sizeObj->GetProperty(keys[i]);
2646         if (val->IsNull() || val->IsEmpty()) {
2647             continue;
2648         }
2649         uint32_t span = 0;
2650         int32_t offset = 0;
2651         if (ParseSpanAndOffset(val, span, offset)) {
2652             builder->SetSizeColumn(static_cast<GridSizeType>(i), span);
2653             builder->SetOffset(offset, static_cast<GridSizeType>(i));
2654         }
2655     }
2656 }
2657 
JsZIndex(const JSCallbackInfo & info)2658 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
2659 {
2660     if (info.Length() < 1) {
2661         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2662         return;
2663     }
2664 
2665     int zIndex = 0;
2666     if (info[0]->IsNumber()) {
2667         zIndex = info[0]->ToNumber<int>();
2668     }
2669     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
2670     auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
2671     if (renderComponent) {
2672         renderComponent->SetZIndex(zIndex);
2673     }
2674 }
2675 
Pop()2676 void JSViewAbstract::Pop()
2677 {
2678     ViewStackProcessor::GetInstance()->Pop();
2679 }
2680 
JsOnDragStart(const JSCallbackInfo & info)2681 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
2682 {
2683     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2684     if (!CheckJSCallbackInfo("JsOnDragStart", info, checkList)) {
2685         return;
2686     }
2687 
2688     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2689     auto onDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc)](
2690                         const RefPtr<DragEvent>& info, const std::string &extraParams) -> DragItemInfo {
2691         DragItemInfo itemInfo;
2692         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, itemInfo);
2693 
2694         auto ret = func->Execute(info, extraParams);
2695         if (!ret->IsObject()) {
2696             LOGE("builder param is not an object.");
2697             return itemInfo;
2698         }
2699         auto componnet = ParseDragItemComponent(ret);
2700         if (componnet) {
2701             LOGI("use custom builder param.");
2702             itemInfo.customComponent = componnet;
2703             return itemInfo;
2704         }
2705 
2706         auto builderObj = JSRef<JSObject>::Cast(ret);
2707 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
2708         auto pixmap = builderObj->GetProperty("pixelMap");
2709         itemInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
2710 #endif
2711         auto extarInfo = builderObj->GetProperty("extraInfo");
2712         ParseJsString(extarInfo, itemInfo.extraInfo);
2713         auto component = ParseDragItemComponent(builderObj->GetProperty("builder"));
2714         itemInfo.customComponent = component;
2715         return itemInfo;
2716     };
2717     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2718     box->SetOnDragStartId(onDragStartId);
2719 }
2720 
ParseDragItemComponent(const JSRef<JSVal> & info)2721 RefPtr<Component> JSViewAbstract::ParseDragItemComponent(const JSRef<JSVal>& info)
2722 {
2723     JSRef<JSVal> builder;
2724     if (info->IsObject()) {
2725         auto builderObj = JSRef<JSObject>::Cast(info);
2726         builder = builderObj->GetProperty("builder");
2727     } else if (info->IsFunction()) {
2728         builder = info;
2729     } else {
2730         return nullptr;
2731     }
2732     if (!builder->IsFunction()) {
2733         return nullptr;
2734     }
2735     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2736     if (!builderFunc) {
2737         return nullptr;
2738     }
2739     // use another VSP instance while executing the builder function
2740     ScopedViewStackProcessor builderViewStackProcessor;
2741     {
2742         ACE_SCORING_EVENT("onDragStart.builder");
2743         builderFunc->Execute();
2744     }
2745     auto component = ViewStackProcessor::GetInstance()->Finish();
2746     if (!component) {
2747         LOGE("Custom component is null.");
2748     }
2749     return component;
2750 }
2751 
JsOnDragEnter(const JSCallbackInfo & info)2752 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
2753 {
2754     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2755     if (!CheckJSCallbackInfo("JsOnDragEnter", info, checkList)) {
2756         return;
2757     }
2758     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2759     auto onDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
2760                             const RefPtr<DragEvent>& info, const std::string &extraParams) {
2761         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2762         ACE_SCORING_EVENT("onDragEnter");
2763         func->Execute(info, extraParams);
2764     };
2765     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2766     box->SetOnDragEnterId(onDragEnterId);
2767 }
2768 
JsOnDragMove(const JSCallbackInfo & info)2769 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
2770 {
2771     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2772     if (!CheckJSCallbackInfo("JsOnDragMove", info, checkList)) {
2773         return;
2774     }
2775     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2776     auto onDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
2777                             const RefPtr<DragEvent>& info, const std::string &extraParams) {
2778         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2779         ACE_SCORING_EVENT("onDragMove");
2780         func->Execute(info, extraParams);
2781     };
2782     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2783     box->SetOnDragMoveId(onDragMoveId);
2784 }
2785 
JsOnDragLeave(const JSCallbackInfo & info)2786 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
2787 {
2788     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2789     if (!CheckJSCallbackInfo("JsOnDragLeave", info, checkList)) {
2790         return;
2791     }
2792     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2793     auto onDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
2794                             const RefPtr<DragEvent>& info, const std::string &extraParams) {
2795         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2796         ACE_SCORING_EVENT("onDragLeave");
2797         func->Execute(info, extraParams);
2798     };
2799     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2800     box->SetOnDragLeaveId(onDragLeaveId);
2801 }
2802 
JsOnDrop(const JSCallbackInfo & info)2803 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
2804 {
2805     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2806     if (!CheckJSCallbackInfo("JsOnDrop", info, checkList)) {
2807         return;
2808     }
2809     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
2810     auto onDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
2811                         const RefPtr<DragEvent>& info, const std::string &extraParams) {
2812         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2813         ACE_SCORING_EVENT("onDrop");
2814         func->Execute(info, extraParams);
2815     };
2816     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
2817     box->SetOnDropId(onDropId);
2818 }
2819 
JsOnAreaChange(const JSCallbackInfo & info)2820 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
2821 {
2822     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::FUNCTION};
2823     if (!CheckJSCallbackInfo("JsOnAreaChange", info, checkList)) {
2824         return;
2825     }
2826     auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(info[0]));
2827     auto onAreaChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction)](
2828                                     const Rect& oldRect, const Offset& oldOrigin, const Rect& rect,
2829                                     const Offset& origin) {
2830         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2831         ACE_SCORING_EVENT("onAreaChange");
2832         func->Execute(oldRect, oldOrigin, rect, origin);
2833     };
2834     auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
2835     boxComponent->GetEventExtensions()->GetOnAreaChangeExtension()->AddOnAreaChangeEvent(
2836         std::move(onAreaChangeCallback));
2837 }
2838 
2839 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)2840 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
2841 {
2842     if (info.Length() < 2) {
2843         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
2844         return;
2845     }
2846 
2847     if (!info[0]->IsBoolean() && !info[0]->IsObject()) {
2848         LOGE("The first param type is not bool or object, invaild.");
2849         return;
2850     }
2851 
2852     if (!info[1]->IsObject()) {
2853         LOGE("The second param type is not object, invaild.");
2854         return;
2855     }
2856 
2857     ViewStackProcessor::GetInstance()->GetCoverageComponent();
2858     auto popupComponent = ViewStackProcessor::GetInstance()->GetPopupComponent(true);
2859     if (!popupComponent) {
2860         return;
2861     }
2862     auto popupParam = popupComponent->GetPopupParam();
2863     if (!popupParam) {
2864         return;
2865     }
2866 
2867     auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
2868     if (!inspector) {
2869         LOGE("this component does not hava inspetor");
2870         return;
2871     }
2872     popupParam->SetTargetId(inspector->GetId());
2873     if (info[0]->IsBoolean()) {
2874         popupParam->SetIsShow(info[0]->ToBoolean());
2875     } else {
2876         JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
2877         ParseShowObject(info, showObj, popupComponent);
2878         popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
2879     }
2880 
2881     JSRef<JSObject> popupObj = JSRef<JSObject>::Cast(info[1]);
2882     if (popupObj->GetProperty("message")->IsString()) {
2883         ParsePopupParam(info, popupObj, popupComponent);
2884     } else {
2885         ParseCustomPopupParam(info, popupObj, popupComponent);
2886     }
2887 }
2888 #endif
2889 
JsLinearGradient(const JSCallbackInfo & info)2890 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
2891 {
2892     if (info.Length() < 1) {
2893         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
2894         return;
2895     }
2896     if (!info[0]->IsObject()) {
2897         LOGE("arg is not a object.");
2898         return;
2899     }
2900 
2901     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2902     if (!argsPtrItem || argsPtrItem->IsNull()) {
2903         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2904         info.ReturnSelf();
2905         return;
2906     }
2907     Gradient lineGradient;
2908     lineGradient.SetType(GradientType::LINEAR);
2909     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
2910     // angle
2911     std::optional<float> degree;
2912     GetAngle("angle", argsPtrItem, degree);
2913     if (degree) {
2914         lineGradient.GetLinearGradient().angle = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
2915         degree.reset();
2916     }
2917     // direction
2918     auto direction =
2919         static_cast<GradientDirection>(argsPtrItem->GetInt("direction", static_cast<int32_t>(GradientDirection::NONE)));
2920     switch (direction) {
2921         case GradientDirection::LEFT:
2922             lineGradient.GetLinearGradient().linearX = GradientDirection::LEFT;
2923             break;
2924         case GradientDirection::RIGHT:
2925             lineGradient.GetLinearGradient().linearX = GradientDirection::RIGHT;
2926             break;
2927         case GradientDirection::TOP:
2928             lineGradient.GetLinearGradient().linearY = GradientDirection::TOP;
2929             break;
2930         case GradientDirection::BOTTOM:
2931             lineGradient.GetLinearGradient().linearY = GradientDirection::BOTTOM;
2932             break;
2933         case GradientDirection::LEFT_TOP:
2934             lineGradient.GetLinearGradient().linearX = GradientDirection::LEFT;
2935             lineGradient.GetLinearGradient().linearY = GradientDirection::TOP;
2936             break;
2937         case GradientDirection::LEFT_BOTTOM:
2938             lineGradient.GetLinearGradient().linearX = GradientDirection::LEFT;
2939             lineGradient.GetLinearGradient().linearY = GradientDirection::BOTTOM;
2940             break;
2941         case GradientDirection::RIGHT_TOP:
2942             lineGradient.GetLinearGradient().linearX = GradientDirection::RIGHT;
2943             lineGradient.GetLinearGradient().linearY = GradientDirection::TOP;
2944             break;
2945         case GradientDirection::RIGHT_BOTTOM:
2946             lineGradient.GetLinearGradient().linearX = GradientDirection::RIGHT;
2947             lineGradient.GetLinearGradient().linearY = GradientDirection::BOTTOM;
2948             break;
2949         case GradientDirection::NONE:
2950         case GradientDirection::START_TO_END:
2951         case GradientDirection::END_TO_START:
2952         default:
2953             break;
2954     }
2955     // repeating
2956     auto repeating = argsPtrItem->GetBool("repeating", false);
2957     lineGradient.SetRepeat(repeating);
2958     // color stops
2959     GetGradientColorStops(lineGradient, argsPtrItem->GetValue("colors"));
2960 
2961     auto stack = ViewStackProcessor::GetInstance();
2962     if (!stack->IsVisualStateSet()) {
2963         auto decoration = GetBackDecoration();
2964         if (decoration) {
2965             decoration->SetGradient(lineGradient);
2966         }
2967     } else {
2968         auto boxComponent = stack->GetBoxComponent();
2969         boxComponent->GetStateAttributes()->AddAttribute<Gradient>
2970             (BoxStateAttribute::GRADIENT, lineGradient, stack->GetVisualState());
2971         if (!boxComponent->GetStateAttributes()->
2972             HasAttribute(BoxStateAttribute::GRADIENT, VisualState::NORMAL)) {
2973             boxComponent->GetStateAttributes()->AddAttribute<Gradient>(BoxStateAttribute::GRADIENT,
2974                 GetBackDecoration()->GetGradient(), VisualState::NORMAL);
2975         }
2976     }
2977 }
2978 
JsRadialGradient(const JSCallbackInfo & info)2979 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
2980 {
2981     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
2982     if (!CheckJSCallbackInfo("JsRadialGradient", info, checkList)) {
2983         return;
2984     }
2985 
2986     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
2987     if (!argsPtrItem || argsPtrItem->IsNull()) {
2988         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
2989         info.ReturnSelf();
2990         return;
2991     }
2992 
2993     Gradient radialGradient;
2994     radialGradient.SetType(GradientType::RADIAL);
2995     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
2996     // center
2997     auto center = argsPtrItem->GetValue("center");
2998     if (center && !center->IsNull() && center->IsArray() && center->GetArraySize() == 2) {
2999         Dimension value;
3000         if (ParseJsonDimensionVp(center->GetArrayItem(0), value)) {
3001             radialGradient.GetRadialGradient().radialCenterX = AnimatableDimension(value, option);
3002             if (value.Unit() == DimensionUnit::PERCENT) {
3003                 // [0,1] -> [0, 100]
3004                 radialGradient.GetRadialGradient().radialCenterX =
3005                     AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3006             }
3007         }
3008         if (ParseJsonDimensionVp(center->GetArrayItem(1), value)) {
3009             radialGradient.GetRadialGradient().radialCenterY = AnimatableDimension(value, option);
3010             if (value.Unit() == DimensionUnit::PERCENT) {
3011                 // [0,1] -> [0, 100]
3012                 radialGradient.GetRadialGradient().radialCenterY =
3013                     AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3014             }
3015         }
3016     }
3017     // radius
3018     Dimension radius;
3019     if (ParseJsonDimensionVp(argsPtrItem->GetValue("radius"), radius)) {
3020         radialGradient.GetRadialGradient().radialVerticalSize = AnimatableDimension(radius, option);
3021         radialGradient.GetRadialGradient().radialHorizontalSize = AnimatableDimension(radius, option);
3022     }
3023     // repeating
3024     auto repeating = argsPtrItem->GetBool("repeating", false);
3025     radialGradient.SetRepeat(repeating);
3026     // color stops
3027     GetGradientColorStops(radialGradient, argsPtrItem->GetValue("colors"));
3028 
3029     auto stack = ViewStackProcessor::GetInstance();
3030     if (!stack->IsVisualStateSet()) {
3031         auto decoration = GetBackDecoration();
3032         if (decoration) {
3033             decoration->SetGradient(radialGradient);
3034         }
3035     } else {
3036         auto boxComponent = stack->GetBoxComponent();
3037         boxComponent->GetStateAttributes()->AddAttribute<Gradient>
3038             (BoxStateAttribute::GRADIENT, radialGradient, stack->GetVisualState());
3039         if (!boxComponent->GetStateAttributes()->
3040             HasAttribute(BoxStateAttribute::GRADIENT, VisualState::NORMAL)) {
3041             boxComponent->GetStateAttributes()->AddAttribute<Gradient>(BoxStateAttribute::GRADIENT,
3042                 GetBackDecoration()->GetGradient(), VisualState::NORMAL);
3043         }
3044     }
3045 }
3046 
JsSweepGradient(const JSCallbackInfo & info)3047 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
3048 {
3049     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
3050     if (!CheckJSCallbackInfo("JsSweepGradient", info, checkList)) {
3051         return;
3052     }
3053 
3054     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3055     if (!argsPtrItem || argsPtrItem->IsNull()) {
3056         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
3057         info.ReturnSelf();
3058         return;
3059     }
3060 
3061     Gradient sweepGradient;
3062     sweepGradient.SetType(GradientType::SWEEP);
3063     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3064     // center
3065     auto center = argsPtrItem->GetValue("center");
3066     if (center && !center->IsNull() && center->IsArray() && center->GetArraySize() == 2) {
3067         Dimension value;
3068         if (ParseJsonDimensionVp(center->GetArrayItem(0), value)) {
3069             sweepGradient.GetSweepGradient().centerX = AnimatableDimension(value, option);
3070             if (value.Unit() == DimensionUnit::PERCENT) {
3071                 // [0,1] -> [0, 100]
3072                 sweepGradient.GetSweepGradient().centerX =
3073                     AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3074             }
3075         }
3076         if (ParseJsonDimensionVp(center->GetArrayItem(1), value)) {
3077             sweepGradient.GetSweepGradient().centerY = AnimatableDimension(value, option);
3078             if (value.Unit() == DimensionUnit::PERCENT) {
3079                 // [0,1] -> [0, 100]
3080                 sweepGradient.GetSweepGradient().centerY =
3081                     AnimatableDimension(value.Value() * 100.0, DimensionUnit::PERCENT, option);
3082             }
3083         }
3084     }
3085     std::optional<float> degree;
3086     // start
3087     GetAngle("start", argsPtrItem, degree);
3088     if (degree) {
3089         sweepGradient.GetSweepGradient().startAngle = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
3090         degree.reset();
3091     }
3092     // end
3093     GetAngle("end", argsPtrItem, degree);
3094     if (degree) {
3095         sweepGradient.GetSweepGradient().endAngle = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
3096         degree.reset();
3097     }
3098     // rotation
3099     GetAngle("rotation", argsPtrItem, degree);
3100     if (degree) {
3101         sweepGradient.GetSweepGradient().rotation = AnimatableDimension(degree.value(), DimensionUnit::PX, option);
3102         degree.reset();
3103     }
3104     // repeating
3105     auto repeating = argsPtrItem->GetBool("repeating", false);
3106     sweepGradient.SetRepeat(repeating);
3107     // color stops
3108     GetGradientColorStops(sweepGradient, argsPtrItem->GetValue("colors"));
3109 
3110     auto stack = ViewStackProcessor::GetInstance();
3111     if (!stack->IsVisualStateSet()) {
3112         auto decoration = GetBackDecoration();
3113         if (decoration) {
3114             decoration->SetGradient(sweepGradient);
3115         }
3116     } else {
3117         auto boxComponent = stack->GetBoxComponent();
3118         boxComponent->GetStateAttributes()->AddAttribute<Gradient>
3119             (BoxStateAttribute::GRADIENT, sweepGradient, stack->GetVisualState());
3120         if (!boxComponent->GetStateAttributes()->
3121             HasAttribute(BoxStateAttribute::GRADIENT, VisualState::NORMAL)) {
3122             boxComponent->GetStateAttributes()->AddAttribute<Gradient>(BoxStateAttribute::GRADIENT,
3123                 GetBackDecoration()->GetGradient(), VisualState::NORMAL);
3124         }
3125     }
3126 }
3127 
JsMotionPath(const JSCallbackInfo & info)3128 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
3129 {
3130     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
3131     if (!CheckJSCallbackInfo("JsMotionPath", info, checkList)) {
3132         return;
3133     }
3134     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3135     MotionPathOption motionPathOption;
3136     if (ParseMotionPath(argsPtrItem, motionPathOption)) {
3137         if (motionPathOption.GetRotate()) {
3138             ViewStackProcessor::GetInstance()->GetTransformComponent();
3139         }
3140         auto flexItem = ViewStackProcessor::GetInstance()->GetFlexItemComponent();
3141         flexItem->SetMotionPathOption(motionPathOption);
3142     } else {
3143         LOGE("parse motionPath failed. %{public}s", info[0]->ToString().c_str());
3144     }
3145 }
3146 
JsShadow(const JSCallbackInfo & info)3147 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
3148 {
3149     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::OBJECT};
3150     if (!CheckJSCallbackInfo("JsShadow", info, checkList)) {
3151         return;
3152     }
3153     auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
3154     if (!argsPtrItem || argsPtrItem->IsNull()) {
3155         LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
3156         info.ReturnSelf();
3157         return;
3158     }
3159     double radius = 0.0;
3160     ParseJsonDouble(argsPtrItem->GetValue("radius"), radius);
3161     if (LessOrEqual(radius, 0.0)) {
3162         LOGE("JsShadow Parse radius failed, radius = %{public}lf", radius);
3163         return;
3164     }
3165     std::vector<Shadow> shadows(1);
3166     shadows.begin()->SetBlurRadius(radius);
3167     Dimension offsetX;
3168     if (ParseJsonDimensionVp(argsPtrItem->GetValue("offsetX"), offsetX)) {
3169         shadows.begin()->SetOffsetX(offsetX.Value());
3170     }
3171     Dimension offsetY;
3172     if (ParseJsonDimensionVp(argsPtrItem->GetValue("offsetY"), offsetY)) {
3173         shadows.begin()->SetOffsetY(offsetY.Value());
3174     }
3175     Color color;
3176     if (ParseJsonColor(argsPtrItem->GetValue("color"), color)) {
3177         shadows.begin()->SetColor(color);
3178     }
3179     auto backDecoration = GetBackDecoration();
3180     backDecoration->SetShadows(shadows);
3181 }
3182 
JsGrayScale(const JSCallbackInfo & info)3183 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
3184 {
3185     if (info.Length() < 1) {
3186         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3187         return;
3188     }
3189 
3190     Dimension value;
3191     if (!ParseJsDimensionVp(info[0], value)) {
3192         return;
3193     }
3194 
3195     if (LessNotEqual(value.Value(), 0.0)) {
3196         value.SetValue(0.0);
3197     }
3198 
3199     if (GreatNotEqual(value.Value(), 1.0)) {
3200         value.SetValue(1.0);
3201     }
3202 
3203     auto frontDecoration = GetFrontDecoration();
3204     frontDecoration->SetGrayScale(value);
3205 }
3206 
JsBrightness(const JSCallbackInfo & info)3207 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
3208 {
3209     if (info.Length() < 1) {
3210         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3211         return;
3212     }
3213 
3214     Dimension value;
3215     if (!ParseJsDimensionVp(info[0], value)) {
3216         return;
3217     }
3218 
3219     auto frontDecoration = GetFrontDecoration();
3220     frontDecoration->SetBrightness(value);
3221 }
3222 
JsContrast(const JSCallbackInfo & info)3223 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
3224 {
3225     if (info.Length() < 1) {
3226         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3227         return;
3228     }
3229 
3230     Dimension value;
3231     if (!ParseJsDimensionVp(info[0], value)) {
3232         return;
3233     }
3234 
3235     if (LessNotEqual(value.Value(), 0.0)) {
3236         value.SetValue(0.0);
3237     }
3238     auto frontDecoration = GetFrontDecoration();
3239     frontDecoration->SetContrast(value);
3240 }
3241 
JsSaturate(const JSCallbackInfo & info)3242 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
3243 {
3244     if (info.Length() < 1) {
3245         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3246         return;
3247     }
3248     Dimension value;
3249     if (!ParseJsDimensionVp(info[0], value)) {
3250         return;
3251     }
3252 
3253     if (LessNotEqual(value.Value(), 0.0)) {
3254         value.SetValue(0.0);
3255     }
3256     auto frontDecoration = GetFrontDecoration();
3257     frontDecoration->SetSaturate(value);
3258 }
3259 
JsSepia(const JSCallbackInfo & info)3260 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
3261 {
3262     if (info.Length() < 1) {
3263         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3264         return;
3265     }
3266 
3267     Dimension value;
3268     if (!ParseJsDimensionVp(info[0], value)) {
3269         return;
3270     }
3271 
3272     if (LessNotEqual(value.Value(), 0.0)) {
3273         value.SetValue(0.0);
3274     }
3275     auto frontDecoration = GetFrontDecoration();
3276     frontDecoration->SetSepia(value);
3277 }
3278 
JsInvert(const JSCallbackInfo & info)3279 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
3280 {
3281     if (info.Length() < 1) {
3282         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
3283         return;
3284     }
3285     Dimension value;
3286     if (!ParseJsDimensionVp(info[0], value)) {
3287         return;
3288     }
3289     if (LessNotEqual(value.Value(), 0.0)) {
3290         value.SetValue(0.0);
3291     }
3292     auto frontDecoration = GetFrontDecoration();
3293     frontDecoration->SetInvert(value);
3294 }
3295 
JsHueRotate(const JSCallbackInfo & info)3296 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
3297 {
3298     std::optional<float> degree;
3299     if (info.Length() < 1) {
3300         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
3301         return;
3302     }
3303     if (info[0]->IsString()) {
3304         degree = static_cast<float>(StringUtils::StringToDegree(info[0]->ToString()));
3305     } else if (info[0]->IsNumber()) {
3306         degree = static_cast<float>(info[0]->ToNumber<uint32_t>());
3307     } else {
3308         LOGE("Invalid value type");
3309     }
3310     float deg = 0.0;
3311     if (degree) {
3312         deg = degree.value();
3313         degree.reset();
3314     }
3315     auto decoration = GetFrontDecoration();
3316     if (decoration) {
3317         decoration->SetHueRotate(deg);
3318     }
3319 }
3320 
JsClip(const JSCallbackInfo & info)3321 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
3322 {
3323     if (info.Length() > 0) {
3324         auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3325         if (info[0]->IsObject()) {
3326             JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
3327             if (clipShape == nullptr) {
3328                 LOGE("clipShape is null.");
3329                 return;
3330             }
3331             auto clipPath = AceType::MakeRefPtr<ClipPath>();
3332             clipPath->SetBasicShape(clipShape->GetBasicShape());
3333             box->SetClipPath(clipPath);
3334         } else if (info[0]->IsBoolean()) {
3335             box->SetBoxClipFlag(info[0]->ToBoolean());
3336         }
3337     }
3338 }
3339 
JsMask(const JSCallbackInfo & info)3340 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
3341 {
3342     if (info.Length() > 0 && info[0]->IsObject()) {
3343         JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
3344         if (maskShape == nullptr) {
3345             return;
3346         }
3347         auto maskPath = AceType::MakeRefPtr<MaskPath>();
3348         maskPath->SetBasicShape(maskShape->GetBasicShape());
3349         auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3350         box->SetMask(maskPath);
3351     }
3352 }
3353 
JsFocusable(const JSCallbackInfo & info)3354 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
3355 {
3356     if (!info[0]->IsBoolean()) {
3357         LOGE("The info is wrong, it is supposed to be an boolean");
3358         return;
3359     }
3360 
3361     auto focusComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3362     if (!focusComponent) {
3363         LOGE("The focusComponent is null");
3364         return;
3365     } else {
3366         focusComponent->SetFocusable(info[0]->ToBoolean());
3367     }
3368 }
3369 
JsOnFocusMove(const JSCallbackInfo & args)3370 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
3371 {
3372     if (args[0]->IsFunction()) {
3373         RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
3374         auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove)](int info) {
3375             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3376             ACE_SCORING_EVENT("onFocusMove");
3377             func->Execute(info);
3378         };
3379         auto focusableComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3380         focusableComponent->SetOnFocusMove(onFocusMove);
3381     }
3382 }
3383 
JsOnFocus(const JSCallbackInfo & args)3384 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
3385 {
3386     if (args[0]->IsFunction()) {
3387         RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
3388         auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus)]() {
3389             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3390             ACE_SCORING_EVENT("onFocus");
3391             func->Execute();
3392         };
3393         auto focusableComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3394         focusableComponent->SetOnFocus(onFocus);
3395     }
3396 }
3397 
JsOnBlur(const JSCallbackInfo & args)3398 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
3399 {
3400     if (args[0]->IsFunction()) {
3401         RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(args[0]));
3402         auto onBlur_ = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur)]() {
3403             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3404             ACE_SCORING_EVENT("onBlur");
3405             func->Execute();
3406         };
3407         auto focusableComponent = ViewStackProcessor::GetInstance()->GetFocusableComponent();
3408         focusableComponent->SetOnBlur(onBlur_);
3409     }
3410 }
3411 
JsKey(const std::string & key)3412 void JSViewAbstract::JsKey(const std::string& key)
3413 {
3414     auto component = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3415     if (component) {
3416         component->SetInspectorKey(key);
3417     }
3418 }
3419 
JsId(const std::string & id)3420 void JSViewAbstract::JsId(const std::string& id)
3421 {
3422     JsKey(id);
3423 }
3424 
JsRestoreId(int32_t restoreId)3425 void JSViewAbstract::JsRestoreId(int32_t restoreId)
3426 {
3427     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
3428     if (component) {
3429         component->SetRestoreId(restoreId);
3430     }
3431 }
3432 
3433 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
JsDebugLine(const JSCallbackInfo & info)3434 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
3435 {
3436     std::vector<JSCallbackInfoType> checkList {JSCallbackInfoType::STRING};
3437     if (!CheckJSCallbackInfo("JsDebugLine", info, checkList)) {
3438         return;
3439     }
3440 
3441     auto component = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3442     if (component) {
3443         component->SetDebugLine(info[0]->ToString());
3444     }
3445 }
3446 #endif
3447 
JsOpacityPassThrough(const JSCallbackInfo & info)3448 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
3449 {
3450     JSViewAbstract::JsOpacity(info);
3451     if (ViewStackProcessor::GetInstance()->HasDisplayComponent()) {
3452         auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
3453         display->DisableLayer(true);
3454     }
3455 }
3456 
JsTransitionPassThrough(const JSCallbackInfo & info)3457 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
3458 {
3459     JSViewAbstract::JsTransition(info);
3460     if (ViewStackProcessor::GetInstance()->HasDisplayComponent()) {
3461         auto display = ViewStackProcessor::GetInstance()->GetDisplayComponent();
3462         display->DisableLayer(true);
3463     }
3464 }
3465 
JsAccessibilityGroup(bool accessible)3466 void JSViewAbstract::JsAccessibilityGroup(bool accessible)
3467 {
3468     auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3469     if (!inspector) {
3470         LOGE("this component does not hava inspetor");
3471         return;
3472     }
3473     inspector->SetAccessibilityGroup(accessible);
3474 }
3475 
JsAccessibilityText(const std::string & text)3476 void JSViewAbstract::JsAccessibilityText(const std::string& text)
3477 {
3478     auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3479     if (!inspector) {
3480         LOGE("this component does not hava inspetor");
3481         return;
3482     }
3483     inspector->SetAccessibilitytext(text);
3484 }
3485 
JsAccessibilityDescription(const std::string & description)3486 void JSViewAbstract::JsAccessibilityDescription(const std::string& description)
3487 {
3488     auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3489     if (!inspector) {
3490         LOGE("this component does not hava inspetor");
3491         return;
3492     }
3493     inspector->SetAccessibilityDescription(description);
3494 }
3495 
JsAccessibilityImportance(const std::string & importance)3496 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
3497 {
3498     auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
3499     if (!inspector) {
3500         LOGE("this component does not hava inspetor");
3501         return;
3502     }
3503     inspector->SetAccessibilityImportance(importance);
3504 }
3505 
JsBindContextMenu(const JSCallbackInfo & info)3506 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
3507 {
3508     ViewStackProcessor::GetInstance()->GetCoverageComponent();
3509     auto menuComponent = ViewStackProcessor::GetInstance()->GetMenuComponent(true);
3510     if (!menuComponent) {
3511         return;
3512     }
3513 #if defined(MULTIPLE_WINDOW_SUPPORTED)
3514     menuComponent->SetIsContextMenu(true);
3515 #endif
3516     int32_t responseType = static_cast<int32_t>(ResponseType::LONGPRESS);
3517     if (info.Length() == 2 && info[1]->IsNumber()) {
3518         responseType = info[1]->ToNumber<int32_t>();
3519         LOGI("Set the responseType is %d.", responseType);
3520     }
3521 
3522     if (responseType == static_cast<int32_t>(ResponseType::RIGHT_CLICK)) {
3523         auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3524         box->SetOnMouseId([weak = WeakPtr<OHOS::Ace::MenuComponent>(menuComponent)](MouseInfo& info) {
3525             auto refPtr = weak.Upgrade();
3526             if (!refPtr) {
3527                 return;
3528             }
3529             if (info.GetButton() == MouseButton::RIGHT_BUTTON && info.GetAction() == MouseAction::RELEASE) {
3530                 auto showMenu = refPtr->GetTargetCallback();
3531 #if defined(MULTIPLE_WINDOW_SUPPORTED)
3532                 showMenu("", info.GetScreenLocation());
3533 #else
3534                 showMenu("", info.GetGlobalLocation());
3535 #endif
3536             }
3537         });
3538     } else if (responseType == static_cast<int32_t>(ResponseType::LONGPRESS)) {
3539         auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3540         RefPtr<Gesture> longGesture =
3541             AceType::MakeRefPtr<LongPressGesture>(DEFAULT_LONG_PRESS_FINGER, false, DEFAULT_LONG_PRESS_DURATION);
3542         longGesture->SetOnActionId([weak = WeakPtr<OHOS::Ace::MenuComponent>(menuComponent)](const GestureEvent& info) {
3543             auto refPtr = weak.Upgrade();
3544             if (!refPtr) {
3545                 return;
3546             }
3547             auto showMenu = refPtr->GetTargetCallback();
3548 #if defined(MULTIPLE_WINDOW_SUPPORTED)
3549             showMenu("", info.GetScreenLocation());
3550 #else
3551             showMenu("", info.GetGlobalLocation());
3552 #endif
3553         });
3554         box->SetOnLongPress(longGesture);
3555     } else {
3556         LOGE("The arg responseType is invalid.");
3557         return;
3558     }
3559     auto menuTheme = GetTheme<SelectTheme>();
3560     menuComponent->SetTheme(menuTheme);
3561 
3562     if (info[0]->IsObject()) {
3563         JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[0]);
3564 
3565         auto builder = menuObj->GetProperty("builder");
3566         if (!builder->IsFunction()) {
3567             LOGE("builder param is not a function.");
3568             return;
3569         }
3570         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3571         if (!builderFunc) {
3572             LOGE("builder function is null.");
3573             return;
3574         }
3575         // use another VSP instance while executing the builder function
3576         ScopedViewStackProcessor builderViewStackProcessor;
3577         {
3578             ACE_SCORING_EVENT("contextMenu.builder");
3579             builderFunc->Execute();
3580         }
3581         auto customComponent = ViewStackProcessor::GetInstance()->Finish();
3582         if (!customComponent) {
3583             LOGE("Custom component is null.");
3584             return;
3585         }
3586 
3587         auto optionTheme = GetTheme<SelectTheme>();
3588         auto optionComponent = AceType::MakeRefPtr<OHOS::Ace::OptionComponent>(optionTheme);
3589         optionComponent->SetCustomComponent(customComponent);
3590         menuComponent->ClearOptions();
3591         menuComponent->AppendOption(optionComponent);
3592     } else {
3593         LOGE("Param is invalid");
3594         return;
3595     }
3596 }
3597 
JSBind()3598 void JSViewAbstract::JSBind()
3599 {
3600     JSClass<JSViewAbstract>::Declare("JSViewAbstract");
3601 
3602     // staticmethods
3603     MethodOptions opt = MethodOptions::NONE;
3604     JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
3605 
3606     JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
3607     JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
3608     JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
3609     JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
3610     JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
3611     JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
3612     JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
3613 
3614     JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
3615     JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
3616     JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
3617     JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
3618     JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
3619 
3620     JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
3621     JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
3622     JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
3623     JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
3624     JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
3625 
3626     JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
3627     JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
3628     JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
3629     JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
3630     JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::SetBorderStyle, opt);
3631     JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
3632     JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
3633     JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
3634     JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
3635 
3636     JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
3637     JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
3638     JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
3639     JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
3640     JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
3641     JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
3642     JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
3643     JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
3644     JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
3645     JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
3646     JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
3647     JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
3648 
3649     JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
3650     JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
3651     JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
3652     JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
3653     JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
3654     JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
3655     JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
3656 
3657     JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
3658     JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
3659     JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
3660     JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
3661     JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
3662     JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
3663     JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
3664     JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
3665     JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
3666     JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
3667     JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
3668     JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
3669     JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
3670     JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
3671 #ifndef WEARABLE_PRODUCT
3672     JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
3673 #endif
3674 
3675     JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
3676     JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
3677     JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
3678     JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
3679     JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
3680     JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
3681     JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
3682 
3683     JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
3684     JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
3685     JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
3686     JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
3687     JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
3688     JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
3689     JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
3690     JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
3691     JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
3692     JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
3693     JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
3694     JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
3695     JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
3696     JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
3697     JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
3698     JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
3699     JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
3700     JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
3701     JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
3702     JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
3703     JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
3704     JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
3705     JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
3706     JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
3707     JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
3708     JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
3709 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
3710     JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
3711 #endif
3712     JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
3713     JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
3714     JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
3715 
3716     JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
3717     JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
3718     JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
3719     JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
3720     JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
3721 }
3722 
GetFrontDecoration()3723 RefPtr<Decoration> JSViewAbstract::GetFrontDecoration()
3724 {
3725     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3726     auto decoration = box->GetFrontDecoration();
3727     if (!decoration) {
3728         decoration = AceType::MakeRefPtr<Decoration>();
3729         box->SetFrontDecoration(decoration);
3730     }
3731 
3732     return decoration;
3733 }
3734 
GetBackDecoration()3735 RefPtr<Decoration> JSViewAbstract::GetBackDecoration()
3736 {
3737     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3738     auto decoration = box->GetBackDecoration();
3739     if (!decoration) {
3740         decoration = AceType::MakeRefPtr<Decoration>();
3741         box->SetBackDecoration(decoration);
3742     }
3743     return decoration;
3744 }
3745 
SetBorderRadius(const Dimension & value,const AnimationOption & option)3746 void JSViewAbstract::SetBorderRadius(const Dimension& value, const AnimationOption& option)
3747 {
3748     BoxComponentHelper::SetBorderRadius(GetBackDecoration(), value, option);
3749 }
3750 
SetBorderStyle(int32_t style)3751 void JSViewAbstract::SetBorderStyle(int32_t style)
3752 {
3753     BorderStyle borderStyle = BorderStyle::SOLID;
3754 
3755     if (static_cast<int32_t>(BorderStyle::SOLID) == style) {
3756         borderStyle = BorderStyle::SOLID;
3757     } else if (static_cast<int32_t>(BorderStyle::DASHED) == style) {
3758         borderStyle = BorderStyle::DASHED;
3759     } else if (static_cast<int32_t>(BorderStyle::DOTTED) == style) {
3760         borderStyle = BorderStyle::DOTTED;
3761     } else {
3762         borderStyle = BorderStyle::NONE;
3763     }
3764 
3765     auto stack = ViewStackProcessor::GetInstance();
3766     if (!stack->IsVisualStateSet()) {
3767         BoxComponentHelper::SetBorderStyle(GetBackDecoration(), borderStyle);
3768     } else {
3769         auto boxComponent = AceType::DynamicCast<BoxComponent>(stack->GetBoxComponent());
3770         boxComponent->GetStateAttributes()->AddAttribute<BorderStyle>
3771             (BoxStateAttribute::BORDER_STYLE, borderStyle, stack->GetVisualState());
3772         if (!boxComponent->GetStateAttributes()->
3773             HasAttribute(BoxStateAttribute::BORDER_STYLE, VisualState::NORMAL)) {
3774             boxComponent->GetStateAttributes()->AddAttribute<BorderStyle>(BoxStateAttribute::BORDER_STYLE,
3775                 BoxComponentHelper::GetBorderStyle(GetBackDecoration()), VisualState::NORMAL);
3776         }
3777     }
3778 }
3779 
SetMarginTop(const JSCallbackInfo & info)3780 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
3781 {
3782     if (info.Length() < 1) {
3783         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3784         return;
3785     }
3786     AnimatableDimension value;
3787     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3788         return;
3789     }
3790     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3791     Edge margin = box->GetMargin();
3792     margin.SetTop(value);
3793     box->SetMargin(margin);
3794 }
3795 
SetMarginBottom(const JSCallbackInfo & info)3796 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
3797 {
3798     if (info.Length() < 1) {
3799         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3800         return;
3801     }
3802     AnimatableDimension value;
3803     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3804         return;
3805     }
3806     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3807     Edge margin = box->GetMargin();
3808     margin.SetBottom(value);
3809     box->SetMargin(margin);
3810 }
3811 
SetMarginLeft(const JSCallbackInfo & info)3812 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
3813 {
3814     if (info.Length() < 1) {
3815         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3816         return;
3817     }
3818     AnimatableDimension value;
3819     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3820         return;
3821     }
3822     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3823     Edge margin = box->GetMargin();
3824     margin.SetLeft(value);
3825     box->SetMargin(margin);
3826 }
3827 
SetMarginRight(const JSCallbackInfo & info)3828 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
3829 {
3830     if (info.Length() < 1) {
3831         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3832         return;
3833     }
3834     AnimatableDimension value;
3835     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3836         return;
3837     }
3838     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3839     Edge margin = box->GetMargin();
3840     margin.SetRight(value);
3841     box->SetMargin(margin);
3842 }
3843 
SetMargins(const Dimension & top,const Dimension & bottom,const Dimension & left,const Dimension & right)3844 void JSViewAbstract::SetMargins(
3845     const Dimension& top, const Dimension& bottom, const Dimension& left, const Dimension& right)
3846 {
3847     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3848     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3849     Edge margin(left, top, right, bottom, option);
3850     box->SetMargin(margin);
3851 }
3852 
SetPaddingTop(const JSCallbackInfo & info)3853 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
3854 {
3855     if (info.Length() < 1) {
3856         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3857         return;
3858     }
3859     AnimatableDimension value;
3860     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3861         return;
3862     }
3863     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3864     Edge padding = box->GetPadding();
3865     padding.SetTop(value);
3866     box->SetPadding(padding);
3867 }
3868 
SetPaddingBottom(const JSCallbackInfo & info)3869 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
3870 {
3871     if (info.Length() < 1) {
3872         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3873         return;
3874     }
3875     AnimatableDimension value;
3876     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3877         return;
3878     }
3879     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3880     Edge padding = box->GetPadding();
3881     padding.SetBottom(value);
3882     box->SetPadding(padding);
3883 }
3884 
SetPaddingLeft(const JSCallbackInfo & info)3885 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
3886 {
3887     if (info.Length() < 1) {
3888         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3889         return;
3890     }
3891     AnimatableDimension value;
3892     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3893         return;
3894     }
3895     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3896     Edge padding = box->GetPadding();
3897     padding.SetLeft(value);
3898     box->SetPadding(padding);
3899 }
3900 
SetPaddingRight(const JSCallbackInfo & info)3901 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
3902 {
3903     if (info.Length() < 1) {
3904         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
3905         return;
3906     }
3907     AnimatableDimension value;
3908     if (!ParseJsAnimatableDimensionVp(info[0], value)) {
3909         return;
3910     }
3911     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3912     Edge padding = box->GetPadding();
3913     padding.SetRight(value);
3914     box->SetPadding(padding);
3915 }
3916 
SetPadding(const Dimension & value)3917 void JSViewAbstract::SetPadding(const Dimension& value)
3918 {
3919     SetPaddings(value, value, value, value);
3920 }
3921 
SetPaddings(const Dimension & top,const Dimension & bottom,const Dimension & left,const Dimension & right)3922 void JSViewAbstract::SetPaddings(
3923     const Dimension& top, const Dimension& bottom, const Dimension& left, const Dimension& right)
3924 {
3925     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
3926     AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3927     Edge padding(left, top, right, bottom, option);
3928     box->SetPadding(padding);
3929 }
3930 
SetMargin(const Dimension & value)3931 void JSViewAbstract::SetMargin(const Dimension& value)
3932 {
3933     SetMargins(value, value, value, value);
3934 }
3935 
SetBlur(float radius)3936 void JSViewAbstract::SetBlur(float radius)
3937 {
3938     auto decoration = GetFrontDecoration();
3939     SetBlurRadius(decoration, radius);
3940 }
3941 
SetColorBlend(Color color)3942 void JSViewAbstract::SetColorBlend(Color color)
3943 {
3944     auto decoration = GetFrontDecoration();
3945     if (decoration) {
3946         decoration->SetColorBlend(color);
3947     }
3948 }
3949 
SetBackdropBlur(float radius)3950 void JSViewAbstract::SetBackdropBlur(float radius)
3951 {
3952     auto decoration = GetBackDecoration();
3953     SetBlurRadius(decoration, radius);
3954 }
3955 
SetBlurRadius(const RefPtr<Decoration> & decoration,float radius)3956 void JSViewAbstract::SetBlurRadius(const RefPtr<Decoration>& decoration, float radius)
3957 {
3958     if (decoration) {
3959         AnimationOption option = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
3960         decoration->SetBlurRadius(AnimatableDimension(radius, DimensionUnit::PX, option));
3961     }
3962 }
3963 
SetWindowBlur(float progress,WindowBlurStyle blurStyle)3964 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
3965 {
3966     auto decoration = GetBackDecoration();
3967     if (decoration) {
3968         decoration->SetWindowBlurProgress(progress);
3969         decoration->SetWindowBlurStyle(blurStyle);
3970     }
3971 }
3972 
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,Dimension & result,DimensionUnit defaultUnit)3973 bool JSViewAbstract::ParseJsonDimension(
3974     const std::unique_ptr<JsonValue>& jsonValue, Dimension& result, DimensionUnit defaultUnit)
3975 {
3976     if (!jsonValue || jsonValue->IsNull()) {
3977         LOGD("invalid json value");
3978         return false;
3979     }
3980     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
3981         LOGE("json value is not numner, string or object");
3982         return false;
3983     }
3984     if (jsonValue->IsNumber()) {
3985         result = Dimension(jsonValue->GetDouble(), defaultUnit);
3986         return true;
3987     }
3988     if (jsonValue->IsString()) {
3989         result = StringUtils::StringToDimensionWithUnit(jsonValue->GetString(), defaultUnit);
3990         return true;
3991     }
3992     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
3993     auto resId = resVal->GetValue("id");
3994     if (!resId || !resId->IsNumber()) {
3995         LOGE("invalid resource id");
3996         return false;
3997     }
3998     auto themeConstants = GetThemeConstants();
3999     if (!themeConstants) {
4000         LOGE("themeConstants is nullptr");
4001         return false;
4002     }
4003     result = themeConstants->GetDimension(resId->GetUInt());
4004     return true;
4005 }
4006 
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,Dimension & result)4007 bool JSViewAbstract::ParseJsonDimensionVp(const std::unique_ptr<JsonValue>& jsonValue, Dimension& result)
4008 {
4009     return ParseJsonDimension(jsonValue, result, DimensionUnit::VP);
4010 }
4011 
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)4012 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
4013 {
4014     if (!jsonValue || jsonValue->IsNull()) {
4015         LOGD("invalid json value");
4016         return false;
4017     }
4018     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
4019         LOGE("json value is not numner, string or object");
4020         return false;
4021     }
4022     if (jsonValue->IsNumber()) {
4023         result = jsonValue->GetDouble();
4024         return true;
4025     }
4026     if (jsonValue->IsString()) {
4027         result = StringUtils::StringToDouble(jsonValue->GetString());
4028         return true;
4029     }
4030     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
4031     auto resId = resVal->GetValue("id");
4032     if (!resId || !resId->IsNumber()) {
4033         LOGE("invalid resource id");
4034         return false;
4035     }
4036     auto themeConstants = GetThemeConstants();
4037     if (!themeConstants) {
4038         LOGW("themeConstants is nullptr");
4039         return false;
4040     }
4041     result = themeConstants->GetDouble(resId->GetUInt());
4042     return true;
4043 }
4044 
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)4045 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
4046 {
4047     if (!jsonValue || jsonValue->IsNull()) {
4048         LOGD("invalid json value");
4049         return false;
4050     }
4051     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
4052         LOGE("json value is not numner, string or object");
4053         return false;
4054     }
4055     if (jsonValue->IsNumber()) {
4056         result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
4057         return true;
4058     }
4059     if (jsonValue->IsString()) {
4060         result = Color::FromString(jsonValue->GetString());
4061         return true;
4062     }
4063     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
4064     auto resId = resVal->GetValue("id");
4065     if (!resId || !resId->IsNumber()) {
4066         LOGE("invalid resource id");
4067         return false;
4068     }
4069     auto themeConstants = GetThemeConstants();
4070     if (!themeConstants) {
4071         LOGW("themeConstants is nullptr");
4072         return false;
4073     }
4074     result = themeConstants->GetColor(resId->GetUInt());
4075     return true;
4076 }
4077 
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)4078 void JSViewAbstract::GetAngle(
4079     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
4080 {
4081     auto value = jsonValue->GetValue(key);
4082     if (value && value->IsString()) {
4083         angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
4084     } else if (value && value->IsNumber()) {
4085         angle = static_cast<float>(value->GetDouble());
4086     } else {
4087         LOGE("Invalid value type");
4088     }
4089 }
4090 
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)4091 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
4092 {
4093     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
4094         return;
4095     }
4096 
4097     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
4098         GradientColor gradientColor;
4099         auto item = colorStops->GetArrayItem(i);
4100         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
4101             auto colorParams = item->GetArrayItem(0);
4102             // color
4103             Color color;
4104             if (!ParseJsonColor(colorParams, color)) {
4105                 LOGE("parse colorParams failed");
4106                 continue;
4107             }
4108             gradientColor.SetColor(color);
4109             gradientColor.SetHasValue(false);
4110             // stop value
4111             if (item->GetArraySize() <= 1) {
4112                 continue;
4113             }
4114             auto stopValue = item->GetArrayItem(1);
4115             double value = 0.0;
4116             if (ParseJsonDouble(stopValue, value)) {
4117                 value = std::clamp(value, 0.0, 1.0);
4118                 gradientColor.SetHasValue(true);
4119                 //  [0, 1] -> [0, 100.0];
4120                 gradientColor.SetDimension(Dimension(value * 100.0, DimensionUnit::PERCENT));
4121             }
4122 
4123             gradient.AddColor(gradientColor);
4124         }
4125     }
4126 }
4127 
SetDirection(const std::string & dir)4128 void JSViewAbstract::SetDirection(const std::string& dir)
4129 {
4130     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
4131     if (!box) {
4132         return;
4133     }
4134 
4135     if (dir == "Ltr") {
4136         box->SetTextDirection(TextDirection::LTR);
4137         box->SetInspectorDirection(TextDirection::LTR);
4138     } else if (dir == "Rtl") {
4139         box->SetTextDirection(TextDirection::RTL);
4140         box->SetInspectorDirection(TextDirection::RTL);
4141     } else if (dir == "Auto") {
4142         box->SetTextDirection(
4143             AceApplicationInfo::GetInstance().IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
4144         box->SetInspectorDirection(TextDirection::AUTO);
4145     }
4146 }
4147 
GetThemeConstants()4148 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants()
4149 {
4150     auto container = Container::Current();
4151     if (!container) {
4152         LOGW("container is null");
4153         return nullptr;
4154     }
4155     auto pipelineContext = container->GetPipelineContext();
4156     if (!pipelineContext) {
4157         LOGE("pipelineContext is null!");
4158         return nullptr;
4159     }
4160     auto themeManager = pipelineContext->GetThemeManager();
4161     if (!themeManager) {
4162         LOGE("themeManager is null!");
4163         return nullptr;
4164     }
4165     return themeManager->GetThemeConstants();
4166 }
4167 
JsHoverEffect(const JSCallbackInfo & info)4168 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
4169 {
4170     if (!info[0]->IsNumber()) {
4171         LOGE("info[0] is not a number");
4172         return;
4173     }
4174     auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
4175     boxComponent->SetMouseAnimationType(static_cast<HoverAnimationType>(info[0]->ToNumber<int32_t>()));
4176 }
4177 
GetTapGesture(const JSCallbackInfo & info,int32_t countNum,int32_t fingerNum)4178 RefPtr<Gesture> JSViewAbstract::GetTapGesture(const JSCallbackInfo& info, int32_t countNum, int32_t fingerNum)
4179 {
4180     auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
4181     if (!inspector) {
4182         LOGE("fail to get inspector for on touch event");
4183         return nullptr;
4184     }
4185     auto impl = inspector->GetInspectorFunctionImpl();
4186     RefPtr<Gesture> tapGesture = AceType::MakeRefPtr<TapGesture>(countNum, fingerNum);
4187     RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
4188     tapGesture->SetOnActionId(
4189         [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), impl](GestureEvent& info) {
4190             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4191             if (impl) {
4192                 impl->UpdateEventInfo(info);
4193             }
4194             ACE_SCORING_EVENT("onClick");
4195             func->Execute(info);
4196         });
4197     return tapGesture;
4198 }
4199 
JsOnMouse(const JSCallbackInfo & args)4200 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& args)
4201 {
4202     if (args[0]->IsFunction()) {
4203         auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
4204         if (!inspector) {
4205             LOGE("fail to get inspector for on mouse event");
4206             return;
4207         }
4208         auto impl = inspector->GetInspectorFunctionImpl();
4209         RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(args[0]));
4210         auto onMouseId = [execCtx = args.GetExecutionContext(), func = std::move(jsOnMouseFunc), impl](
4211                              MouseInfo& info) {
4212             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4213             if (impl) {
4214                 impl->UpdateEventInfo(info);
4215             }
4216             ACE_SCORING_EVENT("onMouse");
4217             func->Execute(info);
4218         };
4219         auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
4220         box->SetOnMouseId(onMouseId);
4221     }
4222 }
4223 
4224 } // namespace OHOS::Ace::Framework
4225