1  /*
2   * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3   * Licensed under the Apache License, Version 2.0 (the "License");
4   * you may not use this file except in compliance with the License.
5   * You may obtain a copy of the License at
6   *
7   *     http://www.apache.org/licenses/LICENSE-2.0
8   *
9   * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
17  
18  #include <algorithm>
19  #include <cstdint>
20  #include <functional>
21  #include <memory>
22  #include <optional>
23  #include <regex>
24  #include <string>
25  #include <utility>
26  #include <vector>
27  #include <unordered_map>
28  
29  #include "base/geometry/calc_dimension.h"
30  #include "base/geometry/dimension.h"
31  #include "base/geometry/matrix4.h"
32  #include "base/geometry/ng/offset_t.h"
33  #include "base/geometry/ng/vector.h"
34  #include "base/geometry/shape.h"
35  #include "base/json/json_util.h"
36  #include "base/log/ace_scoring_log.h"
37  #include "base/log/log.h"
38  #include "base/memory/ace_type.h"
39  #include "base/memory/referenced.h"
40  #include "base/utils/utils.h"
41  #include "bridge/common/utils/engine_helper.h"
42  #include "bridge/common/utils/utils.h"
43  #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
44  #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
45  #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
46  #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h"
47  #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
48  #include "bridge/declarative_frontend/engine/functions/js_function.h"
49  #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
50  #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
51  #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
52  #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
53  #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
54  #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
55  #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
56  #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
57  #include "bridge/js_frontend/engine/jsi/ark_js_value.h"
58  #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
59  #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
60  #include "bridge/declarative_frontend/engine/js_converter.h"
61  #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
62  #include "bridge/declarative_frontend/engine/js_types.h"
63  #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
64  #include "bridge/declarative_frontend/jsview/js_grid_container.h"
65  #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
66  #include "bridge/declarative_frontend/jsview/js_utils.h"
67  #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
68  #include "bridge/declarative_frontend/jsview/js_view_context.h"
69  #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
70  #include "canvas_napi/js_canvas.h"
71  #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
72  #include "interfaces/inner_api/ui_session/ui_session_manager.h"
73  #endif
74  #include "core/common/resource/resource_manager.h"
75  #include "core/common/resource/resource_object.h"
76  #include "core/components/common/layout/constants.h"
77  #include "core/components/common/layout/position_param.h"
78  #include "core/components/common/layout/screen_system_manager.h"
79  #include "core/components/common/properties/animation_option.h"
80  #include "core/components/common/properties/border_image.h"
81  #include "core/components/common/properties/color.h"
82  #include "core/components/common/properties/decoration.h"
83  #include "core/components/common/properties/shadow.h"
84  #include "core/components/common/properties/invert.h"
85  #include "core/components/common/properties/shadow_config.h"
86  #include "core/components/theme/resource_adapter.h"
87  #include "core/components/theme/shadow_theme.h"
88  #include "core/components_ng/base/view_abstract.h"
89  #include "core/components_ng/base/view_abstract_model.h"
90  #include "core/components_ng/base/view_stack_processor.h"
91  #include "core/components_ng/event/focus_box.h"
92  #include "core/components_ng/gestures/base_gesture_event.h"
93  #include "core/components_ng/pattern/menu/menu_pattern.h"
94  #include "core/components_ng/pattern/overlay/modal_style.h"
95  #include "core/components_ng/pattern/overlay/sheet_style.h"
96  #include "core/components_ng/property/grid_property.h"
97  #include "core/components_ng/property/safe_area_insets.h"
98  #include "core/gestures/gesture_info.h"
99  #include "core/image/image_source_info.h"
100  #ifdef PLUGIN_COMPONENT_SUPPORTED
101  #include "core/common/plugin_manager.h"
102  #endif
103  #include "interfaces/native/node/resource.h"
104  
105  #include "core/common/card_scope.h"
106  #include "core/common/container.h"
107  #include "core/common/resource/resource_configuration.h"
108  #include "core/components/progress/progress_theme.h"
109  #include "core/components_ng/base/view_abstract_model_ng.h"
110  #include "core/components_ng/base/view_stack_model.h"
111  #include "core/components_ng/property/progress_mask_property.h"
112  
113  namespace OHOS::Ace {
114  namespace {
115  const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
116  const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
117  constexpr int32_t DIRECTION_COUNT = 4;
118  constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
119  constexpr int NUM1 = 1;
120  const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
121      HoverModeAreaType::BOTTOM_SCREEN };
122  } // namespace
123  
124  std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
125  std::mutex ViewAbstractModel::mutex_;
126  using DoubleBindCallback = std::function<void(const std::string&)>;
127  
GetInstance()128  ViewAbstractModel* ViewAbstractModel::GetInstance()
129  {
130      if (!instance_) {
131          std::lock_guard<std::mutex> lock(mutex_);
132          if (!instance_) {
133  #ifdef NG_BUILD
134              instance_.reset(new NG::ViewAbstractModelNG());
135  #else
136              if (Container::IsCurrentUseNewPipeline()) {
137                  instance_.reset(new NG::ViewAbstractModelNG());
138              } else {
139                  instance_.reset(new Framework::ViewAbstractModelImpl());
140              }
141  #endif
142          }
143      }
144      return instance_.get();
145  }
146  
147  } // namespace OHOS::Ace
148  
149  namespace OHOS::Ace::Framework {
150  namespace {
151  
152  constexpr uint32_t DEFAULT_DURATION = 1000; // ms
153  constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
154  constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
155  constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
156  constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
157  constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
158  constexpr int32_t MAX_ALIGN_VALUE = 8;
159  constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
160  constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
161  const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
162  const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
163  constexpr double FULL_DIMENSION = 100.0;
164  constexpr double HALF_DIMENSION = 50.0;
165  constexpr double ROUND_UNIT = 360.0;
166  constexpr double VISIBLE_RATIO_MIN = 0.0;
167  constexpr double VISIBLE_RATIO_MAX = 1.0;
168  constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
169  constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
170  constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
171  constexpr int32_t SECOND_INDEX = 2;
172  constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
173  constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
174  constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
175  constexpr float MAX_ANGLE = 360.0f;
176  constexpr float DEFAULT_BIAS = 0.5f;
177  constexpr float DEFAULT_LAYOUT_WEIGHT = 0.0f;
178  const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
179  const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
180  const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
181  const std::string SHEET_HEIGHT_MEDIUM = "medium";
182  const std::string SHEET_HEIGHT_LARGE = "large";
183  const std::string SHEET_HEIGHT_AUTO = "auto";
184  const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
185  const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
186  const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
187  const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
188  const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
189  const std::vector<int32_t> LENGTH_METRICS_KEYS {
190      static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
191      static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
192  const char* START_PROPERTY = "start";
193  const char* END_PROPERTY = "end";
194  const char* TOP_PROPERTY = "top";
195  const char* BOTTOM_PROPERTY = "bottom";
196  const char* LEFT_PROPERTY = "left";
197  const char* RIGHT_PROPERTY = "right";
198  const char* TOP_START_PROPERTY = "topStart";
199  const char* TOP_END_PROPERTY = "topEnd";
200  const char* BOTTOM_START_PROPERTY = "bottomStart";
201  const char* BOTTOM_END_PROPERTY = "bottomEnd";
202  const char* DEBUG_LINE_INFO_LINE = "$line";
203  const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
204  
205  constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
206  constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
207  constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
208  
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)209  void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
210      CalcDimension& centerX, CalcDimension& centerY)
211  {
212      double xVal = 1.0;
213      double yVal = 1.0;
214      double zVal = 1.0;
215      if (!jsValue->IsObject()) {
216          scaleX = static_cast<float>(xVal);
217          scaleY = static_cast<float>(yVal);
218          scaleZ = static_cast<float>(zVal);
219          CalcDimension length;
220          centerX = length;
221          centerY = length;
222          return;
223      }
224      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
225      JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
226      JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
227      JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
228      scaleX = static_cast<float>(xVal);
229      scaleY = static_cast<float>(yVal);
230      scaleZ = static_cast<float>(zVal);
231      // if specify centerX
232      JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
233      // if specify centerY
234      JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
235  }
236  
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)237  void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
238      CalcDimension& translateZ)
239  {
240      if (!jsValue->IsObject()) {
241          return;
242      }
243      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
244      JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
245      JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
246      JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
247  }
248  
GetDefaultRotateVector(double & dx,double & dy,double & dz)249  void GetDefaultRotateVector(double& dx, double& dy, double& dz)
250  {
251      dx = 0.0;
252      dy = 0.0;
253      dz = 0.0;
254      if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
255          dz = 1.0;
256      }
257  }
258  
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)259  void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
260  {
261      if (!jsValue->IsObject()) {
262          return;
263      }
264      // default: dx, dy, dz (0.0, 0.0, 0.0)
265      double dxVal = 0.0;
266      double dyVal = 0.0;
267      double dzVal = 0.0;
268      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
269      auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
270      auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
271      auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
272      if (jsRotateX->IsUndefined()
273          && jsRotateY->IsUndefined()
274          && jsRotateZ->IsUndefined()) {
275          GetDefaultRotateVector(dxVal, dyVal, dzVal);
276      } else {
277          JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
278          JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
279          JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
280      }
281      rotate.xDirection = static_cast<float>(dxVal);
282      rotate.yDirection = static_cast<float>(dyVal);
283      rotate.zDirection = static_cast<float>(dzVal);
284      // if specify centerX
285      if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
286          rotate.centerX)) {
287          rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
288      }
289      // if specify centerY
290      if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
291          rotate.centerY)) {
292          rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
293      }
294      // if specify centerZ
295      if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
296          rotate.centerZ)) {
297          rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
298      }
299      // if specify angle
300      JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
301      rotate.perspective = 0.0f;
302      JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
303  }
304  
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)305  bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
306  {
307      if (!jsValue->IsObject()) {
308          return false;
309      }
310  
311      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
312      auto path = jsObj->GetPropertyValue<std::string>("path", "");
313      if (path.empty()) {
314          return false;
315      }
316      option.SetPath(path);
317      double from = 0.0;
318      double to = 1.0;
319      JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
320      JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
321      if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
322          from = 0.0;
323      }
324      if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
325          to = 1.0;
326      } else if (to < from) {
327          to = from;
328      }
329      option.SetBegin(static_cast<float>(from));
330      option.SetEnd(static_cast<float>(to));
331      option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
332      return true;
333  }
334  
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)335  void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
336  {
337      if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::AUTO)) {
338          previewOption.ResetDragPreviewMode();
339          isAuto = true;
340          return;
341      } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE)) {
342          previewOption.isScaleEnabled = false;
343      } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW)) {
344          previewOption.isDefaultShadowEnabled = true;
345      } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS)) {
346          previewOption.isDefaultRadiusEnabled = true;
347      }
348      isAuto = false;
349  }
350  
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)351  void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
352      BackgroundImagePosition& bgImgPosition)
353  {
354      AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
355      bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
356      bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
357  }
358  
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)359  std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
360  {
361      auto index = pos + containCount;
362      if (index < 0) {
363          return std::string();
364      }
365  
366      JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
367      if (type == "d") {
368          if (item->IsNumber()) {
369              return std::to_string(item->ToNumber<int32_t>());
370          } else if (item->IsObject()) {
371              int32_t result = 0;
372              JSViewAbstract::ParseJsInteger(item, result);
373              return std::to_string(result);
374          }
375      } else if (type == "s") {
376          if (item->IsString()) {
377              return item->ToString();
378          } else if (item->IsObject()) {
379              std::string result;
380              JSViewAbstract::ParseJsString(item, result);
381              return result;
382          }
383      } else if (type == "f") {
384          if (item->IsNumber()) {
385              return std::to_string(item->ToNumber<float>());
386          } else if (item->IsObject()) {
387              double result = 0.0;
388              JSViewAbstract::ParseJsDouble(item, result);
389              return std::to_string(result);
390          }
391      }
392      return std::string();
393  }
394  
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)395  void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
396  {
397      auto size = static_cast<int32_t>(params->Length());
398      if (containCount == size) {
399          return;
400      }
401      std::string::const_iterator start = originStr.begin();
402      std::string::const_iterator end = originStr.end();
403      std::smatch matches;
404      bool shortHolderType = false;
405      bool firstMatch = true;
406      int searchTime = 0;
407      while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
408          std::string pos = matches[2];
409          std::string type = matches[4];
410          if (firstMatch) {
411              firstMatch = false;
412              shortHolderType = pos.length() == 0;
413          } else {
414              if (shortHolderType ^ (pos.length() == 0)) {
415                  return;
416              }
417          }
418  
419          std::string replaceContentStr;
420          if (shortHolderType) {
421              replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
422          } else {
423              replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
424          }
425  
426          originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
427          start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
428          end = originStr.end();
429          searchTime++;
430      }
431  }
432  
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)433  bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
434  {
435      JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
436      JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
437      bool hasX = false;
438      bool hasY = false;
439      if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
440          hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
441          hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
442      } else {
443          hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
444          hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
445      }
446      return hasX || hasY;
447  }
448  
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)449  bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
450  {
451      bool useEdges = false;
452      CalcDimension top;
453      CalcDimension left;
454      CalcDimension bottom;
455      CalcDimension right;
456      JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
457      JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
458      JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
459      JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
460      if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
461          edges.SetTop(top);
462          useEdges = true;
463      }
464      if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
465          edges.SetLeft(left);
466          useEdges = true;
467      }
468      if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
469          edges.SetBottom(bottom);
470          useEdges = true;
471      }
472      if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
473          edges.SetRight(right);
474          useEdges = true;
475      }
476      return useEdges;
477  }
478  
ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)479  bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result)
480  {
481      auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
482      if (!value->IsNumber()) {
483          return false;
484      }
485      auto unit = DimensionUnit::VP;
486      auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
487      if (jsUnit->IsNumber()) {
488          unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
489      }
490      CalcDimension dimension(value->ToNumber<double>(), unit);
491      result = dimension;
492      return true;
493  }
494  
CheckLengthMetrics(const JSRef<JSObject> & object)495  bool CheckLengthMetrics(const JSRef<JSObject>& object)
496  {
497      if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
498          object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
499          object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
500          object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
501          object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
502          object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
503          return true;
504      }
505      auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
506      if (jsTop->IsObject()) {
507          JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
508          if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
509              return true;
510          }
511      }
512      auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
513      if (jsBottom->IsObject()) {
514          JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
515          if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
516              return true;
517          }
518      }
519      return false;
520  }
521  
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)522  bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
523  {
524      bool useLocalizedEdges = false;
525      CalcDimension start;
526      CalcDimension end;
527      CalcDimension top;
528      CalcDimension bottom;
529  
530      JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
531      if (startVal->IsObject()) {
532          JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
533          ParseJsLengthMetrics(startObj, start);
534          edges.SetLeft(start);
535          useLocalizedEdges = true;
536      }
537      JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
538      if (endVal->IsObject()) {
539          JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
540          ParseJsLengthMetrics(endObj, end);
541          edges.SetRight(end);
542          useLocalizedEdges = true;
543      }
544      JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
545      if (topVal->IsObject()) {
546          JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
547          ParseJsLengthMetrics(topObj, top);
548          edges.SetTop(top);
549          useLocalizedEdges = true;
550      }
551      JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
552      if (bottomVal->IsObject()) {
553          JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(bottomVal);
554          ParseJsLengthMetrics(bottomObj, bottom);
555          edges.SetBottom(bottom);
556          useLocalizedEdges = true;
557      }
558      return useLocalizedEdges;
559  }
560  
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)561  bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
562  {
563      bool useMarkAnchorPosition = false;
564      CalcDimension start;
565      CalcDimension top;
566  
567      JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
568      if (startVal->IsObject()) {
569          JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
570          ParseJsLengthMetrics(startObj, start);
571          x = start;
572          useMarkAnchorPosition = true;
573      }
574      JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
575      if (topVal->IsObject()) {
576          JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
577          ParseJsLengthMetrics(topObj, top);
578          y = top;
579          useMarkAnchorPosition = true;
580      }
581      return useMarkAnchorPosition;
582  }
583  
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)584  RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
585  {
586      JSRef<JSVal> builder;
587      if (info->IsObject()) {
588          auto builderObj = JSRef<JSObject>::Cast(info);
589          builder = builderObj->GetProperty("builder");
590      } else if (info->IsFunction()) {
591          builder = info;
592      } else {
593          return nullptr;
594      }
595  
596      if (!builder->IsFunction()) {
597          return nullptr;
598      }
599  
600      return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
601  }
602  
603  RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
604      const JSRef<JSObject>& object, const JSExecutionContext& context);
605  
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)606  RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
607      const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
608  {
609      RefPtr<NG::ChainedTransitionEffect> effect;
610      if (effectOption->IsObject()) {
611          NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
612          std::optional<float> angle;
613          ParseJsRotate(effectOption, rotate, angle);
614          if (angle.has_value()) {
615              rotate.angle = angle.value();
616              return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
617          }
618      }
619      return nullptr;
620  }
621  
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)622  RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
623      const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
624  {
625      double opacity = 1.0;
626      if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
627          if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
628              if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
629                  opacity = 1.0;
630              }
631          } else {
632              opacity = std::clamp(opacity, 0.0, 1.0);
633          }
634          return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
635      }
636      return nullptr;
637  }
638  
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)639  RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
640      const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
641  {
642      if (effectOption->IsObject()) {
643          // default: x, y, z (0.0, 0.0, 0.0)
644          NG::TranslateOptions translate;
645          ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
646          return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
647      }
648      return nullptr;
649  }
650  
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)651  RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
652      const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
653  {
654      if (effectOption->IsObject()) {
655          // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
656          NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
657          ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
658          return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
659      }
660      return nullptr;
661  }
662  
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)663  RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
664      const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
665  {
666      int32_t edge = 0;
667      if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
668          if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
669              edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
670              edge = static_cast<int32_t>(NG::TransitionEdge::START);
671          }
672          return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
673      }
674      return nullptr;
675  }
676  
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)677  RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
678      const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
679  {
680      if (effectOption->IsObject()) {
681          auto effectObj = JSRef<JSObject>::Cast(effectOption);
682          auto appearJsVal = effectObj->GetProperty("appear");
683          auto disappearJsVal = effectObj->GetProperty("disappear");
684          RefPtr<NG::ChainedTransitionEffect> appearEffect;
685          RefPtr<NG::ChainedTransitionEffect> disappearEffect;
686          if (appearJsVal->IsObject()) {
687              auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
688              appearEffect = ParseChainedTransition(appearObj, context);
689          }
690          if (disappearJsVal->IsObject()) {
691              auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
692              disappearEffect = ParseChainedTransition(disappearObj, context);
693          }
694          return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
695      }
696      return nullptr;
697  }
698  
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)699  int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
700  {
701      CHECK_NULL_RETURN(pipelineContext, 0);
702      return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
703  }
704  
705  using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
706      const JSRef<JSVal>&, const JSExecutionContext&);
707  
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)708  RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
709      const JSRef<JSObject>& object, const JSExecutionContext& context)
710  {
711      auto propType = object->GetProperty("type_");
712      if (!propType->IsString()) {
713          return nullptr;
714      }
715      std::string type = propType->ToString();
716      auto propEffectOption = object->GetProperty("effect_");
717      auto propAnimationOption = object->GetProperty("animation_");
718      auto propSuccessor = object->GetProperty("successor_");
719      static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
720          { "asymmetric", ParseChainedAsymmetricTransition },
721          { "identity",
722              [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
723                  -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
724          { "move", ParseChainedMoveTransition },
725          { "opacity", ParseChainedOpacityTransition },
726          { "rotate", ParseChainedRotateTransition },
727          { "scale", ParseChainedScaleTransition },
728          { "slideSwitch",
729              [](const JSRef<JSVal>& effectOption,
730                  const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
731                  return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
732              } },
733          { "translate", ParseChainedTranslateTransition },
734      };
735      int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
736      if (index < 0) {
737          return nullptr;
738      }
739      RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
740      if (!result) {
741          return nullptr;
742      }
743      if (propAnimationOption->IsObject()) {
744          auto container = Container::Current();
745          CHECK_NULL_RETURN(container, nullptr);
746          auto pipelineContext = container->GetPipelineContext();
747          CHECK_NULL_RETURN(pipelineContext, nullptr);
748          auto animationOptionResult = std::make_shared<AnimationOption>(
749              JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender()));
750          // The maximum of the form-animation-playback duration value is 1000 ms.
751          if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) {
752              auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
753              // If the duration exceeds 1000ms, init it to 0 ms.
754              if (formAnimationTimeInterval > DEFAULT_DURATION) {
755                  animationOptionResult->SetDuration(0);
756              } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
757                  // If remaining time is less than 1000ms, check for update duration.
758                  animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
759                  TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation]  Form Transition SetDuration: %{public}lld ms",
760                      static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
761              }
762          }
763          auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
764          JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
765          auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
766          if (onFinish->IsFunction()) {
767              RefPtr<JsFunction> jsFunc =
768                  AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
769              std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
770                                                        id = Container::CurrentId(), node = targetNode]() {
771                  ContainerScope scope(id);
772                  JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
773                  PipelineContext::SetCallBackNode(node);
774                  func->Execute();
775              };
776              animationOptionResult->SetOnFinishEvent(onFinishEvent);
777          }
778          result->SetAnimationOption(animationOptionResult);
779      }
780      if (propSuccessor->IsObject()) {
781          result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
782      }
783      return result;
784  }
785  
786  #ifndef WEARABLE_PRODUCT
787  const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
788      Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
789      Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
790  
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)791  DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
792  {
793      JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
794      if (!changeEvent->IsFunction()) {
795          return {};
796      }
797      RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
798      WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
799      auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
800                          const std::string& param) {
801          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
802          if (param != "true" && param != "false") {
803              return;
804          }
805          PipelineContext::SetCallBackNode(node);
806          bool newValue = StringToBool(param);
807          JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
808          func->ExecuteJS(1, &newJSVal);
809      };
810      return callback;
811  }
812  
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)813  void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
814  {
815      auto colorValue = messageOptionsObj->GetProperty("textColor");
816      Color textColor;
817      if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
818          if (popupParam) {
819              popupParam->SetTextColor(textColor);
820          }
821      }
822  
823      auto font = messageOptionsObj->GetProperty("font");
824      if (!font->IsNull() && font->IsObject()) {
825          JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
826          auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
827          CalcDimension fontSize;
828          if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
829              if (popupParam && fontSize.IsValid()) {
830                  popupParam->SetFontSize(fontSize);
831              }
832          }
833          auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
834          if (fontWeightValue->IsString()) {
835              if (popupParam) {
836                  popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
837              }
838          }
839          auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
840          if (fontStyleValue->IsNumber()) {
841              int32_t value = fontStyleValue->ToNumber<int32_t>();
842              if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
843                  return;
844              }
845              if (popupParam) {
846                  popupParam->SetFontStyle(FONT_STYLES[value]);
847              }
848          }
849      }
850  }
851  
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)852  void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
853  {
854      JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
855      if (placementOnTopVal->IsBoolean() && popupParam) {
856          popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
857      }
858  }
859  
IsPopupCreated()860  bool IsPopupCreated()
861  {
862      auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
863      CHECK_NULL_RETURN(targetNode, false);
864      auto targetId = targetNode->GetId();
865      auto container = Container::Current();
866      CHECK_NULL_RETURN(container, false);
867      auto pipelineContext = container->GetPipelineContext();
868      CHECK_NULL_RETURN(pipelineContext, false);
869      auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
870      CHECK_NULL_RETURN(context, false);
871      auto overlayManager = context->GetOverlayManager();
872      CHECK_NULL_RETURN(overlayManager, false);
873      auto popupInfo = overlayManager->GetPopupInfo(targetId);
874      if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
875          return false;
876      }
877      return true;
878  }
879  
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)880  void ParsePopupCommonParam(
881      const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
882  {
883      auto arrowOffset = popupObj->GetProperty("arrowOffset");
884      CalcDimension offset;
885      if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
886          if (popupParam) {
887              popupParam->SetArrowOffset(offset);
888          }
889      }
890  
891      auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
892      if (arrowPointPosition->IsString()) {
893          char* pEnd = nullptr;
894          auto arrowString = arrowPointPosition->ToString();
895          std::strtod(arrowString.c_str(), &pEnd);
896          if (pEnd != nullptr) {
897              if (std::strcmp(pEnd, "Start") == 0) {
898                  offset = ARROW_ZERO_PERCENT_VALUE;
899              }
900              if (std::strcmp(pEnd, "Center") == 0) {
901                  offset = ARROW_HALF_PERCENT_VALUE;
902              }
903              if (std::strcmp(pEnd, "End") == 0) {
904                  offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
905              }
906              if (popupParam) {
907                  popupParam->SetArrowOffset(offset);
908              }
909          }
910      }
911  
912      auto targetSpace = popupObj->GetProperty("targetSpace");
913      if (!targetSpace->IsNull()) {
914          CalcDimension space;
915          if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
916              if (popupParam) {
917                  popupParam->SetTargetSpace(space);
918              }
919          }
920      }
921  
922      JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
923      if (showInSubWindowValue->IsBoolean()) {
924          bool showInSubBoolean = showInSubWindowValue->ToBoolean();
925  #if defined(PREVIEW)
926          if (showInSubBoolean) {
927              LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
928              showInSubBoolean = false;
929          }
930  #endif
931          if (popupParam) {
932              popupParam->SetShowInSubWindow(showInSubBoolean);
933          }
934      }
935  
936      auto placementValue = popupObj->GetProperty("placement");
937      if (placementValue->IsNumber()) {
938          auto placement = placementValue->ToNumber<int32_t>();
939          if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
940              popupParam->SetPlacement(PLACEMENT[placement]);
941          }
942      } else {
943          SetPlacementOnTopVal(popupObj, popupParam);
944      }
945  
946      auto enableArrowValue = popupObj->GetProperty("enableArrow");
947      if (enableArrowValue->IsBoolean()) {
948          popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
949      }
950  
951      auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
952      if (followTransformOfTargetValue->IsBoolean()) {
953          popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
954      }
955  
956      JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
957      if (maskValue->IsBoolean()) {
958          if (popupParam) {
959              popupParam->SetBlockEvent(maskValue->ToBoolean());
960          }
961      }
962      if (maskValue->IsObject()) {
963          auto maskObj = JSRef<JSObject>::Cast(maskValue);
964          auto colorValue = maskObj->GetProperty("color");
965          Color maskColor;
966          if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
967              popupParam->SetMaskColor(maskColor);
968          }
969      }
970  
971      JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
972      if (onStateChangeVal->IsFunction()) {
973          std::vector<std::string> keys = { "isVisible" };
974          RefPtr<JsFunction> jsFunc =
975              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
976          auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
977          if (popupParam) {
978              auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
979                                               node = targetNode](const std::string& param) {
980                  JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
981                  ACE_SCORING_EVENT("Popup.onStateChange");
982                  PipelineContext::SetCallBackNode(node);
983                  func->Execute(keys, param);
984              };
985              popupParam->SetOnStateChange(onStateChangeCallback);
986          }
987      }
988  
989      auto offsetVal = popupObj->GetProperty("offset");
990      if (offsetVal->IsObject()) {
991          auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
992          auto xVal = offsetObj->GetProperty("x");
993          auto yVal = offsetObj->GetProperty("y");
994          Offset popupOffset;
995          CalcDimension dx;
996          CalcDimension dy;
997          if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
998              popupOffset.SetX(dx.ConvertToPx());
999          }
1000          if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
1001              popupOffset.SetY(dy.ConvertToPx());
1002          }
1003          if (popupParam) {
1004              popupParam->SetTargetOffset(popupOffset);
1005          }
1006      }
1007  
1008      Color backgroundColor;
1009      auto popupColorVal = popupObj->GetProperty("popupColor");
1010      if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
1011          popupParam->SetBackgroundColor(backgroundColor);
1012      }
1013  
1014      auto autoCancelVal = popupObj->GetProperty("autoCancel");
1015      if (autoCancelVal->IsBoolean()) {
1016          popupParam->SetHasAction(!autoCancelVal->ToBoolean());
1017      }
1018  
1019      auto childWidthVal = popupObj->GetProperty("width");
1020      if (!childWidthVal->IsNull()) {
1021          CalcDimension width;
1022          if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
1023              if (width.Value() > 0) {
1024                  popupParam->SetChildWidth(width);
1025              }
1026          }
1027      }
1028  
1029      auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
1030      if (!arrowWidthVal->IsNull()) {
1031          bool setError = true;
1032          CalcDimension arrowWidth;
1033          if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
1034              if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
1035                  popupParam->SetArrowWidth(arrowWidth);
1036                  setError = false;
1037              }
1038          }
1039          popupParam->SetErrorArrowWidth(setError);
1040      }
1041  
1042      auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
1043      if (!arrowHeightVal->IsNull()) {
1044          bool setError = true;
1045          CalcDimension arrowHeight;
1046          if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
1047              if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
1048                  popupParam->SetArrowHeight(arrowHeight);
1049                  setError = false;
1050              }
1051          }
1052          popupParam->SetErrorArrowHeight(setError);
1053      }
1054  
1055      auto radiusVal = popupObj->GetProperty("radius");
1056      if (!radiusVal->IsNull()) {
1057          bool setError = true;
1058          CalcDimension radius;
1059          if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
1060              if (radius.Value() >= 0) {
1061                  popupParam->SetRadius(radius);
1062                  setError = false;
1063              }
1064          }
1065          popupParam->SetErrorRadius(setError);
1066      }
1067  
1068      Shadow shadow;
1069      auto shadowVal = popupObj->GetProperty("shadow");
1070      if (shadowVal->IsObject() || shadowVal->IsNumber()) {
1071          auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
1072          if (!ret) {
1073              JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1074          }
1075      } else {
1076          JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1077      }
1078      popupParam->SetShadow(shadow);
1079  
1080      auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
1081      if (blurStyleValue->IsNumber()) {
1082          auto blurStyle = blurStyleValue->ToNumber<int32_t>();
1083          if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1084              blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1085              popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
1086          }
1087      }
1088  
1089      auto popupTransition = popupObj->GetProperty("transition");
1090      if (popupTransition->IsObject()) {
1091          popupParam->SetHasTransition(true);
1092          auto obj = JSRef<JSObject>::Cast(popupTransition);
1093          auto effects = ParseChainedTransition(obj, info.GetExecutionContext());
1094          popupParam->SetTransitionEffects(effects);
1095      }
1096  }
1097  
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1098  void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1099  {
1100      ParsePopupCommonParam(info, popupObj, popupParam);
1101      JSRef<JSVal> messageVal = popupObj->GetProperty("message");
1102      if (popupParam) {
1103          popupParam->SetMessage(messageVal->ToString());
1104      }
1105  
1106      auto messageOptions = popupObj->GetProperty("messageOptions");
1107      JSRef<JSObject> messageOptionsObj;
1108      if (!messageOptions->IsNull() && messageOptions->IsObject()) {
1109          messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
1110          SetPopupMessageOptions(messageOptionsObj, popupParam);
1111      }
1112  
1113      JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
1114      if (primaryButtonVal->IsObject()) {
1115          ButtonProperties properties;
1116          JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
1117          JSRef<JSVal> value = obj->GetProperty("value");
1118          if (value->IsString()) {
1119              properties.value = value->ToString();
1120          }
1121  
1122          JSRef<JSVal> actionValue = obj->GetProperty("action");
1123          if (actionValue->IsFunction()) {
1124              auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1125              auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1126              if (popupParam) {
1127                  auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1128                                           node = targetNode](GestureEvent& info) {
1129                      JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1130                      ACE_SCORING_EVENT("primaryButton.action");
1131                      PipelineContext::SetCallBackNode(node);
1132                      func->Execute(info);
1133                  };
1134                  properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1135              }
1136          }
1137          properties.showButton = true;
1138          if (popupParam) {
1139              popupParam->SetPrimaryButtonProperties(properties);
1140          }
1141      }
1142  
1143      JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
1144      if (secondaryButtonVal->IsObject()) {
1145          ButtonProperties properties;
1146          JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
1147          JSRef<JSVal> value = obj->GetProperty("value");
1148          if (value->IsString()) {
1149              properties.value = value->ToString();
1150          }
1151  
1152          JSRef<JSVal> actionValue = obj->GetProperty("action");
1153          if (actionValue->IsFunction()) {
1154              auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1155              auto targetNode =
1156                  AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1157              if (popupParam) {
1158                  auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1159                                           node = targetNode](GestureEvent& info) {
1160                      JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1161                      ACE_SCORING_EVENT("secondaryButton.action");
1162                      PipelineContext::SetCallBackNode(node);
1163                      func->Execute(info);
1164                  };
1165                  properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1166              }
1167          }
1168          properties.showButton = true;
1169          if (popupParam) {
1170              popupParam->SetSecondaryButtonProperties(properties);
1171          }
1172      }
1173  }
1174  
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1175  void ParseCustomPopupParam(
1176      const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1177  {
1178      auto builderValue = popupObj->GetProperty("builder");
1179      if (!builderValue->IsObject()) {
1180          return;
1181      }
1182      if (!builderValue->IsFunction()) {
1183          JSRef<JSObject> builderObj;
1184          builderObj = JSRef<JSObject>::Cast(builderValue);
1185          auto builder = builderObj->GetProperty("builder");
1186          if (!builder->IsFunction()) {
1187              return;
1188          }
1189          auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1190          if (!builderFunc) {
1191              return;
1192          }
1193      }
1194      if (popupParam) {
1195          popupParam->SetUseCustomComponent(true);
1196      }
1197  
1198      auto focusableValue = popupObj->GetProperty("focusable");
1199      if (focusableValue->IsBoolean()) {
1200          popupParam->SetFocusable(focusableValue->ToBoolean());
1201      }
1202  
1203      ParsePopupCommonParam(info, popupObj, popupParam);
1204  }
1205  #endif
1206  
GetBundleNameFromContainer()1207  std::string GetBundleNameFromContainer()
1208  {
1209      auto container = Container::Current();
1210      CHECK_NULL_RETURN(container, "");
1211      return container->GetBundleName();
1212  }
1213  
GetModuleNameFromContainer()1214  std::string GetModuleNameFromContainer()
1215  {
1216      auto container = Container::Current();
1217      CHECK_NULL_RETURN(container, "");
1218      return container->GetModuleName();
1219  }
1220  
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)1221  void CompleteResourceObjectFromParams(
1222      int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
1223  {
1224      JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
1225      int32_t typeNum = -1;
1226      if (type->IsNumber()) {
1227          typeNum = type->ToNumber<int32_t>();
1228      }
1229  
1230      JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1231      if (!args->IsArray()) {
1232          return;
1233      }
1234      JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1235      if (resId != UNKNOWN_RESOURCE_ID) {
1236          return;
1237      }
1238      JSRef<JSVal> identity = params->GetValueAt(0);
1239  
1240      bool isParseDollarResourceSuccess =
1241          JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
1242      if (!isParseDollarResourceSuccess) {
1243          return;
1244      }
1245  
1246      std::regex resNameRegex(RESOURCE_NAME_PATTERN);
1247      std::smatch resNameResults;
1248      if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
1249          jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
1250      }
1251  
1252      if (typeNum == UNKNOWN_RESOURCE_TYPE) {
1253          jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1254      }
1255  }
1256  
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)1257  void CompleteResourceObjectFromId(
1258      JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
1259  {
1260      JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1261      if (!args->IsArray()) {
1262          return;
1263      }
1264      JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1265      auto paramCount = params->Length();
1266      JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
1267      if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
1268          std::vector<JSRef<JSVal>> tmpParams;
1269          for (uint32_t i = 0; i < paramCount; i++) {
1270              auto param = params->GetValueAt(i);
1271              tmpParams.insert(tmpParams.end(), param);
1272          }
1273          params->SetValueAt(0, name);
1274          uint32_t paramIndex = 1;
1275          if (!type->IsEmpty()) {
1276              params->SetValueAt(paramIndex, type);
1277              paramIndex++;
1278          }
1279          for (auto tmpParam : tmpParams) {
1280              params->SetValueAt(paramIndex, tmpParam);
1281              paramIndex++;
1282          }
1283      } else {
1284          params->SetValueAt(0, name);
1285      }
1286      jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
1287      jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1288      if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
1289          jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1290      }
1291      if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
1292          jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1293      }
1294  }
1295  
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)1296  void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
1297  {
1298      if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
1299          checkDimension.Reset();
1300          return;
1301      }
1302      if (notNegative && checkDimension.IsNegative()) {
1303          checkDimension.Reset();
1304          return;
1305      }
1306  }
1307  
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1308  void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1309  {
1310      Color left;
1311      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1312          commonColor.left = left;
1313      }
1314      Color right;
1315      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1316          commonColor.right = right;
1317      }
1318      Color top;
1319      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1320          commonColor.top = top;
1321      }
1322      Color bottom;
1323      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1324          commonColor.bottom = bottom;
1325      }
1326  }
1327  
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1328  void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1329  {
1330      Color start;
1331      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
1332          localizedColor.start = start;
1333      }
1334      Color end;
1335      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
1336          localizedColor.end = end;
1337      }
1338      Color top;
1339      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1340          localizedColor.top = top;
1341      }
1342      Color bottom;
1343      if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1344          localizedColor.bottom = bottom;
1345      }
1346  }
1347  
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1348  bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1349  {
1350      if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1351          object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1352          LocalizedColor localizedColor;
1353          ParseLocalizedEdgeColors(object, localizedColor);
1354          commonColor.top = localizedColor.top;
1355          commonColor.bottom = localizedColor.bottom;
1356          commonColor.left = localizedColor.start;
1357          commonColor.right = localizedColor.end;
1358          return true;
1359      }
1360      ParseEdgeColors(object, commonColor);
1361      return false;
1362  }
1363  
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1364  void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1365  {
1366      CalcDimension left;
1367      if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(LEFT_PROPERTY), left)) {
1368          CheckDimensionUnit(left, true, notNegative);
1369          commonCalcDimension.left = left;
1370      }
1371      CalcDimension right;
1372      if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(RIGHT_PROPERTY), right)) {
1373          CheckDimensionUnit(right, true, notNegative);
1374          commonCalcDimension.right = right;
1375      }
1376      CalcDimension top;
1377      if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(TOP_PROPERTY), top)) {
1378          CheckDimensionUnit(top, true, notNegative);
1379          commonCalcDimension.top = top;
1380      }
1381      CalcDimension bottom;
1382      if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(BOTTOM_PROPERTY), bottom)) {
1383          CheckDimensionUnit(bottom, true, notNegative);
1384          commonCalcDimension.bottom = bottom;
1385      }
1386  }
1387  
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1388  void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1389      bool notNegative, CalcDimension defaultValue)
1390  {
1391      CalcDimension left;
1392      if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
1393          CheckDimensionUnit(left, notPercent, notNegative);
1394          commonCalcDimension.left = left;
1395      } else {
1396          commonCalcDimension.left = defaultValue;
1397      }
1398      CalcDimension right;
1399      if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
1400          CheckDimensionUnit(right, notPercent, notNegative);
1401          commonCalcDimension.right = right;
1402      } else {
1403          commonCalcDimension.right = defaultValue;
1404      }
1405      CalcDimension top;
1406      if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
1407          CheckDimensionUnit(top, notPercent, notNegative);
1408          commonCalcDimension.top = top;
1409      } else {
1410          commonCalcDimension.top = defaultValue;
1411      }
1412      CalcDimension bottom;
1413      if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
1414          CheckDimensionUnit(bottom, false, true);
1415          commonCalcDimension.bottom = bottom;
1416      } else {
1417          commonCalcDimension.bottom = defaultValue;
1418      }
1419  }
1420  
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1421  void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
1422                                bool notNegative)
1423  {
1424      auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
1425      if (jsStart->IsObject()) {
1426          JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
1427          CalcDimension calcDimension;
1428          if (ParseJsLengthMetrics(startObj, calcDimension)) {
1429              CheckDimensionUnit(calcDimension, true, notNegative);
1430              localizedCalcDimension.start = calcDimension;
1431          }
1432      }
1433      auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
1434      if (jsEnd->IsObject()) {
1435          JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
1436          CalcDimension calcDimension;
1437          if (ParseJsLengthMetrics(endObj, calcDimension)) {
1438              CheckDimensionUnit(calcDimension, true, notNegative);
1439              localizedCalcDimension.end = calcDimension;
1440          }
1441      }
1442      auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
1443      if (jsTop->IsObject()) {
1444          JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
1445          CalcDimension calcDimension;
1446          if (ParseJsLengthMetrics(topObj, calcDimension)) {
1447              CheckDimensionUnit(calcDimension, true, notNegative);
1448              localizedCalcDimension.top = calcDimension;
1449          }
1450      }
1451      auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
1452      if (jsBottom->IsObject()) {
1453          JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
1454          CalcDimension calcDimension;
1455          if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1456              CheckDimensionUnit(calcDimension, true, notNegative);
1457              localizedCalcDimension.bottom = calcDimension;
1458          }
1459      }
1460  }
1461  
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1462  void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
1463  {
1464      if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
1465          JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
1466          CalcDimension calcDimension;
1467          if (ParseJsLengthMetrics(startObj, calcDimension)) {
1468              CheckDimensionUnit(calcDimension, false, true);
1469              localizedCalcDimension.start = calcDimension;
1470          }
1471      }
1472      if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1473          JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1474          CalcDimension calcDimension;
1475          if (ParseJsLengthMetrics(endObj, calcDimension)) {
1476              CheckDimensionUnit(calcDimension, false, true);
1477              localizedCalcDimension.end = calcDimension;
1478          }
1479      }
1480      if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1481          JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1482          CalcDimension calcDimension;
1483          if (ParseJsLengthMetrics(topObj, calcDimension)) {
1484              CheckDimensionUnit(calcDimension, false, true);
1485              localizedCalcDimension.top = calcDimension;
1486          }
1487      }
1488      if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1489          JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1490          CalcDimension calcDimension;
1491          if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1492              CheckDimensionUnit(calcDimension, false, true);
1493              localizedCalcDimension.bottom = calcDimension;
1494          }
1495      }
1496  }
1497  
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1498  bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1499  {
1500      if (CheckLengthMetrics(object)) {
1501          LocalizedCalcDimension localizedCalcDimension;
1502          ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1503          commonCalcDimension.top = localizedCalcDimension.top;
1504          commonCalcDimension.bottom = localizedCalcDimension.bottom;
1505          commonCalcDimension.left = localizedCalcDimension.start;
1506          commonCalcDimension.right = localizedCalcDimension.end;
1507          return true;
1508      }
1509      ParseEdgeWidths(object, commonCalcDimension, notNegative);
1510      return false;
1511  }
1512  
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1513  void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1514  {
1515      if (CheckLengthMetrics(object)) {
1516          LocalizedCalcDimension localizedCalcDimension;
1517          ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1518          auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1519          commonCalcDimension.top = localizedCalcDimension.top;
1520          commonCalcDimension.bottom = localizedCalcDimension.bottom;
1521          commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1522          commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1523          return;
1524      }
1525      ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1526  }
1527  
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1528  void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1529  {
1530      if (CheckLengthMetrics(object)) {
1531          LocalizedCalcDimension localizedCalcDimension;
1532          ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1533          auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1534          commonCalcDimension.top = localizedCalcDimension.top;
1535          commonCalcDimension.bottom = localizedCalcDimension.bottom;
1536          commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1537          commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1538          return;
1539      }
1540      ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1541  }
1542  
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1543  std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1544  {
1545      auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1546      auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1547      auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1548          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1549          NG::PipelineContext::SetCallBackNode(targetNode);
1550          JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1551          jsFuncFinish->ExecuteJS(1, &newJSVal);
1552      };
1553      return finishCallback;
1554  }
1555  } // namespace
1556  
GetResourceObject(const JSRef<JSObject> & jsObj)1557  RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1558  {
1559      auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1560      auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1561      auto args = jsObj->GetProperty("params");
1562  
1563      std::string bundleName;
1564      std::string moduleName;
1565      auto bundle = jsObj->GetProperty("bundleName");
1566      auto module = jsObj->GetProperty("moduleName");
1567      if (bundle->IsString() && module->IsString()) {
1568          bundleName = bundle->ToString();
1569          moduleName = module->ToString();
1570      }
1571      if (!args->IsArray()) {
1572          return nullptr;
1573      }
1574      JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1575      std::vector<ResourceObjectParams> resObjParamsList;
1576      auto size = static_cast<int32_t>(params->Length());
1577      for (int32_t i = 0; i < size; i++) {
1578          auto item = params->GetValueAt(i);
1579          ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1580          if (item->IsString()) {
1581              resObjParams.type = ResourceObjectParamType::STRING;
1582          } else if (item->IsNumber()) {
1583              if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1584                  resObjParams.type = ResourceObjectParamType::FLOAT;
1585              } else {
1586                  resObjParams.type = ResourceObjectParamType::INT;
1587              }
1588          }
1589          resObjParamsList.push_back(resObjParams);
1590      }
1591      auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
1592      return resourceObject;
1593  }
1594  
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1595  RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1596  {
1597      auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1598      auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1599      auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName);
1600      return resourceObject;
1601  }
1602  
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1603  RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1604  {
1605      RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1606      RefPtr<ThemeConstants> themeConstants = nullptr;
1607      if (SystemProperties::GetResourceDecoupling()) {
1608          resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1609          if (!resourceAdapter) {
1610              return nullptr;
1611          }
1612      } else {
1613          themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1614          if (!themeConstants) {
1615              return nullptr;
1616          }
1617      }
1618      auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1619      return resourceWrapper;
1620  }
1621  
CreateResourceWrapper()1622  RefPtr<ResourceWrapper> CreateResourceWrapper()
1623  {
1624      RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1625      RefPtr<ThemeConstants> themeConstants = nullptr;
1626      if (SystemProperties::GetResourceDecoupling()) {
1627          resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter();
1628          if (!resourceAdapter) {
1629              return nullptr;
1630          }
1631      } else {
1632          themeConstants = JSViewAbstract::GetThemeConstants();
1633          if (!themeConstants) {
1634              return nullptr;
1635          }
1636      }
1637      auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1638      return resourceWrapper;
1639  }
1640  
ColorAlphaAdapt(uint32_t origin)1641  uint32_t ColorAlphaAdapt(uint32_t origin)
1642  {
1643      uint32_t result = origin;
1644      if (origin >> COLOR_ALPHA_OFFSET == 0) {
1645          result = origin | COLOR_ALPHA_VALUE;
1646      }
1647      return result;
1648  }
1649  
JsScale(const JSCallbackInfo & info)1650  void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1651  {
1652      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1653      auto jsVal = info[0];
1654      if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1655          SetDefaultScale();
1656          return;
1657      }
1658  
1659      if (jsVal->IsObject()) {
1660          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1661          if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1662              jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1663              jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1664              // default: x, y, z (1.0, 1.0, 1.0)
1665              auto scaleX = 1.0f;
1666              auto scaleY = 1.0f;
1667              auto scaleZ = 1.0f;
1668              // default centerX, centerY 50% 50%;
1669              CalcDimension centerX = 0.5_pct;
1670              CalcDimension centerY = 0.5_pct;
1671              ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1672              ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1673              ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1674              return;
1675          } else {
1676              SetDefaultScale();
1677          }
1678      }
1679      double scale = 0.0;
1680      if (ParseJsDouble(jsVal, scale)) {
1681          ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1682      }
1683  }
1684  
SetDefaultScale()1685  void JSViewAbstract::SetDefaultScale()
1686  {
1687      ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1688      ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1689  }
1690  
JsScaleX(const JSCallbackInfo & info)1691  void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1692  {
1693      double scaleVal = 0.0;
1694      if (!ParseJsDouble(info[0], scaleVal)) {
1695          return;
1696      }
1697      ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1698  }
1699  
JsScaleY(const JSCallbackInfo & info)1700  void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1701  {
1702      double scaleVal = 0.0;
1703      if (!ParseJsDouble(info[0], scaleVal)) {
1704          return;
1705      }
1706      ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1707  }
1708  
JsOpacity(const JSCallbackInfo & info)1709  void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1710  {
1711      double opacity = 0.0;
1712      if (!ParseJsDouble(info[0], opacity)) {
1713          ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1714          return;
1715      }
1716      if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1717          opacity = std::clamp(opacity, 0.0, 1.0);
1718      } else {
1719          if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1720              opacity = 1.0;
1721          }
1722      }
1723      ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1724  }
1725  
JsTranslate(const JSCallbackInfo & info)1726  void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1727  {
1728      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1729          JSCallbackInfoType::OBJECT };
1730      auto jsVal = info[0];
1731      if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1732          SetDefaultTranslate();
1733          return;
1734      }
1735  
1736      if (jsVal->IsObject()) {
1737          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1738          if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1739              jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1740              jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1741              // default: x, y, z (0.0, 0.0, 0.0)
1742              auto translateX = CalcDimension(0.0);
1743              auto translateY = CalcDimension(0.0);
1744              auto translateZ = CalcDimension(0.0);
1745              ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1746              ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1747              return;
1748          } else {
1749              SetDefaultTranslate();
1750          }
1751      }
1752      CalcDimension value;
1753      if (ParseJsDimensionVp(jsVal, value)) {
1754          ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1755      }
1756  }
1757  
SetDefaultTranslate()1758  void JSViewAbstract::SetDefaultTranslate()
1759  {
1760      ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1761  }
1762  
JsTranslateX(const JSCallbackInfo & info)1763  void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1764  {
1765      CalcDimension value;
1766      if (!ParseJsDimensionVp(info[0], value)) {
1767          return;
1768      }
1769      ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1770  }
1771  
JsTranslateY(const JSCallbackInfo & info)1772  void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1773  {
1774      CalcDimension value;
1775      if (!ParseJsDimensionVp(info[0], value)) {
1776          return;
1777      }
1778      ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1779  }
1780  
JsRotate(const JSCallbackInfo & info)1781  void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1782  {
1783      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1784      auto jsVal = info[0];
1785      if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1786          SetDefaultRotate();
1787          return;
1788      }
1789  
1790      if (jsVal->IsObject()) {
1791          NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1792          std::optional<float> angle;
1793          ParseJsRotate(jsVal, rotate, angle);
1794          if (angle) {
1795              ViewAbstractModel::GetInstance()->SetRotate(
1796                  rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1797              ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1798          } else {
1799              SetDefaultRotate();
1800          }
1801          return;
1802      }
1803      double rotateZ;
1804      if (ParseJsDouble(jsVal, rotateZ)) {
1805          ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1806      }
1807  }
1808  
SetDefaultRotate()1809  void JSViewAbstract::SetDefaultRotate()
1810  {
1811      NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1812      ViewAbstractModel::GetInstance()->SetRotate(
1813          rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1814      ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1815  }
1816  
JsRotateX(const JSCallbackInfo & info)1817  void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1818  {
1819      double rotateVal = 0.0;
1820      if (!ParseJsDouble(info[0], rotateVal)) {
1821          return;
1822      }
1823      ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1824  }
1825  
JsRotateY(const JSCallbackInfo & info)1826  void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1827  {
1828      double rotateVal = 0.0;
1829      if (!ParseJsDouble(info[0], rotateVal)) {
1830          return;
1831      }
1832      ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1833  }
1834  
JsTransform(const JSCallbackInfo & info)1835  void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1836  {
1837      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1838      auto jsVal = info[0];
1839      if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1840          SetDefaultTransform();
1841          return;
1842      }
1843      JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1844      const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1845      if (!array->IsArray()) {
1846          return;
1847      }
1848      JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1849      if (jsArray->Length() != matrix4Len) {
1850          return;
1851      }
1852      std::vector<float> matrix(matrix4Len);
1853      for (int32_t i = 0; i < matrix4Len; i++) {
1854          double value = 0.0;
1855          ParseJsDouble(jsArray->GetValueAt(i), value);
1856          matrix[i] = static_cast<float>(value);
1857      }
1858      ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1859  }
1860  
SetDefaultTransform()1861  void JSViewAbstract::SetDefaultTransform()
1862  {
1863      const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1864      std::vector<float> matrix(matrix4Len);
1865      const int32_t initPosition = 5;
1866      for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1867          double value = 1.0;
1868          matrix[i] = static_cast<float>(value);
1869      }
1870      ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1871  }
1872  
ParseJsTransition(const JSRef<JSObject> & jsObj)1873  NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1874  {
1875      NG::TransitionOptions transitionOption;
1876      bool hasEffect = false;
1877      transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1878      if (jsObj->HasProperty("opacity")) {
1879          double opacity = 1.0;
1880          ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1881          if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1882              if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1883                  opacity = 1.0;
1884              }
1885          } else {
1886              opacity = std::clamp(opacity, 0.0, 1.0);
1887          }
1888          transitionOption.UpdateOpacity(static_cast<float>(opacity));
1889          hasEffect = true;
1890      }
1891      if (jsObj->HasProperty("translate")) {
1892          // default: x, y, z (0.0, 0.0, 0.0)
1893          NG::TranslateOptions translate;
1894          ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1895          transitionOption.UpdateTranslate(translate);
1896          hasEffect = true;
1897      }
1898      if (jsObj->HasProperty("scale")) {
1899          // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1900          NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1901          ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1902              scale.centerX, scale.centerY);
1903          transitionOption.UpdateScale(scale);
1904          hasEffect = true;
1905      }
1906      if (jsObj->HasProperty("rotate")) {
1907          // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1908          NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1909          std::optional<float> angle;
1910          ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1911          if (angle.has_value()) {
1912              rotate.angle = angle.value();
1913              transitionOption.UpdateRotate(rotate);
1914              hasEffect = true;
1915          }
1916      }
1917      if (!hasEffect) {
1918          // default transition
1919          transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1920      }
1921      return transitionOption;
1922  }
1923  
ParseJsTransitionEffect(const JSCallbackInfo & info)1924  RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1925  {
1926      JSRef<JSVal> arg = info[0];
1927      if (!arg->IsObject()) {
1928          return nullptr;
1929      }
1930      auto obj = JSRef<JSObject>::Cast(arg);
1931      auto transitionVal = obj->GetProperty("transition");
1932  
1933      if (!transitionVal->IsObject()) {
1934          return nullptr;
1935      }
1936  
1937      auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1938      auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
1939      return chainedEffect;
1940  }
1941  
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)1942  RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
1943      const JSExecutionContext& context)
1944  {
1945      auto chainedEffect = ParseChainedTransition(object, context);
1946      return chainedEffect;
1947  }
1948  
JsTransition(const JSCallbackInfo & info)1949  void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1950  {
1951      if (info.Length() < 1 || !info[0]->IsObject()) {
1952          if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
1953              ViewAbstractModel::GetInstance()->CleanTransition();
1954              ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
1955          }
1956          return;
1957      }
1958      auto obj = JSRef<JSObject>::Cast(info[0]);
1959      if (!obj->GetProperty("successor_")->IsUndefined()) {
1960          auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1961          std::function<void(bool)> finishCallback;
1962          if (info.Length() > 1 && info[1]->IsFunction()) {
1963              finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
1964          }
1965          ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
1966          return;
1967      }
1968      auto options = ParseJsTransition(obj);
1969      ViewAbstractModel::GetInstance()->SetTransition(options);
1970  }
1971  
JsWidth(const JSCallbackInfo & info)1972  void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1973  {
1974      JsWidth(info[0]);
1975  }
1976  
JsWidth(const JSRef<JSVal> & jsValue)1977  bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1978  {
1979      CalcDimension value;
1980      if (jsValue->IsUndefined()) {
1981          ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1982          return true;
1983      }
1984      if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1985          if (!ParseJsDimensionVpNG(jsValue, value)) {
1986              ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1987              return false;
1988          }
1989      } else if (!ParseJsDimensionVp(jsValue, value)) {
1990          return false;
1991      }
1992  
1993      if (LessNotEqual(value.Value(), 0.0)) {
1994          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1995              ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1996              return true;
1997          } else {
1998              value.SetValue(0.0);
1999          }
2000      }
2001  
2002      ViewAbstractModel::GetInstance()->SetWidth(value);
2003      return true;
2004  }
2005  
JsHeight(const JSCallbackInfo & info)2006  void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2007  {
2008      JsHeight(info[0]);
2009  }
2010  
JsHeight(const JSRef<JSVal> & jsValue)2011  bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2012  {
2013      CalcDimension value;
2014      if (jsValue->IsUndefined()) {
2015          ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2016          return true;
2017      }
2018      if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2019          if (!ParseJsDimensionVpNG(jsValue, value)) {
2020              ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2021              return false;
2022          }
2023      } else if (!ParseJsDimensionVp(jsValue, value)) {
2024          return false;
2025      }
2026  
2027      if (LessNotEqual(value.Value(), 0.0)) {
2028          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2029              ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2030              return true;
2031          } else {
2032              value.SetValue(0.0);
2033          }
2034      }
2035  
2036      ViewAbstractModel::GetInstance()->SetHeight(value);
2037      return true;
2038  }
2039  
JsResponseRegion(const JSCallbackInfo & info)2040  void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2041  {
2042      std::vector<DimensionRect> result;
2043      if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2044          ViewAbstractModel::GetInstance()->SetResponseRegion({});
2045          return;
2046      }
2047  
2048      ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2049  }
2050  
JsMouseResponseRegion(const JSCallbackInfo & info)2051  void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2052  {
2053      std::vector<DimensionRect> result;
2054      if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2055          ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2056          return;
2057      }
2058      ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2059  }
2060  
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2061  bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2062  {
2063      result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2064      result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2065      if (!jsValue->IsObject()) {
2066          return true;
2067      }
2068  
2069      JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2070      JSRef<JSVal> x = obj->GetProperty("x");
2071      JSRef<JSVal> y = obj->GetProperty("y");
2072      JSRef<JSVal> width = obj->GetProperty("width");
2073      JSRef<JSVal> height = obj->GetProperty("height");
2074      CalcDimension xDimen = result.GetOffset().GetX();
2075      CalcDimension yDimen = result.GetOffset().GetY();
2076      CalcDimension widthDimen = result.GetWidth();
2077      CalcDimension heightDimen = result.GetHeight();
2078      auto s1 = width->ToString();
2079      auto s2 = height->ToString();
2080      if (s1.find('-') != std::string::npos) {
2081          width = JSRef<JSVal>::Make(ToJSValue("100%"));
2082      }
2083      if (s2.find('-') != std::string::npos) {
2084          height = JSRef<JSVal>::Make(ToJSValue("100%"));
2085      }
2086      if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2087          auto offset = result.GetOffset();
2088          offset.SetX(xDimen);
2089          result.SetOffset(offset);
2090      }
2091      if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2092          auto offset = result.GetOffset();
2093          offset.SetY(yDimen);
2094          result.SetOffset(offset);
2095      }
2096      if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2097          if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2098              return true;
2099          }
2100          result.SetWidth(widthDimen);
2101      }
2102      if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2103          if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2104              return true;
2105          }
2106          result.SetHeight(heightDimen);
2107      }
2108      return true;
2109  }
2110  
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2111  bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2112  {
2113      if (!jsValue->IsArray() && !jsValue->IsObject()) {
2114          return false;
2115      }
2116  
2117      if (jsValue->IsArray()) {
2118          JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2119          for (size_t i = 0; i < array->Length(); i++) {
2120              CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2121              CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2122              CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2123              CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2124              DimensionOffset offsetDimen(xDimen, yDimen);
2125              DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2126              if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2127                  result.emplace_back(dimenRect);
2128              } else {
2129                  return false;
2130              }
2131          }
2132          return true;
2133      }
2134  
2135      CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2136      CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2137      CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2138      CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2139      DimensionOffset offsetDimen(xDimen, yDimen);
2140      DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2141      if (ParseJsDimensionRect(jsValue, dimenRect)) {
2142          result.emplace_back(dimenRect);
2143          return true;
2144      } else {
2145          return false;
2146      }
2147  }
2148  
JsSize(const JSCallbackInfo & info)2149  void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2150  {
2151      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2152      auto jsVal = info[0];
2153      if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2154          return;
2155      }
2156  
2157      JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2158      JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2159      JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2160  }
2161  
JsConstraintSize(const JSCallbackInfo & info)2162  void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2163  {
2164      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2165      auto jsVal = info[0];
2166      if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2167          ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2168          ViewAbstractModel::GetInstance()->ResetMinSize(true);
2169          ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2170          ViewAbstractModel::GetInstance()->ResetMinSize(false);
2171          return;
2172      }
2173  
2174      JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2175  
2176      JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2177      CalcDimension minWidth;
2178      JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2179      CalcDimension maxWidth;
2180      JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2181      CalcDimension minHeight;
2182      JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2183      CalcDimension maxHeight;
2184      bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2185      if (ParseJsDimensionVp(minWidthValue, minWidth)) {
2186          ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2187      } else if (version10OrLarger) {
2188          ViewAbstractModel::GetInstance()->ResetMinSize(true);
2189      }
2190  
2191      if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
2192          ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2193      } else if (version10OrLarger) {
2194          ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2195      }
2196  
2197      if (ParseJsDimensionVp(minHeightValue, minHeight)) {
2198          ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2199      } else if (version10OrLarger) {
2200          ViewAbstractModel::GetInstance()->ResetMinSize(false);
2201      }
2202  
2203      if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
2204          ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2205      } else if (version10OrLarger) {
2206          ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2207      }
2208  }
2209  
JsLayoutPriority(const JSCallbackInfo & info)2210  void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2211  {
2212      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2213      auto jsVal = info[0];
2214      if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2215          return;
2216      }
2217  
2218      int32_t priority;
2219      if (jsVal->IsNumber()) {
2220          priority = jsVal->ToNumber<int32_t>();
2221      } else {
2222          priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2223      }
2224      ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2225  }
2226  
JsPixelRound(const JSCallbackInfo & info)2227  void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info)
2228  {
2229      uint16_t value = 0;
2230      JSRef<JSVal> arg = info[0];
2231      if (!arg->IsObject()) {
2232          return;
2233      }
2234      JSRef<JSObject> object = JSRef<JSObject>::Cast(arg);
2235      JSRef<JSVal> jsStartValue = object->GetProperty("start");
2236      if (jsStartValue->IsNumber()) {
2237          int32_t startValue = jsStartValue->ToNumber<int32_t>();
2238          if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) {
2239              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_START);
2240          } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) {
2241              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START);
2242          } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(startValue)) {
2243              value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START);
2244          }
2245      }
2246      JSRef<JSVal> jsTopValue = object->GetProperty("top");
2247      if (jsTopValue->IsNumber()) {
2248          int32_t topValue = jsTopValue->ToNumber<int32_t>();
2249          if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) {
2250              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
2251          } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) {
2252              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
2253          } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(topValue)) {
2254              value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP);
2255          }
2256      }
2257      JSRef<JSVal> jsEndValue = object->GetProperty("end");
2258      if (jsEndValue->IsNumber()) {
2259          int32_t endValue = jsEndValue->ToNumber<int32_t>();
2260          if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) {
2261              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END);
2262          } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) {
2263              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_END);
2264          } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(endValue)) {
2265              value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END);
2266          }
2267      }
2268      JSRef<JSVal> jsBottomValue = object->GetProperty("bottom");
2269      if (jsBottomValue->IsNumber()) {
2270          int32_t bottomValue = jsBottomValue->ToNumber<int32_t>();
2271          if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2272              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
2273          } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2274              value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
2275          } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2276              value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM);
2277          }
2278      }
2279      ViewAbstractModel::GetInstance()->SetPixelRound(value);
2280  }
2281  
JsLayoutWeight(const JSCallbackInfo & info)2282  void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2283  {
2284      float value = 0.0f;
2285      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2286      auto jsVal = info[0];
2287      if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2288          if (!jsVal->IsUndefined()) {
2289              return;
2290          }
2291      }
2292  
2293      if (jsVal->IsNumber()) {
2294          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2295              value = jsVal->ToNumber<float>();
2296          } else {
2297              value = jsVal->ToNumber<int32_t>();
2298          }
2299      } else {
2300          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2301              value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2302          } else {
2303              value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2304          }
2305      }
2306  
2307      ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2308  }
2309  
JsChainWeight(const JSCallbackInfo & info)2310  void JSViewAbstract::JsChainWeight(const JSCallbackInfo& info)
2311  {
2312      NG::LayoutWeightPair layoutWeightPair(DEFAULT_LAYOUT_WEIGHT, DEFAULT_LAYOUT_WEIGHT);
2313      auto jsVal = info[0];
2314      if (jsVal->IsObject()) {
2315          JSRef<JSObject> val = JSRef<JSObject>::Cast(jsVal);
2316          auto weightX = val->GetProperty("horizontal");
2317          auto weightY = val->GetProperty("vertical");
2318          if (weightX->IsNumber()) {
2319              layoutWeightPair.first = weightX->ToNumber<float>();
2320          }
2321          if (weightY->IsNumber()) {
2322              layoutWeightPair.second = weightY->ToNumber<float>();
2323          }
2324      }
2325      ViewAbstractModel::GetInstance()->SetLayoutWeight(layoutWeightPair);
2326  }
2327  
JsAlign(const JSCallbackInfo & info)2328  void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2329  {
2330      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2331      auto jsVal = info[0];
2332      if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2333          Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2334          ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2335          return;
2336      }
2337      auto value = jsVal->ToNumber<int32_t>();
2338      Alignment alignment = ParseAlignment(value);
2339      ViewAbstractModel::GetInstance()->SetAlign(alignment);
2340  }
2341  
JsPosition(const JSCallbackInfo & info)2342  void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2343  {
2344      CalcDimension x;
2345      CalcDimension y;
2346      OHOS::Ace::EdgesParam edges;
2347  
2348      auto jsArg = info[0];
2349      if (jsArg->IsObject()) {
2350          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2351          if (ParseLocationProps(jsObj, x, y)) {
2352              return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2353          } else if (ParseLocalizedEdges(jsObj, edges)) {
2354              ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2355              return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2356          } else if (ParseLocationPropsEdges(jsObj, edges)) {
2357              return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2358          }
2359      }
2360      if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2361          ViewAbstractModel::GetInstance()->ResetPosition();
2362      } else {
2363          ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2364      }
2365  }
2366  
JsMarkAnchor(const JSCallbackInfo & info)2367  void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2368  {
2369      CalcDimension x;
2370      CalcDimension y;
2371  
2372      auto jsArg = info[0];
2373      if (jsArg->IsObject()) {
2374          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2375          if (ParseMarkAnchorPosition(jsObj, x, y)) {
2376              ViewAbstractModel::GetInstance()->SetLocalizedMarkAnchor(true);
2377              return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2378          } else if (ParseLocationProps(jsObj, x, y)) {
2379              return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2380          }
2381      }
2382      ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2383  }
2384  
JsOffset(const JSCallbackInfo & info)2385  void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2386  {
2387      CalcDimension x;
2388      CalcDimension y;
2389      OHOS::Ace::EdgesParam edges;
2390      auto jsArg = info[0];
2391      if (jsArg->IsObject()) {
2392          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2393          if (ParseLocalizedEdges(jsObj, edges)) {
2394              ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2395              return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2396          } else if (ParseLocationProps(jsObj, x, y)) {
2397              return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2398          } else if (ParseLocationPropsEdges(jsObj, edges)) {
2399              return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2400          }
2401      }
2402  
2403      ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2404  }
2405  
JsEnabled(const JSCallbackInfo & info)2406  void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2407  {
2408      auto arg = info[0];
2409      if (!arg->IsBoolean()) {
2410          ViewAbstractModel::GetInstance()->SetEnabled(true);
2411      } else {
2412          ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2413      }
2414  }
2415  
JsAspectRatio(const JSCallbackInfo & info)2416  void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2417  {
2418      double value = 0.0;
2419      auto jsAspectRatio = info[0];
2420      if (!ParseJsDouble(jsAspectRatio, value)) {
2421          // add version protection, undefined use default value
2422          if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2423              (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2424              ViewAbstractModel::GetInstance()->ResetAspectRatio();
2425              return;
2426          } else {
2427              return;
2428          }
2429      }
2430  
2431      // negative use default value.
2432      if (LessOrEqual(value, 0.0)) {
2433          if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2434              ViewAbstractModel::GetInstance()->ResetAspectRatio();
2435              return;
2436          } else {
2437              value = 1.0;
2438          }
2439      }
2440  
2441      ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2442  }
2443  
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2444  void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2445      std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2446  {
2447      if (info[0]->IsString()) {
2448          std::string text = info[0]->ToString();
2449          ViewAbstractModel::GetInstance()->SetOverlay(
2450              text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2451      } else if (info[0]->IsObject()) {
2452          JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2453          auto builder = overlayObject->GetProperty("builder");
2454          if (builder->IsFunction()) {
2455              auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2456              CHECK_NULL_VOID(builderFunc);
2457              auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2458              auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2459                                node = targetNode]() {
2460                  JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2461                  ACE_SCORING_EVENT("Overlay");
2462                  PipelineContext::SetCallBackNode(node);
2463                  func->Execute();
2464              };
2465              ViewAbstractModel::GetInstance()->SetOverlay(
2466                  "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2467              return;
2468          }
2469  
2470          JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2471          if (!builderNode->IsObject()) {
2472              return;
2473          }
2474          auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2475          JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2476          if (nodePtr.IsEmpty()) {
2477              return;
2478          }
2479          const auto* vm = nodePtr->GetEcmaVM();
2480          auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
2481          auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2482          CHECK_NULL_VOID(frameNode);
2483          RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2484          ViewAbstractModel::GetInstance()->SetOverlay(
2485              "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2486      }
2487  }
2488  
JsOverlay(const JSCallbackInfo & info)2489  void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2490  {
2491      if (info.Length() > 0 && (info[0]->IsUndefined())) {
2492          ViewAbstractModel::GetInstance()->SetOverlay(
2493              "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2494          return;
2495      }
2496  
2497      if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2498          return;
2499      }
2500      std::optional<Alignment> align;
2501      std::optional<CalcDimension> offsetX;
2502      std::optional<CalcDimension> offsetY;
2503  
2504      if (info[1]->IsObject()) {
2505          JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2506          JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2507          auto value = alignVal->ToNumber<int32_t>();
2508          Alignment alignment = ParseAlignment(value);
2509          align = alignment;
2510  
2511          JSRef<JSVal> val = optionObj->GetProperty("offset");
2512          if (val->IsObject()) {
2513              JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2514              JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2515              CalcDimension x;
2516              if (ParseJsDimensionVp(xVal, x)) {
2517                  offsetX = x;
2518              }
2519              JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2520              CalcDimension y;
2521              if (ParseJsDimensionVp(yVal, y)) {
2522                  offsetY = y;
2523              }
2524          }
2525      }
2526  
2527      ParseOverlayFirstParam(info, align, offsetX, offsetY);
2528  }
2529  
ParseAlignment(int32_t align)2530  Alignment JSViewAbstract::ParseAlignment(int32_t align)
2531  {
2532      Alignment alignment = Alignment::CENTER;
2533      switch (align) {
2534          case 0:
2535              alignment = Alignment::TOP_LEFT;
2536              break;
2537          case 1:
2538              alignment = Alignment::TOP_CENTER;
2539              break;
2540          case 2:
2541              alignment = Alignment::TOP_RIGHT;
2542              break;
2543          case 3:
2544              alignment = Alignment::CENTER_LEFT;
2545              break;
2546          case 4:
2547              alignment = Alignment::CENTER;
2548              break;
2549          case 5:
2550              alignment = Alignment::CENTER_RIGHT;
2551              break;
2552          case 6:
2553              alignment = Alignment::BOTTOM_LEFT;
2554              break;
2555          case 7:
2556              alignment = Alignment::BOTTOM_CENTER;
2557              break;
2558          case 8:
2559              alignment = Alignment::BOTTOM_RIGHT;
2560              break;
2561          default:
2562              break;
2563      }
2564      return alignment;
2565  }
2566  
SetVisibility(const JSCallbackInfo & info)2567  void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2568  {
2569      int32_t visible = 0;
2570      JSRef<JSVal> arg = info[0];
2571      if (arg->IsNull() || arg->IsUndefined()) {
2572          // undefined value use default value.
2573          visible = 0;
2574      } else if (!arg->IsNumber()) {
2575          return;
2576      } else {
2577          visible = arg->ToNumber<int32_t>();
2578      }
2579  
2580      if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2581          (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2582          visible = 0;
2583      }
2584  
2585      if (info.Length() > 1 && info[1]->IsFunction()) {
2586          RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2587          auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2588          auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2589                                        int32_t visible) {
2590              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2591              ACE_SCORING_EVENT("onVisibilityChange");
2592              PipelineContext::SetCallBackNode(node);
2593              JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2594              func->ExecuteJS(1, &newJSVal);
2595          };
2596          ViewAbstractModel::GetInstance()->SetVisibility(
2597              static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2598      } else {
2599          ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2600      }
2601  }
2602  
JsSetFreeze(const JSCallbackInfo & info)2603  void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2604  {
2605      if (info[0]->IsBoolean()) {
2606          ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2607      }
2608  }
2609  
JsFlexBasis(const JSCallbackInfo & info)2610  void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2611  {
2612      CalcDimension value;
2613      if (!ParseJsDimensionVp(info[0], value)) {
2614          value.SetUnit(DimensionUnit::AUTO);
2615      }
2616      // flexbasis don't support percent case.
2617      if (value.Unit() == DimensionUnit::PERCENT) {
2618          value.SetUnit(DimensionUnit::AUTO);
2619      }
2620      ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2621  }
2622  
JsFlexGrow(const JSCallbackInfo & info)2623  void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2624  {
2625      double value = 0.0;
2626      if (!ParseJsDouble(info[0], value)) {
2627          if (info[0]->IsNull() || info[0]->IsUndefined()) {
2628              // undefined use default value.
2629              value = 0.0;
2630          } else {
2631              return;
2632          }
2633      }
2634      // negative use default value.
2635      if (value < 0.0) {
2636          value = 0.0;
2637      }
2638      ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2639  }
2640  
JsFlexShrink(const JSCallbackInfo & info)2641  void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2642  {
2643      double value = 0.0;
2644      if (!ParseJsDouble(info[0], value)) {
2645          if (info[0]->IsNull() || info[0]->IsUndefined()) {
2646              // undefined use default value.
2647              ViewAbstractModel::GetInstance()->ResetFlexShrink();
2648              return;
2649          } else {
2650              return;
2651          }
2652      }
2653      // negative use default value.
2654      if (value < 0.0) {
2655          ViewAbstractModel::GetInstance()->ResetFlexShrink();
2656          return;
2657      }
2658      ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2659  }
2660  
JsDisplayPriority(const JSCallbackInfo & info)2661  void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2662  {
2663      double value = 0.0;
2664      if (!ParseJsDouble(info[0], value)) {
2665          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2666              ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2667          }
2668          return;
2669      }
2670      ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2671  }
2672  
JsSharedTransition(const JSCallbackInfo & info)2673  void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2674  {
2675      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2676      auto jsVal = info[0];
2677      if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2678          return;
2679      }
2680      // id
2681      auto id = jsVal->ToString();
2682      if (id.empty()) {
2683          return;
2684      }
2685      std::shared_ptr<SharedTransitionOption> sharedOption;
2686  
2687      // options
2688      if (info.Length() > 1 && info[1]->IsObject()) {
2689          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2690          sharedOption = std::make_shared<SharedTransitionOption>();
2691          // default: duration: 1000
2692          sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2693          if (sharedOption->duration < 0) {
2694              sharedOption->duration = DEFAULT_DURATION;
2695          }
2696          // default: delay: 0
2697          sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2698          if (sharedOption->delay < 0) {
2699              sharedOption->delay = 0;
2700          }
2701          // default: LinearCurve
2702          RefPtr<Curve> curve;
2703          JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2704          if (curveArgs->IsString()) {
2705              curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2706          } else if (curveArgs->IsObject()) {
2707              JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2708              if (!curveString->IsString()) {
2709                  return;
2710              }
2711              curve = CreateCurve(curveString->ToString(), false);
2712          }
2713          if (!curve) {
2714              curve = Curves::LINEAR;
2715          }
2716          sharedOption->curve = curve;
2717          // motionPath
2718          if (jsObj->HasProperty("motionPath")) {
2719              MotionPathOption motionPathOption;
2720              if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2721                  sharedOption->motionPathOption = motionPathOption;
2722              }
2723          }
2724          // zIndex
2725          sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2726          // type
2727          int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2728              static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2729          sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2730      }
2731      ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2732  }
2733  
JsGeometryTransition(const JSCallbackInfo & info)2734  void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2735  {
2736      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2737      auto jsVal = info[0];
2738      if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2739          return;
2740      }
2741      // id
2742      auto id = jsVal->ToString();
2743      // follow flag
2744      bool followWithOutTransition = false;
2745      // hierarchy flag
2746      bool doRegisterSharedTransition = true;
2747      if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2748          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2749          ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2750  
2751          auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2752          ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2753          switch (transitionHierarchyStrategy) {
2754              case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2755                  doRegisterSharedTransition = false;
2756                  break;
2757              case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2758                  doRegisterSharedTransition = true;
2759                  break;
2760              default:
2761                  break;
2762          }
2763      }
2764      ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2765  }
2766  
JsAlignSelf(const JSCallbackInfo & info)2767  void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2768  {
2769      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2770      auto jsVal = info[0];
2771      if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2772          ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2773          return;
2774      }
2775      auto alignVal = jsVal->ToNumber<int32_t>();
2776  
2777      if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2778          ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2779      }
2780  }
2781  
JsBackgroundColor(const JSCallbackInfo & info)2782  void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2783  {
2784      Color backgroundColor;
2785      if (!ParseJsColor(info[0], backgroundColor)) {
2786          backgroundColor = Color::TRANSPARENT;
2787      }
2788  
2789      ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2790  }
2791  
JsBackgroundImage(const JSCallbackInfo & info)2792  void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2793  {
2794      int32_t resId = 0;
2795      std::string src;
2796      std::string bundle;
2797      std::string module;
2798      RefPtr<PixelMap> pixmap = nullptr;
2799      auto jsBackgroundImage = info[0];
2800      GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2801      if (jsBackgroundImage->IsString()) {
2802          src = jsBackgroundImage->ToString();
2803          ViewAbstractModel::GetInstance()->SetBackgroundImage(
2804              ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2805      } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2806          ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2807      } else {
2808  #if defined(PIXEL_MAP_SUPPORTED)
2809          if (IsDrawable(jsBackgroundImage)) {
2810              pixmap = GetDrawablePixmap(jsBackgroundImage);
2811          } else {
2812              pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2813          }
2814  #endif
2815          ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2816      }
2817  
2818      int32_t repeatIndex = 0;
2819      if (info.Length() == 2) {
2820          auto jsImageRepeat = info[1];
2821          if (jsImageRepeat->IsNumber()) {
2822              repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2823          }
2824      }
2825      auto repeat = static_cast<ImageRepeat>(repeatIndex);
2826      ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2827  }
2828  
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2829  void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2830  {
2831      if (jsBlurOption->GetProperty("grayscale")->IsArray()) {
2832          JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale"));
2833          auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2834          auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2835          std::vector<float> greyVec(2); // 2 number
2836          greyVec[0] = grey1;
2837          greyVec[1] = grey2;
2838          blurOption.grayscale = greyVec;
2839      }
2840  }
2841  
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2842  void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
2843  {
2844      auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2845      ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2846      if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2847          colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2848          styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2849      }
2850      auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2851      ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2852      if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2853          adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2854          styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2855      }
2856  
2857      // policy
2858      auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2859      ParseJsInt32(jsOption->GetProperty("policy"), policy);
2860      if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2861          policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2862          styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2863      }
2864  
2865      // blurType
2866      auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2867      ParseJsInt32(jsOption->GetProperty("type"), blurType);
2868      if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2869          blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2870          styleOption.blurType = static_cast<BlurType>(blurType);
2871      }
2872  
2873      // inactiveColor
2874      if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) {
2875          styleOption.isValidColor = true;
2876      }
2877  
2878      // scale
2879      if (jsOption->GetProperty("scale")->IsNumber()) {
2880          double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2881          styleOption.scale = std::clamp(scale, 0.0, 1.0);
2882      }
2883  
2884      if (jsOption->GetProperty("blurOptions")->IsObject()) {
2885          JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2886          BlurOption blurOption;
2887          ParseBlurOption(jsBlurOption, blurOption);
2888          styleOption.blurOption = blurOption;
2889      }
2890  }
2891  
JsBackgroundBlurStyle(const JSCallbackInfo & info)2892  void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2893  {
2894      if (info.Length() == 0) {
2895          return;
2896      }
2897      BlurStyleOption styleOption;
2898      if (info[0]->IsNumber()) {
2899          auto blurStyle = info[0]->ToNumber<int32_t>();
2900          if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2901              blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2902              styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2903          }
2904      }
2905      if (info.Length() > 1 && info[1]->IsObject()) {
2906          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2907          ParseBlurStyleOption(jsOption, styleOption);
2908      }
2909      ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2910  }
2911  
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2912  void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2913  {
2914      double rate = 1.0f;
2915      if (jsOption->GetProperty("rate")->IsNumber()) {
2916          rate = jsOption->GetProperty("rate")->ToNumber<double>();
2917      }
2918      double lightUpDegree = 0.0f;
2919      if (jsOption->GetProperty("lightUpDegree")->IsNumber()) {
2920          lightUpDegree = jsOption->GetProperty("lightUpDegree")->ToNumber<double>();
2921      }
2922      double cubicCoeff = 0.0f;
2923      if (jsOption->GetProperty("cubicCoeff")->IsNumber()) {
2924          cubicCoeff = jsOption->GetProperty("cubicCoeff")->ToNumber<double>();
2925      }
2926      double quadCoeff = 0.0f;
2927      if (jsOption->GetProperty("quadCoeff")->IsNumber()) {
2928          quadCoeff = jsOption->GetProperty("quadCoeff")->ToNumber<double>();
2929      }
2930      double saturation = 1.0f;
2931      if (jsOption->GetProperty("saturation")->IsNumber()) {
2932          saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2933      }
2934      std::vector<float> posRGB(3, 0.0);
2935      if (jsOption->GetProperty("posRGB")->IsArray()) {
2936          JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("posRGB"));
2937          auto r = params->GetValueAt(0)->ToNumber<double>();
2938          auto g = params->GetValueAt(1)->ToNumber<double>();
2939          auto b = params->GetValueAt(2)->ToNumber<double>();
2940          posRGB[0] = r;
2941          posRGB[1] = g;
2942          posRGB[2] = b;
2943      }
2944      std::vector<float> negRGB(3, 0.0);
2945      if (jsOption->GetProperty("negRGB")->IsArray()) {
2946          JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("negRGB"));
2947          auto r = params->GetValueAt(0)->ToNumber<double>();
2948          auto g = params->GetValueAt(1)->ToNumber<double>();
2949          auto b = params->GetValueAt(2)->ToNumber<double>();
2950          negRGB[0] = r;
2951          negRGB[1] = g;
2952          negRGB[2] = b;
2953      }
2954      double fraction = 1.0f;
2955      if (jsOption->GetProperty("fraction")->IsNumber()) {
2956          fraction = jsOption->GetProperty("fraction")->ToNumber<double>();
2957          fraction = std::clamp(fraction, 0.0, 1.0);
2958      }
2959      brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
2960  }
2961  
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2962  void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
2963  {
2964      CalcDimension radius;
2965      if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2966          radius.SetValue(0.0f);
2967      }
2968      effectOption.radius = radius;
2969  
2970      double saturation = 1.0f;
2971      if (jsOption->GetProperty("saturation")->IsNumber()) {
2972          saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2973          saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2974      }
2975      effectOption.saturation = saturation;
2976  
2977      double brightness = 1.0f;
2978      if (jsOption->GetProperty("brightness")->IsNumber()) {
2979          brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2980          brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2981      }
2982      effectOption.brightness = brightness;
2983  
2984      ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
2985  
2986      auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2987      auto adaptiveColor = AdaptiveColor::DEFAULT;
2988      ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
2989      if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2990          adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2991          adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
2992      }
2993      effectOption.adaptiveColor = adaptiveColor;
2994  
2995      // policy
2996      auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2997      ParseJsInt32(jsOption->GetProperty("policy"), policy);
2998      if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2999          policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3000          effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3001      }
3002  
3003      // blurType
3004      auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3005      ParseJsInt32(jsOption->GetProperty("type"), blurType);
3006      if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3007          blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3008          effectOption.blurType = static_cast<BlurType>(blurType);
3009      }
3010  
3011      // inactiveColor
3012      if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
3013          effectOption.isValidColor = true;
3014      }
3015  
3016      BlurOption blurOption;
3017      if (jsOption->GetProperty("blurOptions")->IsObject()) {
3018          JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3019          ParseBlurOption(jsBlurOption, blurOption);
3020          effectOption.blurOption = blurOption;
3021      }
3022  }
3023  
JsForegroundEffect(const JSCallbackInfo & info)3024  void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
3025  {
3026      if (info.Length() == 0) {
3027          return;
3028      }
3029      float radius = 0.0;
3030      if (info[0]->IsObject()) {
3031          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3032          if (jsOption->GetProperty("radius")->IsNumber()) {
3033              radius = jsOption->GetProperty("radius")->ToNumber<float>();
3034          }
3035      }
3036      radius = std::max(radius, 0.0f);
3037      ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
3038  }
3039  
JsBackgroundEffect(const JSCallbackInfo & info)3040  void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
3041  {
3042      if (info.Length() == 0) {
3043          return;
3044      }
3045      EffectOption option;
3046      if (info[0]->IsObject()) {
3047          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3048          ParseEffectOption(jsOption, option);
3049      }
3050      ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
3051  }
3052  
JsForegroundBlurStyle(const JSCallbackInfo & info)3053  void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
3054  {
3055      if (info.Length() == 0) {
3056          return;
3057      }
3058      BlurStyleOption styleOption;
3059      if (info[0]->IsNumber()) {
3060          auto blurStyle = info[0]->ToNumber<int32_t>();
3061          if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3062              blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3063              styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3064          }
3065      }
3066      if (info.Length() > 1 && info[1]->IsObject()) {
3067          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3068          auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3069          ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3070          if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3071              colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3072              styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3073          }
3074          auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3075          ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3076          if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3077              adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3078              styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3079          }
3080          if (jsOption->GetProperty("scale")->IsNumber()) {
3081              double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3082              styleOption.scale = std::clamp(scale, 0.0, 1.0);
3083          }
3084  
3085          if (jsOption->GetProperty("blurOptions")->IsObject()) {
3086              JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3087              BlurOption blurOption;
3088              ParseBlurOption(jsBlurOption, blurOption);
3089              styleOption.blurOption = blurOption;
3090          }
3091      }
3092      ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
3093  }
3094  
JsSphericalEffect(const JSCallbackInfo & info)3095  void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3096  {
3097      auto radio = 0.0;
3098      if (info[0]->IsNumber()) {
3099          radio = info[0]->ToNumber<double>();
3100      }
3101      ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3102  }
3103  
JsPixelStretchEffect(const JSCallbackInfo & info)3104  void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3105  {
3106      if (!info[0]->IsObject()) {
3107          PixStretchEffectOption option;
3108          option.ResetValue();
3109          ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3110          return;
3111      }
3112      auto jsObject = JSRef<JSObject>::Cast(info[0]);
3113      CalcDimension left;
3114      ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3115      CalcDimension right;
3116      ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3117      CalcDimension top;
3118      ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3119      CalcDimension bottom;
3120      ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3121  
3122      PixStretchEffectOption option;
3123      bool illegalInput = false;
3124      if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3125          top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3126          if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3127              (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3128              (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3129              (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3130              left.SetUnit(DimensionUnit::PERCENT);
3131              top.SetUnit(DimensionUnit::PERCENT);
3132              right.SetUnit(DimensionUnit::PERCENT);
3133              bottom.SetUnit(DimensionUnit::PERCENT);
3134          } else {
3135              illegalInput = true;
3136          }
3137      }
3138      if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3139          (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3140          option.left = left;
3141          option.top = top;
3142          option.right = right;
3143          option.bottom = bottom;
3144      } else {
3145          illegalInput = true;
3146      }
3147      if (illegalInput) {
3148          option.ResetValue();
3149      }
3150      ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3151  }
3152  
JsLightUpEffect(const JSCallbackInfo & info)3153  void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3154  {
3155      auto radio = 1.0;
3156      if (info[0]->IsNumber()) {
3157          radio = info[0]->ToNumber<double>();
3158      }
3159      ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3160  }
3161  
JsBackgroundImageSize(const JSCallbackInfo & info)3162  void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3163  {
3164      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3165      BackgroundImageSize bgImgSize;
3166      auto jsVal = info[0];
3167      if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3168          bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3169          bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3170          ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3171          return;
3172      }
3173      if (jsVal->IsNumber()) {
3174          auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3175          if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3176              (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3177              sizeType = BackgroundImageSizeType::AUTO;
3178          }
3179          bgImgSize.SetSizeTypeX(sizeType);
3180          bgImgSize.SetSizeTypeY(sizeType);
3181      } else {
3182          CalcDimension width;
3183          CalcDimension height;
3184          JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3185          ParseJsDimensionVp(object->GetProperty("width"), width);
3186          ParseJsDimensionVp(object->GetProperty("height"), height);
3187          double valueWidth = width.ConvertToPx();
3188          double valueHeight = height.ConvertToPx();
3189          BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3190          BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3191          if (width.Unit() == DimensionUnit::PERCENT) {
3192              typeWidth = BackgroundImageSizeType::PERCENT;
3193              valueWidth = width.Value() * FULL_DIMENSION;
3194          }
3195          if (height.Unit() == DimensionUnit::PERCENT) {
3196              typeHeight = BackgroundImageSizeType::PERCENT;
3197              valueHeight = height.Value() * FULL_DIMENSION;
3198          }
3199          bgImgSize.SetSizeTypeX(typeWidth);
3200          bgImgSize.SetSizeValueX(valueWidth);
3201          bgImgSize.SetSizeTypeY(typeHeight);
3202          bgImgSize.SetSizeValueY(valueHeight);
3203      }
3204  
3205      ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3206  }
3207  
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3208  void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3209  {
3210      if (align > 8 || align < 0) {
3211          return;
3212      }
3213      std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3214          { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3215          { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3216      SetBgImgPosition(
3217                  DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3218  }
3219  
JsBackgroundImagePosition(const JSCallbackInfo & info)3220  void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3221  {
3222      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3223      BackgroundImagePosition bgImgPosition;
3224      auto jsVal = info[0];
3225      if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3226          SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3227          ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3228          return;
3229      }
3230      if (jsVal->IsNumber()) {
3231          int32_t align = jsVal->ToNumber<int32_t>();
3232          bgImgPosition.SetIsAlign(true);
3233          SetBgImgPositionWithAlign(bgImgPosition, align);
3234      } else {
3235          CalcDimension x;
3236          CalcDimension y;
3237          JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3238          ParseJsDimensionVp(object->GetProperty("x"), x);
3239          ParseJsDimensionVp(object->GetProperty("y"), y);
3240          double valueX = x.Value();
3241          double valueY = y.Value();
3242          if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3243              valueX = x.ConvertToPx();
3244              valueY = y.ConvertToPx();
3245          }
3246          DimensionUnit typeX = DimensionUnit::PX;
3247          DimensionUnit typeY = DimensionUnit::PX;
3248          if (x.Unit() == DimensionUnit::PERCENT) {
3249              valueX = x.Value();
3250              typeX = DimensionUnit::PERCENT;
3251          }
3252          if (y.Unit() == DimensionUnit::PERCENT) {
3253              valueY = y.Value();
3254              typeY = DimensionUnit::PERCENT;
3255          }
3256          SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3257      }
3258  
3259      ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3260  }
3261  
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)3262  std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
3263  {
3264      JSRef<JSVal> arg = info[optionIndex];
3265      if (!arg->IsArray()) {
3266          return std::vector<NG::OptionParam>();
3267      }
3268      auto paramArray = JSRef<JSArray>::Cast(arg);
3269      auto paramArrayLength = paramArray->Length();
3270      std::vector<NG::OptionParam> params(paramArrayLength);
3271      // parse paramArray
3272      for (size_t i = 0; i < paramArrayLength; ++i) {
3273          if (!paramArray->GetValueAt(i)->IsObject()) {
3274              return std::vector<NG::OptionParam>();
3275          }
3276          auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
3277          JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
3278              params[i].value);
3279          auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
3280          if (!actionFunc->IsFunction()) {
3281              return params;
3282          }
3283          auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
3284          auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3285          // set onClick function
3286          params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
3287              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
3288              ACE_SCORING_EVENT("menu.action");
3289              PipelineContext::SetCallBackNode(node);
3290              if (func) {
3291                  func->Execute();
3292              }
3293          };
3294          std::string iconPath;
3295          if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
3296              params[i].icon = iconPath;
3297          }
3298          if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
3299              std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
3300              JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
3301                  indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
3302              params[i].symbol = symbolApply;
3303          }
3304          auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
3305          if (enabled->IsBoolean()) {
3306              params[i].enabled = enabled->ToBoolean();
3307          }
3308      }
3309      return params;
3310  }
3311  
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3312  void ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3313  {
3314      auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
3315      NG::BorderRadiusProperty menuBorderRadius;
3316      CalcDimension borderRadius;
3317      if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
3318          if (borderRadius.Unit() != DimensionUnit::PERCENT && GreatOrEqual(borderRadius.Value(), 0.0f)) {
3319              menuBorderRadius.SetRadius(borderRadius);
3320              menuBorderRadius.multiValued = false;
3321              menuParam.borderRadius = menuBorderRadius;
3322          };
3323      } else if (borderRadiusValue->IsObject()) {
3324          JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
3325          CalcDimension topLeft;
3326          CalcDimension topRight;
3327          CalcDimension bottomLeft;
3328          CalcDimension bottomRight;
3329          bool hasSetBorderRadius =
3330              JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3331          if (LessNotEqual(topLeft.Value(), 0.0f)) {
3332              topLeft.Reset();
3333          }
3334          if (LessNotEqual(topRight.Value(), 0.0f)) {
3335              topRight.Reset();
3336          }
3337          if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
3338              bottomLeft.Reset();
3339          }
3340          if (LessNotEqual(bottomRight.Value(), 0.0f)) {
3341              bottomRight.Reset();
3342          }
3343          auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
3344          menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
3345          menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
3346          menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
3347          menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
3348          menuBorderRadius.multiValued = true;
3349          menuParam.borderRadius = menuBorderRadius;
3350      }
3351  }
3352  
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3353  void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3354  {
3355      auto enableArrowValue = menuOptions->GetProperty("enableArrow");
3356      if (enableArrowValue->IsBoolean()) {
3357          menuParam.enableArrow = enableArrowValue->ToBoolean();
3358      }
3359  
3360      auto arrowOffset = menuOptions->GetProperty("arrowOffset");
3361      CalcDimension offset;
3362      if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
3363          menuParam.arrowOffset = offset;
3364      }
3365  
3366      // if enableArrow is true and placement not set, set placement default value to top.
3367      if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
3368          menuParam.placement = Placement::TOP;
3369      }
3370  }
3371  
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)3372  void ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
3373  {
3374      CalcDimension dimension;
3375      if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
3376          return;
3377      }
3378  
3379      if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
3380          calcDimension = dimension;
3381      }
3382  }
3383  
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3384  void ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3385  {
3386      auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
3387      if (!marginVal->IsObject()) {
3388          return;
3389      }
3390  
3391      CommonCalcDimension commonCalcDimension;
3392      auto object = JSRef<JSObject>::Cast(marginVal);
3393      ParseLayoutRegionMargin(object->GetProperty(TOP_PROPERTY), commonCalcDimension.top);
3394      ParseLayoutRegionMargin(object->GetProperty(BOTTOM_PROPERTY), commonCalcDimension.bottom);
3395      ParseLayoutRegionMargin(object->GetProperty(LEFT_PROPERTY), commonCalcDimension.left);
3396      ParseLayoutRegionMargin(object->GetProperty(RIGHT_PROPERTY), commonCalcDimension.right);
3397  
3398      if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3399          commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3400          menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
3401              commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3402      }
3403  }
3404  
GetMenuShowInSubwindow(NG::MenuParam & menuParam)3405  void GetMenuShowInSubwindow(NG::MenuParam& menuParam)
3406  {
3407      menuParam.isShowInSubWindow = false;
3408      auto pipeline = PipelineBase::GetCurrentContext();
3409      CHECK_NULL_VOID(pipeline);
3410      auto theme = pipeline->GetTheme<SelectTheme>();
3411      CHECK_NULL_VOID(theme);
3412      menuParam.isShowInSubWindow = theme->GetExpandDisplay();
3413  }
3414  
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3415  void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3416  {
3417      auto offsetVal = menuOptions->GetProperty("offset");
3418      if (offsetVal->IsObject()) {
3419          auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
3420          JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
3421          JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
3422          CalcDimension dx;
3423          CalcDimension dy;
3424          if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
3425              menuParam.positionOffset.SetX(dx.ConvertToPx());
3426          }
3427          if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
3428              menuParam.positionOffset.SetY(dy.ConvertToPx());
3429          }
3430      }
3431  
3432      auto placementValue = menuOptions->GetProperty("placement");
3433      if (placementValue->IsNumber()) {
3434          auto placement = placementValue->ToNumber<int32_t>();
3435          if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
3436              menuParam.placement = PLACEMENT[placement];
3437          }
3438      }
3439  
3440      auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
3441      Color backgroundColor;
3442      if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
3443          menuParam.backgroundColor = backgroundColor;
3444      }
3445  
3446      auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
3447      if (backgroundBlurStyle->IsNumber()) {
3448          auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
3449          if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3450              blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3451              menuParam.backgroundBlurStyle = blurStyle;
3452          }
3453      }
3454      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3455      auto onAppearValue = menuOptions->GetProperty("onAppear");
3456      if (onAppearValue->IsFunction()) {
3457          RefPtr<JsFunction> jsOnAppearFunc =
3458              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
3459          auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
3460              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3461              ACE_SCORING_EVENT("onAppear");
3462              PipelineContext::SetCallBackNode(node);
3463              func->Execute();
3464          };
3465          menuParam.onAppear = std::move(onAppear);
3466      }
3467  
3468      auto onDisappearValue = menuOptions->GetProperty("onDisappear");
3469      if (onDisappearValue->IsFunction()) {
3470          RefPtr<JsFunction> jsOnDisAppearFunc =
3471              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
3472          auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
3473                                 node = frameNode]() {
3474              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3475              ACE_SCORING_EVENT("onDisappear");
3476              PipelineContext::SetCallBackNode(node);
3477              func->Execute();
3478          };
3479          menuParam.onDisappear = std::move(onDisappear);
3480      }
3481      auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
3482      if (aboutToAppearValue->IsFunction()) {
3483          RefPtr<JsFunction> jsAboutToAppearFunc =
3484              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
3485          auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
3486                              node = frameNode]() {
3487              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3488              ACE_SCORING_EVENT("aboutToAppear");
3489              PipelineContext::SetCallBackNode(node);
3490              func->Execute();
3491          };
3492          menuParam.aboutToAppear = std::move(aboutToAppear);
3493      }
3494  
3495      auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
3496      if (aboutToDisAppearValue->IsFunction()) {
3497          RefPtr<JsFunction> jsAboutToDisAppearFunc =
3498              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
3499          auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
3500                                 node = frameNode]() {
3501              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3502              ACE_SCORING_EVENT("aboutToDisappear");
3503              PipelineContext::SetCallBackNode(node);
3504              func->Execute();
3505          };
3506          menuParam.aboutToDisappear = std::move(aboutToDisappear);
3507      }
3508  
3509      auto menuTransition = menuOptions->GetProperty("transition");
3510      menuParam.hasTransitionEffect = false;
3511      if (menuTransition->IsObject()) {
3512          auto obj = JSRef<JSObject>::Cast(menuTransition);
3513          menuParam.hasTransitionEffect = true;
3514          menuParam.transition = ParseChainedTransition(obj, info.GetExecutionContext());
3515      }
3516  
3517      JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
3518      GetMenuShowInSubwindow(menuParam);
3519      if (menuParam.isShowInSubWindow) {
3520          if (showInSubWindowValue->IsBoolean()) {
3521              menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
3522          }
3523      }
3524      ParseMenuArrowParam(menuOptions, menuParam);
3525      ParseMenuBorderRadius(menuOptions, menuParam);
3526      ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
3527  }
3528  
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)3529  void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
3530  {
3531      if (!info[optionIndex]->IsObject()) {
3532          return;
3533      }
3534      auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
3535      JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
3536      ParseMenuParam(info, menuOptions, menuParam);
3537  }
3538  
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)3539  void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
3540  {
3541      constexpr int scaleArraySize = 2;
3542      if (scaleArray->Length() == scaleArraySize) {
3543          auto scalePropertyFrom = scaleArray->GetValueAt(0);
3544          if (scalePropertyFrom->IsNumber()) {
3545              auto scaleFrom = scalePropertyFrom->ToNumber<float>();
3546              options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
3547          }
3548          auto scalePropertyTo = scaleArray->GetValueAt(1);
3549          if (scalePropertyTo->IsNumber()) {
3550              auto scaleTo = scalePropertyTo->ToNumber<float>();
3551              options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
3552          }
3553      }
3554  }
3555  
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)3556  void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
3557      NG::MenuParam& menuParam)
3558  {
3559      menuParam.previewAnimationOptions.scaleFrom = -1.0f;
3560      menuParam.previewAnimationOptions.scaleTo = -1.0f;
3561  
3562      auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
3563      if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
3564          auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
3565          auto scaleProperty = animationOptionsObj->GetProperty("scale");
3566          if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
3567              JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
3568              ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
3569          }
3570          auto previewTransition = animationOptionsObj->GetProperty("transition");
3571          menuParam.hasPreviewTransitionEffect = false;
3572          if (previewTransition->IsObject()) {
3573              auto obj = JSRef<JSObject>::Cast(previewTransition);
3574              menuParam.hasPreviewTransitionEffect = true;
3575              menuParam.previewTransition = ParseChainedTransition(obj, info.GetExecutionContext());
3576          }
3577          if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
3578              menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
3579              menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
3580              return;
3581          }
3582          auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
3583          menuParam.isShowHoverImage = false;
3584          menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
3585          menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
3586          if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
3587              JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
3588              ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
3589              menuParam.isShowHoverImage = true;
3590          }
3591      }
3592  }
3593  
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)3594  void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
3595      std::function<void()>& previewBuildFunc)
3596  {
3597      if (!args->IsObject()) {
3598          return;
3599      }
3600      auto menuContentOptions = JSRef<JSObject>::Cast(args);
3601      ParseMenuParam(info, menuContentOptions, menuParam);
3602      RefPtr<JsFunction> previewBuilderFunc;
3603      auto preview = menuContentOptions->GetProperty("preview");
3604      if (!preview->IsFunction() && !preview->IsNumber()) {
3605          return;
3606      }
3607  
3608      if (preview->IsNumber()) {
3609          if (preview->ToNumber<int32_t>() == 1) {
3610              menuParam.previewMode = MenuPreviewMode::IMAGE;
3611              ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3612          }
3613      } else {
3614          previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
3615          CHECK_NULL_VOID(previewBuilderFunc);
3616          auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3617          previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
3618                                 node = frameNode]() {
3619              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3620              ACE_SCORING_EVENT("BuildContextMenuPreviwer");
3621              PipelineContext::SetCallBackNode(node);
3622              func->Execute();
3623          };
3624          menuParam.previewMode = MenuPreviewMode::CUSTOM;
3625          ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3626      }
3627  }
3628  
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)3629  uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
3630  {
3631      size_t builderIndex = 0;
3632      if (info[0]->IsBoolean()) {
3633          menuParam.isShow = info[0]->ToBoolean();
3634          menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3635          menuParam.placement = Placement::BOTTOM_LEFT;
3636          builderIndex = 1;
3637      } else if (info[0]->IsObject()) {
3638          JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
3639          menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3640          auto isShowObj = callbackObj->GetProperty("value");
3641          if (isShowObj->IsBoolean()) {
3642              menuParam.isShow = isShowObj->IsBoolean();
3643              menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3644              builderIndex = 1;
3645          }
3646      }
3647      return builderIndex;
3648  }
3649  
JsBindMenu(const JSCallbackInfo & info)3650  void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
3651  {
3652      NG::MenuParam menuParam;
3653      if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
3654          menuParam.placement = Placement::BOTTOM_LEFT;
3655      }
3656      size_t builderIndex = 0;
3657      GetMenuShowInSubwindow(menuParam);
3658      if (info.Length() > PARAMETER_LENGTH_FIRST) {
3659          auto jsVal = info[0];
3660          if (jsVal->IsBoolean()) {
3661              menuParam.isShow = jsVal->ToBoolean();
3662              menuParam.setShow = true;
3663              builderIndex = 1;
3664              if (info.Length() > PARAMETER_LENGTH_SECOND) {
3665                  ParseBindOptionParam(info, menuParam, builderIndex + 1);
3666              }
3667          } else if (jsVal->IsUndefined()) {
3668              menuParam.setShow = true;
3669              menuParam.isShow = false;
3670              builderIndex = 1;
3671              if (info.Length() > PARAMETER_LENGTH_SECOND) {
3672                  ParseBindOptionParam(info, menuParam, builderIndex + 1);
3673              }
3674          } else if (jsVal->IsObject()) {
3675              JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
3676              menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3677              auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
3678              if (isShowObj->IsBoolean()) {
3679                  menuParam.isShow = isShowObj->ToBoolean();
3680                  menuParam.setShow = true;
3681                  builderIndex = 1;
3682                  if (info.Length() > PARAMETER_LENGTH_SECOND) {
3683                      ParseBindOptionParam(info, menuParam, builderIndex + 1);
3684                  }
3685              } else {
3686                  builderIndex = 0;
3687                  ParseBindOptionParam(info, menuParam, builderIndex + 1);
3688              }
3689          }
3690      }
3691  
3692      if (info[builderIndex]->IsArray()) {
3693          std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex);
3694          ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
3695      } else if (info[builderIndex]->IsObject()) {
3696          // CustomBuilder
3697          JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
3698          auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
3699          if (!builder->IsFunction()) {
3700              return;
3701          }
3702          auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3703  
3704          auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3705          CHECK_NULL_VOID(builderFunc);
3706          auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
3707              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3708              ACE_SCORING_EVENT("BuildMenu");
3709              auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3710              func->Execute();
3711          };
3712          ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
3713      }
3714  }
3715  
JsPadding(const JSCallbackInfo & info)3716  void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3717  {
3718      ParseMarginOrPadding(info, EdgeType::PADDING);
3719  }
3720  
JsMargin(const JSCallbackInfo & info)3721  void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3722  {
3723      ParseMarginOrPadding(info, EdgeType::MARGIN);
3724  }
3725  
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3726  void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
3727  {
3728      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3729          JSCallbackInfoType::NUMBER };
3730      auto jsVal = info[0];
3731      if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3732          auto resetDimension = CalcDimension(0.0);
3733          if (type == EdgeType::MARGIN) {
3734              ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3735          } else if (type == EdgeType::PADDING) {
3736              ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3737          } else if (type == EdgeType::SAFE_AREA_PADDING) {
3738              ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
3739          }
3740          return;
3741      }
3742  
3743      if (jsVal->IsObject()) {
3744          JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3745  
3746          CalcDimension length;
3747          if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
3748              ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
3749              return;
3750          }
3751  
3752          CommonCalcDimension commonCalcDimension;
3753          auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
3754          if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3755              commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3756              if (type == EdgeType::MARGIN)  {
3757                  if (useLengthMetrics) {
3758                      ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
3759                          commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3760                  } else {
3761                      ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
3762                          commonCalcDimension.left, commonCalcDimension.right);
3763                  }
3764              } else if (type == EdgeType::PADDING) {
3765                  if (useLengthMetrics) {
3766                      ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
3767                          commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3768                  } else {
3769                      ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
3770                          commonCalcDimension.left, commonCalcDimension.right);
3771                  }
3772              } else if (type == EdgeType::SAFE_AREA_PADDING) {
3773                  if (useLengthMetrics) {
3774                      ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
3775                          commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3776                  } else {
3777                      ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
3778                          commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3779                  }
3780              }
3781              return;
3782          }
3783      }
3784  
3785      CalcDimension length;
3786      if (!ParseJsDimensionVp(jsVal, length)) {
3787          // use default value.
3788          length.Reset();
3789      }
3790      if (type == EdgeType::MARGIN) {
3791          ViewAbstractModel::GetInstance()->SetMargin(length);
3792      } else if (type == EdgeType::PADDING) {
3793          ViewAbstractModel::GetInstance()->SetPadding(length);
3794      }
3795  }
3796  
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)3797  NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
3798      const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
3799      const std::optional<CalcDimension>& end)
3800  {
3801      NG::PaddingProperty paddings;
3802      if (start.has_value()) {
3803          if (start.value().Unit() == DimensionUnit::CALC) {
3804              paddings.start = NG::CalcLength(start.value().CalcValue());
3805          } else {
3806              paddings.start = NG::CalcLength(start.value());
3807          }
3808      }
3809      if (bottom.has_value()) {
3810          if (bottom.value().Unit() == DimensionUnit::CALC) {
3811              paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
3812          } else {
3813              paddings.bottom = NG::CalcLength(bottom.value());
3814          }
3815      }
3816      if (end.has_value()) {
3817          if (end.value().Unit() == DimensionUnit::CALC) {
3818              paddings.end = NG::CalcLength(end.value().CalcValue());
3819          } else {
3820              paddings.end = NG::CalcLength(end.value());
3821          }
3822      }
3823      if (top.has_value()) {
3824          if (top.value().Unit() == DimensionUnit::CALC) {
3825              paddings.top = NG::CalcLength(top.value().CalcValue());
3826          } else {
3827              paddings.top = NG::CalcLength(top.value());
3828          }
3829      }
3830      return paddings;
3831  }
3832  
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)3833  void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
3834      std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
3835  {
3836      CalcDimension leftDimen;
3837      if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
3838          left = leftDimen;
3839      }
3840      CalcDimension rightDimen;
3841      if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
3842          right = rightDimen;
3843      }
3844      CalcDimension topDimen;
3845      if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
3846          top = topDimen;
3847      }
3848      CalcDimension bottomDimen;
3849      if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
3850          bottom = bottomDimen;
3851      }
3852  }
3853  
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3854  void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3855      const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3856  {
3857      auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3858      if (jsStart->IsObject()) {
3859          JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3860          CalcDimension calcDimension;
3861          if (ParseJsLengthMetrics(startObj, calcDimension)) {
3862              localizedCalcDimension.start = calcDimension;
3863          }
3864      }
3865      auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3866      if (jsEnd->IsObject()) {
3867          JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3868          CalcDimension calcDimension;
3869          if (ParseJsLengthMetrics(endObj, calcDimension)) {
3870              localizedCalcDimension.end = calcDimension;
3871          }
3872      }
3873      auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3874      if (jsTop->IsObject()) {
3875          JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3876          CalcDimension calcDimension;
3877          if (ParseJsLengthMetrics(topObj, calcDimension)) {
3878              localizedCalcDimension.top = calcDimension;
3879          }
3880      }
3881      auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3882      if (jsBottom->IsObject()) {
3883          JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3884          CalcDimension calcDimension;
3885          if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3886              localizedCalcDimension.bottom = calcDimension;
3887          }
3888      }
3889  }
3890  
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3891  bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3892      const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3893  {
3894      if (CheckLengthMetrics(object)) {
3895          LocalizedCalcDimension localizedCalcDimension;
3896          ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3897          auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
3898          commonCalcDimension.top = localizedCalcDimension.top;
3899          commonCalcDimension.bottom = localizedCalcDimension.bottom;
3900          commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
3901          commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
3902          return true;
3903      }
3904      ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3905          commonCalcDimension.right);
3906      return false;
3907  }
3908  
JsOutline(const JSCallbackInfo & info)3909  void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3910  {
3911      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3912      auto jsVal = info[0];
3913      if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3914          CalcDimension borderWidth;
3915          ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3916          ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3917          ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3918          ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3919          return;
3920      }
3921      JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3922      auto valueOuterWidth = object->GetProperty("width");
3923      if (!valueOuterWidth->IsUndefined()) {
3924          ParseOuterBorderWidth(valueOuterWidth);
3925      } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3926          ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3927      }
3928  
3929      // use default value when undefined.
3930      ParseOuterBorderColor(object->GetProperty("color"));
3931  
3932      auto valueOuterRadius = object->GetProperty("radius");
3933      if (!valueOuterRadius->IsUndefined()) {
3934          ParseOuterBorderRadius(valueOuterRadius);
3935      } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3936          ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3937      }
3938      // use default value when undefined.
3939      ParseOuterBorderStyle(object->GetProperty("style"));
3940      info.ReturnSelf();
3941  }
3942  
JsOutlineWidth(const JSCallbackInfo & info)3943  void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
3944  {
3945      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3946          JSCallbackInfoType::OBJECT };
3947      auto jsVal = info[0];
3948      if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
3949          ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3950          return;
3951      }
3952      ParseOuterBorderWidth(jsVal);
3953  }
3954  
JsOutlineColor(const JSCallbackInfo & info)3955  void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
3956  {
3957      ParseOuterBorderColor(info[0]);
3958  }
3959  
JsOutlineRadius(const JSCallbackInfo & info)3960  void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
3961  {
3962      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3963          JSCallbackInfoType::OBJECT };
3964      auto jsVal = info[0];
3965      if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
3966          ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3967          return;
3968      }
3969      ParseOuterBorderRadius(jsVal);
3970  }
3971  
JsOutlineStyle(const JSCallbackInfo & info)3972  void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
3973  {
3974      ParseOuterBorderStyle(info[0]);
3975  }
3976  
JsBorder(const JSCallbackInfo & info)3977  void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
3978  {
3979      if (!info[0]->IsObject()) {
3980          CalcDimension borderWidth;
3981          ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3982          ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3983          ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
3984          ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3985          ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
3986          ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
3987          return;
3988      }
3989      JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3990  
3991      auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3992      if (!valueWidth->IsUndefined()) {
3993          ParseBorderWidth(valueWidth);
3994      }
3995  
3996      // use default value when undefined.
3997      ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
3998  
3999      auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
4000      if (!valueRadius->IsUndefined()) {
4001          ParseBorderRadius(valueRadius);
4002      }
4003      // use default value when undefined.
4004      ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
4005  
4006      auto dashGap = object->GetProperty("dashGap");
4007      if (!dashGap->IsUndefined()) {
4008          ParseDashGap(dashGap);
4009      }
4010      auto dashWidth = object->GetProperty("dashWidth");
4011      if (!dashWidth->IsUndefined()) {
4012          ParseDashWidth(dashWidth);
4013      }
4014  
4015      info.ReturnSelf();
4016  }
4017  
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4018  bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
4019  {
4020      if (!args->IsObject()) {
4021          return false;
4022      }
4023      JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4024      if (obj->IsUndefined()) {
4025          return true;
4026      }
4027      // filter dynamic $r raw input
4028      if (obj->HasProperty("id")) {
4029          return false;
4030      }
4031      if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
4032          (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
4033          (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
4034          (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
4035          (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
4036          (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
4037          return true;
4038      }
4039  
4040      return false;
4041  }
4042  
JsBorderWidth(const JSCallbackInfo & info)4043  void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
4044  {
4045      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4046          JSCallbackInfoType::OBJECT };
4047      auto jsVal = info[0];
4048      if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
4049          ViewAbstractModel::GetInstance()->SetBorderWidth({});
4050          return;
4051      }
4052      ParseBorderWidth(jsVal);
4053  }
4054  
ParseBorderWidth(const JSRef<JSVal> & args)4055  void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
4056  {
4057      CalcDimension borderWidth;
4058      if (ParseJsDimensionVp(args, borderWidth)) {
4059          if (borderWidth.IsNegative()) {
4060              borderWidth.Reset();
4061          }
4062          if (borderWidth.Unit() == DimensionUnit::PERCENT) {
4063              borderWidth.Reset();
4064          }
4065          ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4066      } else if (args->IsObject()) {
4067          if (IsBorderWidthObjUndefined(args)) {
4068              ViewAbstractModel::GetInstance()->SetBorderWidth({});
4069              return;
4070          }
4071          CommonCalcDimension commonCalcDimension;
4072          JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4073          if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
4074              ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
4075                  commonCalcDimension.top, commonCalcDimension.bottom, true);
4076              return;
4077          }
4078          ViewAbstractModel::GetInstance()->SetBorderWidth(
4079              commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4080      } else {
4081          return;
4082      }
4083  }
4084  
ParseDashGap(const JSRef<JSVal> & args)4085  void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
4086  {
4087      CalcDimension dashGap;
4088      if (ParseLengthMetricsToDimension(args, dashGap)) {
4089          if (dashGap.Unit() == DimensionUnit::PERCENT) {
4090              dashGap.Reset();
4091          }
4092          ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4093      } else if (args->IsObject()) {
4094          CommonCalcDimension commonCalcDimension;
4095          JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4096          ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4097          ViewAbstractModel::GetInstance()->SetDashGap(
4098              commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4099      } else {
4100          dashGap.Reset();
4101          ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4102      }
4103  }
4104  
ParseDashWidth(const JSRef<JSVal> & args)4105  void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4106  {
4107      CalcDimension dashWidth;
4108      if (ParseLengthMetricsToDimension(args, dashWidth)) {
4109          if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4110              dashWidth.Reset();
4111          }
4112          ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4113      } else if (args->IsObject()) {
4114          CommonCalcDimension commonCalcDimension;
4115          JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4116          ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4117          ViewAbstractModel::GetInstance()->SetDashWidth(
4118              commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4119      } else {
4120          dashWidth.Reset();
4121          ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4122      }
4123  }
4124  
ParseOuterBorderWidth(const JSRef<JSVal> & args)4125  void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4126  {
4127      CalcDimension borderWidth;
4128      if (ParseJsDimensionVp(args, borderWidth)) {
4129          if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4130              borderWidth.Reset();
4131          }
4132          ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4133      } else if (args->IsObject()) {
4134          std::optional<CalcDimension> leftDimen;
4135          std::optional<CalcDimension> rightDimen;
4136          std::optional<CalcDimension> topDimen;
4137          std::optional<CalcDimension> bottomDimen;
4138          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4139          CalcDimension left;
4140          if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4141              if (left.Unit() == DimensionUnit::PERCENT) {
4142                  left.Reset();
4143              }
4144              leftDimen = left;
4145          }
4146          CalcDimension right;
4147          if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4148              if (right.Unit() == DimensionUnit::PERCENT) {
4149                  right.Reset();
4150              }
4151              rightDimen = right;
4152          }
4153          CalcDimension top;
4154          if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4155              if (top.Unit() == DimensionUnit::PERCENT) {
4156                  top.Reset();
4157              }
4158              topDimen = top;
4159          }
4160          CalcDimension bottom;
4161          if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4162              if (bottom.Unit() == DimensionUnit::PERCENT) {
4163                  bottom.Reset();
4164              }
4165              bottomDimen = bottom;
4166          }
4167          ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4168      } else {
4169          return;
4170      }
4171  }
4172  
JsBorderImage(const JSCallbackInfo & info)4173  void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4174  {
4175      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4176      auto jsVal = info[0];
4177      if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4178          RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4179          uint8_t imageBorderBitsets = 0;
4180          ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4181          return;
4182      }
4183      JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4184      CHECK_NULL_VOID(!object->IsEmpty());
4185  
4186      RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4187      uint8_t imageBorderBitsets = 0;
4188  
4189      auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4190      CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4191      std::string srcResult;
4192      std::string bundleName;
4193      std::string moduleName;
4194      GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4195      borderImage->SetBundleName(bundleName);
4196      borderImage->SetModuleName(moduleName);
4197      if (valueSource->IsString() && !valueSource->ToString().empty()) {
4198          borderImage->SetSrc(valueSource->ToString());
4199          imageBorderBitsets |= BorderImage::SOURCE_BIT;
4200      } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4201          borderImage->SetSrc(srcResult);
4202          imageBorderBitsets |= BorderImage::SOURCE_BIT;
4203      } else if (valueSource->IsObject()) {
4204          ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4205      }
4206      auto valueOutset = object->GetProperty("outset");
4207      if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4208          imageBorderBitsets |= BorderImage::OUTSET_BIT;
4209          ParseBorderImageOutset(valueOutset, borderImage);
4210      }
4211      auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4212      if (!valueRepeat->IsNull()) {
4213          imageBorderBitsets |= BorderImage::REPEAT_BIT;
4214          ParseBorderImageRepeat(valueRepeat, borderImage);
4215      }
4216      auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4217      if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4218          imageBorderBitsets |= BorderImage::SLICE_BIT;
4219          ParseBorderImageSlice(valueSlice, borderImage);
4220      }
4221      auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4222      if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4223          imageBorderBitsets |= BorderImage::WIDTH_BIT;
4224          ParseBorderImageWidth(valueWidth, borderImage);
4225      }
4226      auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4227      if (needFill->IsBoolean()) {
4228          borderImage->SetNeedFillCenter(needFill->ToBoolean());
4229      }
4230      ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4231      info.ReturnSelf();
4232  }
4233  
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4234  bool JSViewAbstract::ParseBorderImageDimension(
4235      const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4236  {
4237      if (!args->IsObject()) {
4238          return false;
4239      }
4240      JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4241      if (CheckLengthMetrics(object)) {
4242          LocalizedCalcDimension localizedCalcDimension;
4243          ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4244          borderImageDimension.topDimension = localizedCalcDimension.top;
4245          borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4246          borderImageDimension.startDimension = localizedCalcDimension.start;
4247          borderImageDimension.endDimension = localizedCalcDimension.end;
4248          return true;
4249      }
4250      static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4251          static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4252          static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4253      for (uint32_t i = 0; i < keys.size(); i++) {
4254          CalcDimension currentDimension;
4255          auto dimensionValue = object->GetProperty(keys.at(i));
4256          if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4257              auto direction = static_cast<BorderImageDirection>(i);
4258              switch (direction) {
4259                  case BorderImageDirection::LEFT:
4260                      borderImageDimension.leftDimension = currentDimension;
4261                      break;
4262                  case BorderImageDirection::RIGHT:
4263                      borderImageDimension.rightDimension = currentDimension;
4264                      break;
4265                  case BorderImageDirection::TOP:
4266                      borderImageDimension.topDimension = currentDimension;
4267                      break;
4268                  case BorderImageDirection::BOTTOM:
4269                      borderImageDimension.bottomDimension = currentDimension;
4270                      break;
4271                  default:
4272                      break;
4273              }
4274          }
4275      }
4276      return false;
4277  }
4278  
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4279  void JSViewAbstract::ParseBorderImageLengthMetrics(
4280      const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4281  {
4282      for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4283          auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4284          if (!jsVal->IsObject()) {
4285              continue;
4286          }
4287          JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4288          CalcDimension calcDimension;
4289          if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4290              auto direction = static_cast<BorderImageDirection>(i);
4291              switch (direction) {
4292                  case BorderImageDirection::LEFT:
4293                      localizedCalcDimension.start = calcDimension;
4294                      break;
4295                  case BorderImageDirection::RIGHT:
4296                      localizedCalcDimension.end = calcDimension;
4297                      break;
4298                  case BorderImageDirection::TOP:
4299                      localizedCalcDimension.top = calcDimension;
4300                      break;
4301                  case BorderImageDirection::BOTTOM:
4302                      localizedCalcDimension.bottom = calcDimension;
4303                      break;
4304                  default:
4305                      break;
4306              }
4307          }
4308      }
4309  }
4310  
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4311  bool JSViewAbstract::CheckJSCallbackInfo(
4312      const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4313  {
4314      bool typeVerified = false;
4315      std::string unrecognizedType;
4316      for (const auto& infoType : infoTypes) {
4317          switch (infoType) {
4318              case JSCallbackInfoType::STRING:
4319                  if (tmpInfo->IsString()) {
4320                      typeVerified = true;
4321                  } else {
4322                      unrecognizedType += "string|";
4323                  }
4324                  break;
4325              case JSCallbackInfoType::NUMBER:
4326                  if (tmpInfo->IsNumber()) {
4327                      typeVerified = true;
4328                  } else {
4329                      unrecognizedType += "number|";
4330                  }
4331                  break;
4332              case JSCallbackInfoType::OBJECT:
4333                  if (tmpInfo->IsObject()) {
4334                      typeVerified = true;
4335                  } else {
4336                      unrecognizedType += "object|";
4337                  }
4338                  break;
4339              case JSCallbackInfoType::FUNCTION:
4340                  if (tmpInfo->IsFunction()) {
4341                      typeVerified = true;
4342                  } else {
4343                      unrecognizedType += "Function|";
4344                  }
4345                  break;
4346              default:
4347                  break;
4348          }
4349      }
4350      if (!typeVerified) {
4351          LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4352              unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4353      }
4354      return typeVerified || infoTypes.size() == 0;
4355  }
4356  
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4357  void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4358  {
4359      switch (direction) {
4360          case NG::GradientDirection::LEFT:
4361              lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4362              break;
4363          case NG::GradientDirection::RIGHT:
4364              lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4365              break;
4366          case NG::GradientDirection::TOP:
4367              lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4368              break;
4369          case NG::GradientDirection::BOTTOM:
4370              lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4371              break;
4372          case NG::GradientDirection::LEFT_TOP:
4373              lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4374              lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4375              break;
4376          case NG::GradientDirection::LEFT_BOTTOM:
4377              lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4378              lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4379              break;
4380          case NG::GradientDirection::RIGHT_TOP:
4381              lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4382              lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4383              break;
4384          case NG::GradientDirection::RIGHT_BOTTOM:
4385              lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4386              lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4387              break;
4388          case NG::GradientDirection::NONE:
4389          case NG::GradientDirection::START_TO_END:
4390          case NG::GradientDirection::END_TO_START:
4391          default:
4392              break;
4393      }
4394  }
4395  
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)4396  void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
4397  {
4398      if (!args->IsObject()) {
4399          return;
4400      }
4401      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
4402      NG::Gradient lineGradient;
4403      lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4404      // angle
4405      std::optional<float> degree;
4406      if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4407          GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
4408      } else {
4409          GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
4410      }
4411      if (degree) {
4412          lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
4413          degree.reset();
4414      }
4415      // direction
4416      auto direction = static_cast<NG::GradientDirection>(
4417          jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
4418          static_cast<int32_t>(NG::GradientDirection::NONE)));
4419      UpdateGradientWithDirection(lineGradient, direction);
4420      auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
4421      lineGradient.SetRepeat(repeating);
4422      NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
4423      ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
4424      bitset |= BorderImage::GRADIENT_BIT;
4425  }
4426  
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4427  void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4428  {
4429      auto repeatString = args->ToString();
4430      if (repeatString == "Repeat") {
4431          borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
4432      } else if (repeatString == "Round") {
4433          borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
4434      } else if (repeatString == "Space") {
4435          borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
4436      } else {
4437          borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
4438      }
4439  }
4440  
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4441  void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4442  {
4443      CalcDimension outsetDimension;
4444      if (ParseJsDimensionVp(args, outsetDimension)) {
4445          borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
4446          borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
4447          borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
4448          borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
4449          return;
4450      }
4451      BorderImage::BorderImageOption option;
4452      ParseBorderImageDimension(args, option);
4453      if (option.startDimension.has_value()) {
4454          borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
4455      }
4456      if (option.endDimension.has_value()) {
4457          borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
4458      }
4459      if (option.leftDimension.has_value()) {
4460          borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
4461      }
4462      if (option.rightDimension.has_value()) {
4463          borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
4464      }
4465      if (option.topDimension.has_value()) {
4466          borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
4467      }
4468      if (option.bottomDimension.has_value()) {
4469          borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4470      }
4471  }
4472  
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4473  void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4474  {
4475      CalcDimension sliceDimension;
4476      if (ParseJsDimensionVp(args, sliceDimension)) {
4477          borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
4478          borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
4479          borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
4480          borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
4481          return;
4482      }
4483      if (!args->IsObject()) {
4484          return;
4485      }
4486      JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4487      if (CheckLengthMetrics(object)) {
4488          LocalizedCalcDimension localizedCalcDimension;
4489          ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4490          if (localizedCalcDimension.top.has_value()) {
4491              borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
4492          }
4493          if (localizedCalcDimension.bottom.has_value()) {
4494              borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
4495          }
4496          if (localizedCalcDimension.start.has_value()) {
4497              borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
4498          }
4499          if (localizedCalcDimension.end.has_value()) {
4500              borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
4501          }
4502          return;
4503      }
4504      static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4505          static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4506          static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4507      for (uint32_t i = 0; i < keys.size(); i++) {
4508          auto dimensionValue = object->GetProperty(keys.at(i));
4509          if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
4510              borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
4511          }
4512      }
4513  }
4514  
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4515  void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4516  {
4517      CalcDimension widthDimension;
4518      if (ParseJsDimensionVp(args, widthDimension)) {
4519          borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
4520          borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
4521          borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
4522          borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
4523          return;
4524      }
4525  
4526      BorderImage::BorderImageOption option;
4527      ParseBorderImageDimension(args, option);
4528      if (option.startDimension.has_value()) {
4529          borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
4530      }
4531      if (option.endDimension.has_value()) {
4532          borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
4533      }
4534      if (option.leftDimension.has_value()) {
4535          borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
4536      }
4537      if (option.rightDimension.has_value()) {
4538          borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
4539      }
4540      if (option.topDimension.has_value()) {
4541          borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
4542      }
4543      if (option.bottomDimension.has_value()) {
4544          borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4545      }
4546  }
4547  
JsBorderColor(const JSCallbackInfo & info)4548  void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
4549  {
4550      ParseBorderColor(info[0]);
4551  }
4552  
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)4553  NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
4554      const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
4555      const std::optional<Color>& colorBottom)
4556  {
4557      NG::BorderColorProperty borderColors;
4558      borderColors.startColor = colorStart;
4559      borderColors.endColor = colorEnd;
4560      borderColors.topColor = colorTop;
4561      borderColors.bottomColor = colorBottom;
4562      borderColors.multiValued = true;
4563      return borderColors;
4564  }
4565  
ParseBorderColor(const JSRef<JSVal> & args)4566  void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
4567  {
4568      Color borderColor;
4569      if (ParseJsColor(args, borderColor)) {
4570          ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
4571      } else if (args->IsObject()) {
4572          CommonColor commonColor;
4573          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4574          if (ParseCommonEdgeColors(object, commonColor)) {
4575              ViewAbstractModel::GetInstance()->SetBorderColor(
4576                  GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4577              return;
4578          }
4579          ViewAbstractModel::GetInstance()->SetBorderColor(
4580              commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4581      } else {
4582          ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4583      }
4584  }
4585  
ParseOuterBorderColor(const JSRef<JSVal> & args)4586  void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
4587  {
4588      Color borderColor;
4589      if (ParseJsColor(args, borderColor)) {
4590          ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
4591      } else if (args->IsObject()) {
4592          CommonColor commonColor;
4593          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4594          if (ParseCommonEdgeColors(object, commonColor)) {
4595              ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4596                  GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4597              return;
4598          }
4599          ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4600              commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4601      } else {
4602          ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4603      }
4604  }
4605  
JsBorderRadius(const JSCallbackInfo & info)4606  void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
4607  {
4608      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4609          JSCallbackInfoType::OBJECT };
4610      auto jsVal = info[0];
4611      if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
4612          ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
4613          return;
4614      }
4615      ParseBorderRadius(jsVal);
4616  }
4617  
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)4618  NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
4619      const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
4620      const std::optional<Dimension>& radiusBottomEnd)
4621  {
4622      NG::BorderRadiusProperty borderRadius;
4623      borderRadius.radiusTopStart = radiusTopStart;
4624      borderRadius.radiusTopEnd = radiusTopEnd;
4625      borderRadius.radiusBottomStart = radiusBottomStart;
4626      borderRadius.radiusBottomEnd = radiusBottomEnd;
4627      borderRadius.multiValued = true;
4628      return borderRadius;
4629  }
4630  
ParseBorderRadius(const JSRef<JSVal> & args)4631  void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
4632  {
4633      CalcDimension borderRadius;
4634      if (ParseJsDimensionVp(args, borderRadius)) {
4635          ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
4636      } else if (args->IsObject()) {
4637          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4638          CalcDimension topLeft;
4639          CalcDimension topRight;
4640          CalcDimension bottomLeft;
4641          CalcDimension bottomRight;
4642          if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4643              ViewAbstractModel::GetInstance()->SetBorderRadius(
4644                  GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4645                  return;
4646          }
4647          ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4648      }
4649  }
4650  
ParseOuterBorderRadius(const JSRef<JSVal> & args)4651  void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
4652  {
4653      if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
4654          return;
4655      }
4656      CalcDimension borderRadius;
4657      if (ParseJsDimensionVp(args, borderRadius)) {
4658          if (borderRadius.Unit() == DimensionUnit::PERCENT) {
4659              borderRadius.Reset();
4660          }
4661          ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
4662      } else if (args->IsObject()) {
4663          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4664          CalcDimension topLeft;
4665          CalcDimension topRight;
4666          CalcDimension bottomLeft;
4667          CalcDimension bottomRight;
4668          if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4669              ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
4670                  GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4671          }
4672          ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4673      }
4674  }
4675  
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4676  void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4677  {
4678      ParseJsDimensionVp(object->GetProperty(key), radius);
4679  }
4680  
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4681  void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4682  {
4683      if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
4684          JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
4685          ParseJsLengthMetrics(startObj, radius);
4686      }
4687  }
4688  
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)4689  bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
4690      CalcDimension& bottomLeft, CalcDimension& bottomRight)
4691  {
4692      if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
4693          object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
4694          CalcDimension topStart;
4695          CalcDimension topEnd;
4696          CalcDimension bottomStart;
4697          CalcDimension bottomEnd;
4698          GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
4699          GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
4700          GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
4701          GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
4702          topLeft = topStart;
4703          topRight = topEnd;
4704          bottomLeft = bottomStart;
4705          bottomRight = bottomEnd;
4706          return true;
4707      }
4708      GetBorderRadius("topLeft", object, topLeft);
4709      GetBorderRadius("topRight", object, topRight);
4710      GetBorderRadius("bottomLeft", object, bottomLeft);
4711      GetBorderRadius("bottomRight", object, bottomRight);
4712      return false;
4713  }
4714  
JsBorderStyle(const JSCallbackInfo & info)4715  void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
4716  {
4717      ParseBorderStyle(info[0]);
4718  }
4719  namespace {
ConvertBorderStyle(int32_t value)4720  BorderStyle ConvertBorderStyle(int32_t value)
4721  {
4722      auto style = static_cast<BorderStyle>(value);
4723      if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4724          style = BorderStyle::SOLID;
4725      }
4726      return style;
4727  }
4728  
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)4729  bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
4730  {
4731      style = static_cast<BorderStyle>(value);
4732      if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4733          return false;
4734      }
4735      return true;
4736  }
4737  } // namespace
4738  
ParseBorderStyle(const JSRef<JSVal> & args)4739  void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
4740  {
4741      if (args->IsObject()) {
4742          std::optional<BorderStyle> styleLeft;
4743          std::optional<BorderStyle> styleRight;
4744          std::optional<BorderStyle> styleTop;
4745          std::optional<BorderStyle> styleBottom;
4746          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4747          auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
4748          if (leftValue->IsNumber()) {
4749              styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4750          }
4751          auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
4752          if (rightValue->IsNumber()) {
4753              styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4754          }
4755          auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4756          if (topValue->IsNumber()) {
4757              styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4758          }
4759          auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4760          if (bottomValue->IsNumber()) {
4761              styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4762          }
4763          ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4764          return;
4765      }
4766      if (args->IsNumber()) {
4767          auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4768          ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
4769          return;
4770      }
4771      ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4772  }
4773  
ParseOuterBorderStyle(const JSRef<JSVal> & args)4774  void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
4775  {
4776      if (!args->IsObject() && !args->IsNumber()) {
4777          ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4778          return;
4779      }
4780      if (args->IsObject()) {
4781          std::optional<BorderStyle> styleLeft;
4782          std::optional<BorderStyle> styleRight;
4783          std::optional<BorderStyle> styleTop;
4784          std::optional<BorderStyle> styleBottom;
4785          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4786          auto leftValue = object->GetProperty("left");
4787          if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
4788              styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4789          }
4790          auto rightValue = object->GetProperty("right");
4791          if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
4792              styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4793          }
4794          auto topValue = object->GetProperty("top");
4795          if (!topValue->IsUndefined() && topValue->IsNumber()) {
4796              styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4797          }
4798          auto bottomValue = object->GetProperty("bottom");
4799          if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
4800              styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4801          }
4802          ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4803          return;
4804      }
4805      auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4806      ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
4807  }
4808  
JsBlur(const JSCallbackInfo & info)4809  void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
4810  {
4811      if (info.Length() == 0) {
4812          return;
4813      }
4814      double blur = 0.0;
4815      if (!ParseJsDouble(info[0], blur)) {
4816          return;
4817      }
4818  
4819      BlurOption blurOption;
4820      if (info.Length() > 1 && info[1]->IsObject()) {
4821          JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4822          ParseBlurOption(jsBlurOption, blurOption);
4823      }
4824      CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4825      ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption);
4826      info.SetReturnValue(info.This());
4827  }
4828  
JsMotionBlur(const JSCallbackInfo & info)4829  void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
4830  {
4831      if (!info[0]->IsObject()) {
4832          return;
4833      }
4834      MotionBlurOption option;
4835      double x = 0.0;
4836      double y = 0.0;
4837      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4838      JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
4839      if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
4840          JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
4841          ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
4842          ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
4843      }
4844      double radius = 0.0;
4845      if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
4846          radius = 0.0;
4847      }
4848      if (LessNotEqual(x, 0.0)) {
4849          x = 0.0;
4850      }
4851      if (LessNotEqual(y, 0.0)) {
4852          y = 0.0;
4853      }
4854      option.radius = radius;
4855      option.anchor.x = std::clamp(x, 0.0, 1.0);
4856      option.anchor.y = std::clamp(y, 0.0, 1.0);
4857      ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4858  }
4859  
JsColorBlend(const JSCallbackInfo & info)4860  void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4861  {
4862      Color colorBlend;
4863      if (info[0]->IsUndefined()) {
4864          colorBlend = Color::TRANSPARENT;
4865          SetColorBlend(colorBlend);
4866          return;
4867      }
4868      if (!ParseJsColor(info[0], colorBlend)) {
4869          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4870              colorBlend = Color::TRANSPARENT;
4871              SetColorBlend(colorBlend);
4872          }
4873          return;
4874      }
4875      SetColorBlend(colorBlend);
4876      info.SetReturnValue(info.This());
4877  }
4878  
JsUseEffect(const JSCallbackInfo & info)4879  void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4880  {
4881      if (info[0]->IsBoolean()) {
4882          auto effectType = EffectType::DEFAULT;
4883          if (info.Length() == 2 && info[1]->IsNumber()) {
4884              effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
4885              if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
4886                  effectType = EffectType::DEFAULT;
4887              }
4888          }
4889          ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
4890      }
4891  }
4892  
JsUseShadowBatching(const JSCallbackInfo & info)4893  void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4894  {
4895      if (info[0]->IsBoolean()) {
4896          ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4897      } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4898          ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4899      }
4900  }
4901  
JsBackdropBlur(const JSCallbackInfo & info)4902  void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4903  {
4904      if (info.Length() == 0) {
4905          return;
4906      }
4907      double blur = 0.0;
4908      BlurOption blurOption;
4909      if (!ParseJsDouble(info[0], blur)) {
4910          if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4911              return;
4912          }
4913      }
4914      CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4915      if (info.Length() > 1 && info[1]->IsObject()) {
4916          JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4917          ParseBlurOption(jsBlurOption, blurOption);
4918      }
4919      ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption);
4920      info.SetReturnValue(info.This());
4921  }
4922  
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4923  void JSViewAbstract::GetFractionStops(
4924      std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4925  {
4926      if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4927          return;
4928      }
4929      JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4930      float tmpPos = -1.0f;
4931      size_t length = jsArray->Length();
4932      for (size_t i = 0; i < length; i++) {
4933          std::pair<float, float> fractionStop;
4934          JSRef<JSVal> item = jsArray->GetValueAt(i);
4935          if (!item->IsArray()) {
4936              continue;
4937          }
4938          JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4939          if (subArray->Length() < 2) {
4940              continue;
4941          }
4942  
4943          double value = 0.0;
4944          if (ParseJsDouble(subArray->GetValueAt(0), value)) {
4945              value = std::clamp(value, 0.0, 1.0);
4946              fractionStop.first = static_cast<float>(value);
4947          }
4948          value = 0.0;
4949          if (ParseJsDouble(subArray->GetValueAt(1), value)) {
4950              value = std::clamp(value, 0.0, 1.0);
4951              fractionStop.second = static_cast<float>(value);
4952          }
4953  
4954          if (fractionStop.second <= tmpPos) {
4955              fractionStops.clear();
4956              return;
4957          }
4958          tmpPos = fractionStop.second;
4959          fractionStops.push_back(fractionStop);
4960      }
4961  }
JsLinearGradientBlur(const JSCallbackInfo & info)4962  void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
4963  {
4964      if (info.Length() < 2) { // 2 represents the least para num;
4965          return;
4966      }
4967      double blurRadius = 0.0;
4968      ParseJsDouble(info[0], blurRadius);
4969  
4970      std::vector<std::pair<float, float>> fractionStops;
4971      auto direction = GradientDirection::BOTTOM;
4972      if (info[1]->IsObject()) {
4973          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
4974          GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
4975          auto directionValue =
4976              jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
4977          if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
4978              directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
4979              directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
4980          }
4981          direction = static_cast<GradientDirection>(directionValue);
4982      }
4983      if (static_cast<int32_t>(fractionStops.size()) <= 1) {
4984          fractionStops.clear();
4985          fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
4986          fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
4987      }
4988      // Parse direction
4989      CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
4990      NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
4991      SetLinearGradientBlur(blurPara);
4992  }
4993  
JsBackgroundBrightness(const JSCallbackInfo & info)4994  void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
4995  {
4996      double rate = 0.0;
4997      double lightUpDegree = 0.0;
4998      if (info[0]->IsObject()) {
4999          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5000          ParseJsDouble(jsObj->GetProperty("rate"), rate);
5001          ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
5002      }
5003      SetDynamicLightUp(rate, lightUpDegree);
5004  }
5005  
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)5006  void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
5007  {
5008      if (info.Length() == 0) {
5009          return;
5010      }
5011      BrightnessOption option;
5012      if (info[0]->IsObject()) {
5013          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5014          ParseBrightnessOption(jsOption, option);
5015      }
5016      SetBgDynamicBrightness(option);
5017  }
5018  
JsForegroundBrightness(const JSCallbackInfo & info)5019  void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
5020  {
5021      if (info.Length() == 0) {
5022          return;
5023      }
5024      BrightnessOption option;
5025      if (info[0]->IsObject()) {
5026          JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5027          ParseBrightnessOption(jsOption, option);
5028      }
5029      SetFgDynamicBrightness(option);
5030  }
5031  
JsWindowBlur(const JSCallbackInfo & info)5032  void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
5033  {
5034      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5035      auto jsVal = info[0];
5036      if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
5037          return;
5038      }
5039  
5040      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
5041      double progress = 0.0;
5042      ParseJsDouble(jsObj->GetProperty("percent"), progress);
5043      auto style = jsObj->GetPropertyValue<int32_t>("style",
5044          static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
5045  
5046      progress = std::clamp(progress, 0.0, 1.0);
5047      style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
5048          static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
5049  
5050      SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
5051      info.SetReturnValue(info.This());
5052  }
5053  
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)5054  bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
5055      std::string& resName, bool isParseType)
5056  {
5057      if (!jsValue->IsString()) {
5058          return false;
5059      }
5060      std::string resPath = jsValue->ToString();
5061      std::smatch results;
5062      std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
5063      if (!std::regex_match(resPath, results, tokenRegex)) {
5064          return false;
5065      }
5066      targetModule = results[1];
5067      if (isParseType && !ConvertResourceType(results[2], resType)) {
5068          return false;
5069      }
5070      resName = resPath;
5071      return true;
5072  }
5073  
ConvertResourceType(const std::string & typeName,ResourceType & resType)5074  bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
5075  {
5076      static const std::unordered_map<std::string, ResourceType> resTypeMap {
5077          { "color", ResourceType::COLOR },
5078          { "media", ResourceType::MEDIA },
5079          { "float", ResourceType::FLOAT },
5080          { "string", ResourceType::STRING },
5081          { "plural", ResourceType::PLURAL },
5082          { "pattern", ResourceType::PATTERN },
5083          { "boolean", ResourceType::BOOLEAN },
5084          { "integer", ResourceType::INTEGER },
5085          { "strarray", ResourceType::STRARRAY },
5086          { "intarray", ResourceType::INTARRAY },
5087      };
5088      auto it = resTypeMap.find(typeName);
5089      if (it == resTypeMap.end()) {
5090          return false;
5091      }
5092      resType = it->second;
5093      return true;
5094  }
5095  
CompleteResourceObject(JSRef<JSObject> & jsObj)5096  void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
5097  {
5098      std::string bundleName;
5099      std::string moduleName;
5100      int32_t resId = -1;
5101      CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5102  }
5103  
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)5104  void JSViewAbstract::CompleteResourceObjectWithBundleName(
5105      JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
5106  {
5107      CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5108  }
5109  
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)5110  void JSViewAbstract::CompleteResourceObjectInner(
5111      JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
5112  {
5113      // dynamic $r raw input format is
5114      // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
5115      JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5116      ResourceType resType;
5117  
5118      std::string targetModule;
5119      std::string resName;
5120      if (resId->IsString()) {
5121          JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
5122          int32_t typeNum = -1;
5123          if (type->IsNumber()) {
5124              typeNum = type->ToNumber<int32_t>();
5125          }
5126          if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
5127              return;
5128          }
5129          CompleteResourceObjectFromId(type, jsObj, resType, resName);
5130      } else if (resId->IsNumber()) {
5131          resIdValue = resId->ToNumber<int32_t>();
5132          if (resIdValue == -1) {
5133              CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
5134          }
5135      }
5136  
5137      JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
5138      if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
5139          bundleName = GetBundleNameFromContainer();
5140          jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
5141      }
5142      if (moduleName == DEFAULT_HAR_MODULE_NAME) {
5143          moduleName = GetModuleNameFromContainer();
5144          jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
5145      }
5146  }
5147  
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)5148  bool JSViewAbstract::ParseJsDimensionNG(
5149      const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
5150  {
5151      if (jsValue->IsNumber()) {
5152          result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5153          return true;
5154      }
5155      if (jsValue->IsString()) {
5156          auto value = jsValue->ToString();
5157          if (!isSupportPercent && value.back() == '%') {
5158              return false;
5159          }
5160          return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5161      }
5162      if (jsValue->IsObject()) {
5163          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5164          CompleteResourceObject(jsObj);
5165          JSRef<JSVal> resId = jsObj->GetProperty("id");
5166          if (!resId->IsNumber()) {
5167              return false;
5168          }
5169          auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5170          if (resType == UNKNOWN_RESOURCE_TYPE) {
5171              return false;
5172          }
5173  
5174          auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5175          auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5176          if (!resourceWrapper) {
5177              return false;
5178          }
5179  
5180          auto resIdNum = resId->ToNumber<int32_t>();
5181          if (resIdNum == -1) {
5182              if (!IsGetResourceByName(jsObj)) {
5183                  return false;
5184              }
5185              JSRef<JSVal> args = jsObj->GetProperty("params");
5186              if (!args->IsArray()) {
5187                  return false;
5188              }
5189              JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5190              auto param = params->GetValueAt(0);
5191              if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5192                  auto value = resourceWrapper->GetStringByName(param->ToString());
5193                  return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5194              }
5195              if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5196                  auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5197                  StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5198                  return true;
5199              }
5200              result = resourceWrapper->GetDimensionByName(param->ToString());
5201              return true;
5202          }
5203  
5204          if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5205              auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5206              return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5207          }
5208          if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5209              auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5210              StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5211              return true;
5212          }
5213  
5214          if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5215              result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
5216              return true;
5217          }
5218      }
5219  
5220      return false;
5221  }
5222  
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)5223  bool JSViewAbstract::ParseJsLengthNG(
5224      const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
5225  {
5226      if (jsValue->IsNumber()) {
5227          if (std::isnan(jsValue->ToNumber<double>())) {
5228              return false;
5229          }
5230          result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
5231          return true;
5232      } else if (jsValue->IsObject()) {
5233          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5234          JSRef<JSVal> value = jsObj->GetProperty("value");
5235          if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
5236              return false;
5237          }
5238          DimensionUnit unit = defaultUnit;
5239          JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
5240          if (jsUnit->IsNumber()) {
5241              if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
5242                  return false;
5243              }
5244              unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
5245          }
5246          result = NG::CalcLength(value->ToNumber<double>(), unit);
5247          return true;
5248      }
5249  
5250      return false;
5251  }
5252  
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)5253  bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
5254  {
5255      // 'vp' -> the value varies with pixel density of device.
5256      return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5257  }
5258  
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)5259  bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
5260  {
5261      if (jsValue->IsNumber()) {
5262          result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5263          return true;
5264      }
5265      if (jsValue->IsString()) {
5266          result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
5267          return true;
5268      }
5269      if (!jsValue->IsObject()) {
5270          return false;
5271      }
5272      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5273      CompleteResourceObject(jsObj);
5274      JSRef<JSVal> resId = jsObj->GetProperty("id");
5275      if (!resId->IsNumber()) {
5276          return false;
5277      }
5278  
5279      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5280      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5281      if (!resourceWrapper) {
5282          return false;
5283      }
5284  
5285      auto resIdNum = resId->ToNumber<int32_t>();
5286      int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5287      if (resType == UNKNOWN_RESOURCE_TYPE) {
5288          return false;
5289      }
5290  
5291      if (resIdNum == -1) {
5292          if (!IsGetResourceByName(jsObj)) {
5293              return false;
5294          }
5295          JSRef<JSVal> args = jsObj->GetProperty("params");
5296          if (!args->IsArray()) {
5297              return false;
5298          }
5299          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5300          auto param = params->GetValueAt(0);
5301          if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5302              auto value = resourceWrapper->GetStringByName(param->ToString());
5303              result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5304              return true;
5305          }
5306          if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5307              auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5308              result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5309              return true;
5310          }
5311          result = resourceWrapper->GetDimensionByName(param->ToString());
5312          return true;
5313      }
5314  
5315      if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5316          auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5317          result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5318          return true;
5319      }
5320      if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5321          auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5322          result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5323          return true;
5324      }
5325      result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
5326      return true;
5327  }
5328  
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5329  bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5330  {
5331      // 'vp' -> the value varies with pixel density of device.
5332      return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5333  }
5334  
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)5335  bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5336  {
5337      // 'vp' -> the value varies with pixel density of device.
5338      return ParseJsDimension(jsValue, result, DimensionUnit::VP);
5339  }
5340  
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)5341  bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5342  {
5343      // the 'fp' unit is used for text scenes.
5344      return ParseJsDimension(jsValue, result, DimensionUnit::FP);
5345  }
5346  
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5347  bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5348  {
5349      // the 'fp' unit is used for text scenes.
5350      return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
5351  }
5352  
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)5353  bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
5354  {
5355      return ParseJsDimension(jsValue, result, DimensionUnit::PX);
5356  }
5357  
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)5358  bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
5359  {
5360      if (!jsValue->IsObject()) {
5361          return false;
5362      }
5363      auto colorObj = JSRef<JSObject>::Cast(jsValue);
5364      auto toNumericProp = colorObj->GetProperty("toNumeric");
5365      if (toNumericProp->IsFunction()) {
5366          auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
5367          result.SetValue(colorVal->ToNumber<uint32_t>());
5368          return true;
5369      }
5370      return false;
5371  }
5372  
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5373  bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5374  {
5375      if (jsValue->IsNumber()) {
5376          result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
5377          return true;
5378      }
5379      if (jsValue->IsString()) {
5380          auto value = jsValue->ToString();
5381          return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
5382      }
5383      if (jsValue->IsObject()) {
5384          auto jsObj = JSRef<JSObject>::Cast(jsValue);
5385          auto valObj = jsObj->GetProperty("value");
5386          if (valObj->IsUndefined() || valObj->IsNull()) {
5387              return false;
5388          }
5389          double value = valObj->ToNumber<double>();
5390          auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
5391          result = CalcDimension(value, unit);
5392          return true;
5393      }
5394      return false;
5395  }
5396  
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5397  bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5398  {
5399      return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
5400  }
5401  
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)5402  bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
5403  {
5404      if (!jsValue->IsObject()) {
5405          return false;
5406      }
5407      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5408      CompleteResourceObject(jsObj);
5409      if (jsObj->IsEmpty()) {
5410          return false;
5411      }
5412      JSRef<JSVal> id = jsObj->GetProperty("id");
5413      if (!id->IsNumber()) {
5414          return false;
5415      }
5416  
5417      auto resId = id->ToNumber<int32_t>();
5418      int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5419      if (resType == UNKNOWN_RESOURCE_TYPE) {
5420          return false;
5421      }
5422  
5423      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5424      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5425      if (!resourceWrapper) {
5426          return false;
5427      }
5428  
5429      if (resId == -1) {
5430          if (!IsGetResourceByName(jsObj)) {
5431              return false;
5432          }
5433          JSRef<JSVal> args = jsObj->GetProperty("params");
5434          if (!args->IsArray()) {
5435              return false;
5436          }
5437          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5438          auto param = params->GetValueAt(0);
5439          if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5440              auto numberString = resourceWrapper->GetStringByName(param->ToString());
5441              return StringUtils::StringToDouble(numberString, result);
5442          }
5443          if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5444              result = resourceWrapper->GetIntByName(param->ToString());
5445              return true;
5446          }
5447          if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5448              result = resourceWrapper->GetDoubleByName(param->ToString());
5449              return true;
5450          }
5451          return false;
5452      }
5453      if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5454          auto numberString = resourceWrapper->GetString(resId);
5455          return StringUtils::StringToDouble(numberString, result);
5456      }
5457      if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5458          result = resourceWrapper->GetInt(resId);
5459          return true;
5460      }
5461      if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5462          result = resourceWrapper->GetDouble(resId);
5463          return true;
5464      }
5465      return false;
5466  }
5467  
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)5468  bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
5469  {
5470      if (jsValue->IsNumber()) {
5471          result = jsValue->ToNumber<double>();
5472          return true;
5473      }
5474      if (jsValue->IsString()) {
5475          return StringUtils::StringToDouble(jsValue->ToString(), result);
5476      }
5477      if (jsValue->IsObject()) {
5478          return ParseResourceToDouble(jsValue, result);
5479      }
5480      return false;
5481  }
5482  
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)5483  bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
5484  {
5485      if (jsValue->IsNumber()) {
5486          result = jsValue->ToNumber<int32_t>();
5487          return true;
5488      }
5489      if (jsValue->IsString()) {
5490          result = StringUtils::StringToInt(jsValue->ToString());
5491          return true;
5492      }
5493      if (!jsValue->IsObject()) {
5494          return false;
5495      }
5496      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5497      CompleteResourceObject(jsObj);
5498      JSRef<JSVal> resId = jsObj->GetProperty("id");
5499      if (!resId->IsNumber()) {
5500          return false;
5501      }
5502  
5503      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5504      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5505      if (!resourceWrapper) {
5506          return false;
5507      }
5508  
5509      auto resIdNum = resId->ToNumber<int32_t>();
5510      if (resIdNum == -1) {
5511          if (!IsGetResourceByName(jsObj)) {
5512              return false;
5513          }
5514          JSRef<JSVal> args = jsObj->GetProperty("params");
5515          if (!args->IsArray()) {
5516              return false;
5517          }
5518          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5519          auto param = params->GetValueAt(0);
5520          result = resourceWrapper->GetIntByName(param->ToString());
5521          return true;
5522      }
5523      result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5524      return true;
5525  }
5526  
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)5527  bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
5528  {
5529      if (!jsValue->IsObject()) {
5530          return false;
5531      }
5532      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5533      CompleteResourceObject(jsObj);
5534  
5535      auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
5536      if (ok) {
5537          JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
5538          if (jsOpacityRatio->IsNumber()) {
5539              double opacityRatio = jsOpacityRatio->ToNumber<double>();
5540              result = result.BlendOpacity(opacityRatio);
5541          }
5542      }
5543      return ok;
5544  }
5545  
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)5546  bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
5547  {
5548      JSRef<JSVal> resId = jsObj->GetProperty("id");
5549      if (!resId->IsNumber()) {
5550          return false;
5551      }
5552  
5553      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5554      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5555      if (!resourceWrapper) {
5556          return false;
5557      }
5558  
5559      auto resIdNum = resId->ToNumber<int32_t>();
5560      if (resIdNum == -1) {
5561          if (!IsGetResourceByName(jsObj)) {
5562              return false;
5563          }
5564          JSRef<JSVal> args = jsObj->GetProperty("params");
5565          if (!args->IsArray()) {
5566              return false;
5567          }
5568          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5569          auto param = params->GetValueAt(0);
5570          result = resourceWrapper->GetColorByName(param->ToString());
5571          return true;
5572      }
5573  
5574      auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5575      if (type == static_cast<int32_t>(ResourceType::STRING)) {
5576          auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5577          return Color::ParseColorString(value, result);
5578      }
5579      if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5580          auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5581          result = Color(ColorAlphaAdapt(value));
5582          return true;
5583      }
5584      if (type == static_cast<int32_t>(ResourceType::COLOR)) {
5585          result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
5586          result.SetResourceId(resId->ToNumber<uint32_t>());
5587          return true;
5588      }
5589      return false;
5590  }
5591  
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)5592  bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
5593  {
5594      if (jsValue->IsNumber()) {
5595          result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5596          return true;
5597      }
5598      if (jsValue->IsString()) {
5599          return Color::ParseColorString(jsValue->ToString(), result);
5600      }
5601      if (jsValue->IsObject()) {
5602          return ParseJsColorFromResource(jsValue, result);
5603      }
5604      return false;
5605  }
5606  
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)5607  bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
5608  {
5609      if (jsValue->IsNumber()) {
5610          result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5611          return true;
5612      }
5613      if (jsValue->IsString()) {
5614          return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
5615      }
5616      if (!jsValue->IsObject()) {
5617          return false;
5618      }
5619      return ParseJsColorFromResource(jsValue, result);
5620  }
5621  
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)5622  bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
5623  {
5624      if (jsValue->IsString()) {
5625          std::string colorStr = jsValue->ToString();
5626          if (colorStr.compare("invert") == 0) {
5627              strategy = ForegroundColorStrategy::INVERT;
5628              return true;
5629          }
5630      }
5631      return false;
5632  }
5633  
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)5634  bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
5635  {
5636      if (jsValue->IsString()) {
5637          std::string colorStr = jsValue->ToString();
5638          if (colorStr.compare("average") == 0) {
5639              strategy = ShadowColorStrategy::AVERAGE;
5640              return true;
5641          } else if (colorStr.compare("primary") == 0) {
5642              strategy = ShadowColorStrategy::PRIMARY;
5643              return true;
5644          }
5645      }
5646      return false;
5647  }
5648  
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)5649  bool JSViewAbstract::ParseJsSymbolId(
5650      const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
5651  {
5652      if (jsValue->IsNull() || jsValue->IsUndefined()) {
5653          symbolId = 0;
5654          return false;
5655      }
5656      if (!jsValue->IsObject()) {
5657          return false;
5658      }
5659      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5660      CompleteResourceObject(jsObj);
5661      JSRef<JSVal> resId = jsObj->GetProperty("id");
5662      if (resId->IsNull() || !resId->IsNumber()) {
5663          return false;
5664      }
5665      auto resourceObject = GetResourceObject(jsObj);
5666      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5667      symbolResourceObject = resourceObject;
5668      if (!resourceWrapper) {
5669          return false;
5670      }
5671      if (!resourceObject) {
5672          return false;
5673      }
5674  
5675      auto resIdNum = resId->ToNumber<int32_t>();
5676      if (resIdNum == -1) {
5677          if (!IsGetResourceByName(jsObj)) {
5678              return false;
5679          }
5680          JSRef<JSVal> args = jsObj->GetProperty("params");
5681          if (!args->IsArray()) {
5682              return false;
5683          }
5684          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5685          auto param = params->GetValueAt(0);
5686          auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
5687          if (!symbol) {
5688              return false;
5689          }
5690          symbolId = symbol;
5691          return true;
5692      }
5693  
5694      auto symbol = resourceWrapper->GetSymbolById(resIdNum);
5695      if (!symbol) {
5696          return false;
5697      }
5698      symbolId = symbol;
5699      return true;
5700  }
5701  
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)5702  bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
5703  {
5704      if (!jsValue->IsArray()) {
5705          return false;
5706      }
5707      if (jsValue->IsArray()) {
5708          JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5709          for (size_t i = 0; i < array->Length(); i++) {
5710              JSRef<JSVal> value = array->GetValueAt(i);
5711              if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
5712                  return false;
5713              }
5714              if (value->IsNumber()) {
5715                  result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
5716                  continue;
5717              } else if (value->IsString()) {
5718                  Color color;
5719                  Color::ParseColorString(value->ToString(), color);
5720                  result.emplace_back(color);
5721                  continue;
5722              } else {
5723                  Color color;
5724                  ParseJsColorFromResource(value, color);
5725                  result.emplace_back(color);
5726              }
5727          }
5728          return true;
5729      }
5730      return false;
5731  }
5732  
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5733  bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5734  {
5735      result.clear();
5736      if (!jsValue->IsString() && !jsValue->IsObject()) {
5737          return false;
5738      }
5739      if (jsValue->IsString()) {
5740          result = ConvertStrToFontFamilies(jsValue->ToString());
5741          return true;
5742      }
5743      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5744      CompleteResourceObject(jsObj);
5745      JSRef<JSVal> resId = jsObj->GetProperty("id");
5746      if (!resId->IsNumber()) {
5747          return false;
5748      }
5749  
5750      auto resourceObject = GetResourceObject(jsObj);
5751      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5752      if (!resourceWrapper) {
5753          return false;
5754      }
5755  
5756      auto resIdNum = resId->ToNumber<int32_t>();
5757      if (resIdNum == -1) {
5758          if (!IsGetResourceByName(jsObj)) {
5759              return false;
5760          }
5761          JSRef<JSVal> args = jsObj->GetProperty("params");
5762          if (!args->IsArray()) {
5763              return false;
5764          }
5765          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5766          auto param = params->GetValueAt(0);
5767          result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
5768          return true;
5769      }
5770      result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
5771      return true;
5772  }
5773  
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5774  bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5775  {
5776      if (jsValue->IsString()) {
5777          result = jsValue->ToString();
5778          return true;
5779      }
5780  
5781      if (!jsValue->IsObject()) {
5782          return false;
5783      }
5784  
5785      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5786      CompleteResourceObject(jsObj);
5787  
5788      JSRef<JSVal> resId = jsObj->GetProperty("id");
5789      if (!resId->IsNumber()) {
5790          return false;
5791      }
5792      auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5793      if (type == UNKNOWN_RESOURCE_TYPE) {
5794          return false;
5795      }
5796  
5797      JSRef<JSVal> args = jsObj->GetProperty("params");
5798      if (!args->IsArray()) {
5799          return false;
5800      }
5801  
5802      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5803      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5804      if (!resourceWrapper) {
5805          return false;
5806      }
5807  
5808      JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5809      auto resIdNum = resId->ToNumber<int32_t>();
5810      if (resIdNum == -1) {
5811          if (!IsGetResourceByName(jsObj)) {
5812              return false;
5813          }
5814          auto param = params->GetValueAt(0);
5815          if (type == static_cast<int32_t>(ResourceType::STRING)) {
5816              auto originStr = resourceWrapper->GetStringByName(param->ToString());
5817              ReplaceHolder(originStr, params, 1);
5818              result = originStr;
5819          } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5820              auto countJsVal = params->GetValueAt(1);
5821              int count = 0;
5822              if (!countJsVal->IsNumber()) {
5823                  return false;
5824              }
5825              count = countJsVal->ToNumber<int>();
5826              auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5827              ReplaceHolder(pluralStr, params, 2);
5828              result = pluralStr;
5829          } else {
5830              return false;
5831          }
5832          return true;
5833      }
5834      if (type == static_cast<int32_t>(ResourceType::STRING)) {
5835          auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5836          ReplaceHolder(originStr, params, 0);
5837          result = originStr;
5838      } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5839          auto countJsVal = params->GetValueAt(0);
5840          int count = 0;
5841          if (!countJsVal->IsNumber()) {
5842              return false;
5843          }
5844          count = countJsVal->ToNumber<int>();
5845          auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5846          ReplaceHolder(pluralStr, params, 1);
5847          result = pluralStr;
5848      } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5849          result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5850      } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5851          result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5852      } else {
5853          return false;
5854      }
5855      return true;
5856  }
5857  
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5858  bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5859  {
5860      if (!jsValue->IsObject() && !jsValue->IsString()) {
5861          return false;
5862      }
5863      if (jsValue->IsString()) {
5864          result = jsValue->ToString();
5865          return true;
5866      }
5867      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5868      CompleteResourceObject(jsObj);
5869      return ParseJSMediaInternal(jsObj, result);
5870  }
5871  
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5872  bool JSViewAbstract::ParseJsMediaWithBundleName(
5873      const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5874  {
5875      if (!jsValue->IsObject() && !jsValue->IsString()) {
5876          return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5877      }
5878      if (jsValue->IsString()) {
5879          result = jsValue->ToString();
5880          return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5881      }
5882      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5883      CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5884      return ParseJSMediaInternal(jsObj, result);
5885  }
5886  
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5887  bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5888  {
5889      int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5890      JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5891      if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5892          auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5893          auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5894          CHECK_NULL_RETURN(resourceWrapper, false);
5895          if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5896              JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5897              if (!args->IsArray()) {
5898                  return false;
5899              }
5900              JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5901              auto fileName = params->GetValueAt(0);
5902              if (!fileName->IsString()) {
5903                  return false;
5904              }
5905              result = resourceWrapper->GetRawfile(fileName->ToString());
5906              return true;
5907          }
5908          auto resIdNum = resId->ToNumber<int32_t>();
5909          if (resIdNum == -1) {
5910              if (!IsGetResourceByName(jsObj)) {
5911                  return false;
5912              }
5913              JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5914              if (!args->IsArray()) {
5915                  return false;
5916              }
5917              JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5918              auto param = params->GetValueAt(0);
5919              if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5920                  result = resourceWrapper->GetMediaPathByName(param->ToString());
5921                  return true;
5922              }
5923              if (type == static_cast<int32_t>(ResourceType::STRING)) {
5924                  result = resourceWrapper->GetStringByName(param->ToString());
5925                  return true;
5926              }
5927              return false;
5928          } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5929              result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5930              return true;
5931          } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5932              result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5933              return true;
5934          }
5935      }
5936      return false;
5937  }
5938  
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5939  void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
5940      const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
5941  {
5942      auto vm = info.GetVm();
5943      auto globalObj = JSNApi::GetGlobalObject(vm);
5944      auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
5945      JsiValue jsiValue(globalFunc);
5946      JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
5947      if (!globalFuncRef->IsFunction()) {
5948          return;
5949      }
5950      if (modifierNormalObj->IsUndefined()) {
5951          symbolApply.onApply = nullptr;
5952      } else {
5953          RefPtr<JsFunction> jsFunc =
5954              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
5955          auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
5956                              modifierNormal = std::move(modifierNormalObj),
5957                              modifierSelected = std::move(modifierSelectedObj)](
5958                              WeakPtr<NG::FrameNode> frameNode, std::string type) {
5959              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5960              auto node = frameNode.Upgrade();
5961              CHECK_NULL_VOID(node);
5962              JSRef<JSVal> params[SECOND_INDEX];
5963              if (type == "normal") {
5964                  params[0] = modifierNormal;
5965              } else if (!modifierSelected->IsUndefined()) {
5966                  params[0] = modifierSelected;
5967              }
5968              params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
5969              PipelineContext::SetCallBackNode(node);
5970              func->ExecuteJS(SECOND_INDEX, params);
5971          };
5972          symbolApply.onApply = onApply;
5973      }
5974  }
5975  
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)5976  bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
5977  {
5978      if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
5979          return false;
5980      }
5981  
5982      if (jsValue->IsBoolean()) {
5983          result = jsValue->ToBoolean();
5984          return true;
5985      }
5986  
5987      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5988      CompleteResourceObject(jsObj);
5989      int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5990      if (resType == UNKNOWN_RESOURCE_TYPE) {
5991          return false;
5992      }
5993  
5994      JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5995      if (!resId->IsNumber()) {
5996          return false;
5997      }
5998  
5999      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6000      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6001      if (!resourceWrapper) {
6002          return false;
6003      }
6004  
6005      auto resIdNum = resId->ToNumber<int32_t>();
6006      if (resIdNum == -1) {
6007          if (!IsGetResourceByName(jsObj)) {
6008              return false;
6009          }
6010          JSRef<JSVal> args = jsObj->GetProperty("params");
6011          if (!args->IsArray()) {
6012              return false;
6013          }
6014          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6015          auto param = params->GetValueAt(0);
6016          if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6017              result = resourceWrapper->GetBooleanByName(param->ToString());
6018              return true;
6019          }
6020          return false;
6021      }
6022  
6023      if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6024          result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
6025          return true;
6026      }
6027      return false;
6028  }
6029  
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)6030  bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
6031  {
6032      return ParseJsInteger<uint32_t>(jsValue, result);
6033  }
6034  
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)6035  bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
6036  {
6037      return ParseJsInteger<int32_t>(jsValue, result);
6038  }
6039  
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)6040  bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
6041  {
6042      if (!jsValue->IsArray() && !jsValue->IsObject()) {
6043          return false;
6044      }
6045  
6046      if (jsValue->IsArray()) {
6047          JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6048          for (size_t i = 0; i < array->Length(); i++) {
6049              JSRef<JSVal> value = array->GetValueAt(i);
6050              if (value->IsNumber()) {
6051                  result.emplace_back(value->ToNumber<uint32_t>());
6052              } else if (value->IsObject()) {
6053                  uint32_t singleResInt;
6054                  if (ParseJsInteger(value, singleResInt)) {
6055                      result.emplace_back(singleResInt);
6056                  } else {
6057                      return false;
6058                  }
6059              } else {
6060                  return false;
6061              }
6062          }
6063          return true;
6064      }
6065  
6066      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6067      CompleteResourceObject(jsObj);
6068      int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6069      if (resType == UNKNOWN_RESOURCE_TYPE) {
6070          return false;
6071      }
6072  
6073      JSRef<JSVal> resId = jsObj->GetProperty("id");
6074      if (!resId->IsNumber()) {
6075          return false;
6076      }
6077  
6078      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6079      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6080      if (!resourceWrapper) {
6081          return false;
6082      }
6083  
6084      auto resIdNum = resId->ToNumber<int32_t>();
6085      if (resIdNum == -1) {
6086          if (!IsGetResourceByName(jsObj)) {
6087              return false;
6088          }
6089          JSRef<JSVal> args = jsObj->GetProperty("params");
6090          if (!args->IsArray()) {
6091              return false;
6092          }
6093          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6094          auto param = params->GetValueAt(0);
6095          if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6096              result = resourceWrapper->GetIntArrayByName(param->ToString());
6097              return true;
6098          }
6099          return false;
6100      }
6101  
6102      if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6103          result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
6104          return true;
6105      }
6106      return false;
6107  }
6108  
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)6109  bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
6110  {
6111      if (!jsValue->IsArray() && !jsValue->IsObject()) {
6112          return false;
6113      }
6114  
6115      if (jsValue->IsArray()) {
6116          JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6117          for (size_t i = 0; i < array->Length(); i++) {
6118              JSRef<JSVal> value = array->GetValueAt(i);
6119              if (value->IsString()) {
6120                  result.emplace_back(value->ToString());
6121              } else if (value->IsObject()) {
6122                  std::string singleResStr;
6123                  if (ParseJsString(value, singleResStr)) {
6124                      result.emplace_back(singleResStr);
6125                  } else {
6126                      return false;
6127                  }
6128              } else {
6129                  return false;
6130              }
6131          }
6132          return true;
6133      }
6134  
6135      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6136      CompleteResourceObject(jsObj);
6137      int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6138      if (resType == UNKNOWN_RESOURCE_TYPE) {
6139          return false;
6140      }
6141  
6142      JSRef<JSVal> resId = jsObj->GetProperty("id");
6143      if (!resId->IsNumber()) {
6144          return false;
6145      }
6146  
6147      auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6148      auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6149      if (!resourceWrapper) {
6150          return false;
6151      }
6152  
6153      auto resIdNum = resId->ToNumber<int32_t>();
6154      if (resIdNum == -1) {
6155          if (!IsGetResourceByName(jsObj)) {
6156              return false;
6157          }
6158          JSRef<JSVal> args = jsObj->GetProperty("params");
6159          if (!args->IsArray()) {
6160              return false;
6161          }
6162          JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6163          auto param = params->GetValueAt(0);
6164          if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6165              result = resourceWrapper->GetStringArrayByName(param->ToString());
6166              return true;
6167          }
6168          return false;
6169      }
6170  
6171      if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6172          result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
6173          return true;
6174      }
6175      return false;
6176  }
6177  
IsGetResourceByName(const JSRef<JSObject> & jsObj)6178  bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
6179  {
6180      JSRef<JSVal> resId = jsObj->GetProperty("id");
6181      if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
6182          return false;
6183      }
6184      JSRef<JSVal> args = jsObj->GetProperty("params");
6185      if (!args->IsArray()) {
6186          return false;
6187      }
6188      JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
6189      JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
6190      if (!bundleName->IsString() || !moduleName->IsString()) {
6191          return false;
6192      }
6193      JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6194      if (params->IsEmpty()) {
6195          return false;
6196      }
6197      return true;
6198  }
6199  
ParseSize(const JSCallbackInfo & info)6200  std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
6201  {
6202      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6203      auto jsVal = info[0];
6204      if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
6205          return std::pair<CalcDimension, CalcDimension>();
6206      }
6207      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6208      CalcDimension width;
6209      CalcDimension height;
6210      if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
6211          !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
6212          return std::pair<CalcDimension, CalcDimension>();
6213      }
6214      return std::pair<CalcDimension, CalcDimension>(width, height);
6215  }
6216  
JsUseAlign(const JSCallbackInfo & info)6217  void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
6218  {
6219      if (info.Length() < 2) {
6220          return;
6221      }
6222  
6223      if (!info[0]->IsObject() && !info[1]->IsObject()) {
6224          return;
6225      }
6226  
6227      AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
6228      if (declaration == nullptr) {
6229          return;
6230      }
6231  
6232      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6233      JSRef<JSVal> side = obj->GetProperty("side");
6234      JSRef<JSVal> offset = obj->GetProperty("offset");
6235  
6236      if (!side->IsNumber()) {
6237          return;
6238      }
6239  
6240      auto sideValue = side->ToNumber<int32_t>();
6241  
6242      if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
6243          if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
6244              sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
6245              return;
6246          }
6247      } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
6248          if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
6249              sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
6250              return;
6251          }
6252      }
6253  
6254      std::optional<CalcDimension> optOffset;
6255      CalcDimension offsetDimension;
6256      if (ParseJsDimensionVp(offset, offsetDimension)) {
6257          optOffset = offsetDimension;
6258      }
6259      ViewAbstractModel::GetInstance()->SetUseAlign(
6260          declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
6261  }
6262  
JsGridSpan(const JSCallbackInfo & info)6263  void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
6264  {
6265      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6266      auto jsVal = info[0];
6267      if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
6268          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6269              ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
6270          }
6271          return;
6272      }
6273      auto span = jsVal->ToNumber<int32_t>();
6274      ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
6275  }
6276  
JsGridOffset(const JSCallbackInfo & info)6277  void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
6278  {
6279      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6280      auto jsVal = info[0];
6281      if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
6282          if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6283              ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
6284          }
6285          return;
6286      }
6287      auto offset = jsVal->ToNumber<int32_t>();
6288      ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
6289  }
6290  
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)6291  static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
6292  {
6293      // {lg: 4}
6294      if (val->IsNumber()) {
6295          span = val->ToNumber<uint32_t>();
6296          return true;
6297      }
6298  
6299      if (!val->IsObject()) {
6300          return false;
6301      }
6302  
6303      // {lg: {span: 1, offset: 2}}
6304      JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
6305      span = obj->GetProperty("span")->ToNumber<uint32_t>();
6306      offset = obj->GetProperty("offset")->ToNumber<int32_t>();
6307      return true;
6308  }
6309  
JsUseSizeType(const JSCallbackInfo & info)6310  void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
6311  {
6312      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6313      auto jsVal = info[0];
6314      if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
6315          return;
6316      }
6317      JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
6318      for (auto values : SCREEN_SIZE_VALUES) {
6319          JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
6320          if (val->IsNull() || val->IsEmpty()) {
6321              continue;
6322          }
6323          uint32_t span = 0;
6324          int32_t offset = 0;
6325          if (ParseSpanAndOffset(val, span, offset)) {
6326              ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
6327          }
6328      }
6329  }
6330  
JsZIndex(const JSCallbackInfo & info)6331  void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
6332  {
6333      int zIndex = 0;
6334      if (info[0]->IsNumber()) {
6335          zIndex = info[0]->ToNumber<int>();
6336      }
6337  
6338      ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
6339  }
6340  
Pop()6341  void JSViewAbstract::Pop()
6342  {
6343      ViewStackModel::GetInstance()->Pop();
6344  }
6345  
JsSetDraggable(bool draggable)6346  void JSViewAbstract::JsSetDraggable(bool draggable)
6347  {
6348      ViewAbstractModel::GetInstance()->SetDraggable(draggable);
6349  }
6350  
ParseDragPreviewOptions(const JSCallbackInfo & info)6351  NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
6352  {
6353      NG::DragPreviewOption previewOption;
6354      if (!info[0]->IsObject()) {
6355          return previewOption;
6356      }
6357      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
6358      auto mode = obj->GetProperty("mode");
6359      bool isAuto = true;
6360      if (mode->IsNumber()) {
6361          ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
6362      } else if (mode->IsArray()) {
6363          JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
6364          for (size_t i = 0; i < array->Length(); i++) {
6365              JSRef<JSVal> value = array->GetValueAt(i);
6366              if (value->IsNumber()) {
6367                  ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
6368              }
6369              if (isAuto) {
6370                  break;
6371              }
6372          }
6373      }
6374  
6375      JSViewAbstract::SetDragNumberBadge(info, previewOption);
6376  
6377      if (info.Length() > 1 && info[1]->IsObject()) {
6378          JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6379          auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
6380          if (multiSelection->IsBoolean()) {
6381              previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
6382          }
6383          auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
6384          if (defaultAnimation->IsBoolean()) {
6385              previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
6386          }
6387          auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
6388          if (dragPreview->IsBoolean()) {
6389              previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
6390          }
6391      }
6392  
6393      JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
6394  
6395      return previewOption;
6396  }
6397  
JsSetDragPreviewOptions(const JSCallbackInfo & info)6398  void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
6399  {
6400      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6401      auto jsVal = info[0];
6402      if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
6403          return;
6404      }
6405      NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
6406      ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
6407  }
6408  
JsOnDragStart(const JSCallbackInfo & info)6409  void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
6410  {
6411      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6412      auto jsVal = info[0];
6413      if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
6414          return;
6415      }
6416  
6417      RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6418  
6419      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6420      auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
6421                             const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
6422          NG::DragDropBaseInfo dragDropInfo;
6423          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
6424          PipelineContext::SetCallBackNode(node);
6425          auto ret = func->Execute(info, extraParams);
6426          if (!ret->IsObject()) {
6427              return dragDropInfo;
6428          }
6429  
6430          dragDropInfo.node = ParseDragNode(ret);
6431          auto builderObj = JSRef<JSObject>::Cast(ret);
6432  #if defined(PIXEL_MAP_SUPPORTED)
6433          auto pixmap = builderObj->GetProperty("pixelMap");
6434          dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
6435  #endif
6436          auto extraInfo = builderObj->GetProperty("extraInfo");
6437          ParseJsString(extraInfo, dragDropInfo.extraInfo);
6438          return dragDropInfo;
6439      };
6440      ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
6441  }
6442  
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)6443  bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
6444  {
6445      auto node = ParseDragNode(info);
6446      if (!node) {
6447          return false;
6448      }
6449      dragInfo.node = node;
6450      return true;
6451  }
6452  
ParseDragNode(const JSRef<JSVal> & info)6453  RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
6454  {
6455      auto builderFunc = ParseDragStartBuilderFunc(info);
6456      if (!builderFunc) {
6457          return nullptr;
6458      }
6459      // use another VSP instance while executing the builder function
6460      ViewStackModel::GetInstance()->NewScope();
6461      {
6462          ACE_SCORING_EVENT("onDragStart.builder");
6463          builderFunc->Execute();
6464      }
6465  
6466      return ViewStackModel::GetInstance()->Finish();
6467  }
6468  
JsOnDragEnter(const JSCallbackInfo & info)6469  void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
6470  {
6471      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6472      auto jsVal = info[0];
6473      if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
6474          return;
6475      }
6476      RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6477      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6478      auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
6479                             const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6480          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6481          ACE_SCORING_EVENT("onDragEnter");
6482          PipelineContext::SetCallBackNode(node);
6483          func->Execute(info, extraParams);
6484      };
6485  
6486      ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
6487  }
6488  
JsOnDragEnd(const JSCallbackInfo & info)6489  void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
6490  {
6491      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6492      auto jsVal = info[0];
6493      if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
6494          return;
6495      }
6496      RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6497      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6498      auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
6499                           const RefPtr<OHOS::Ace::DragEvent>& info) {
6500          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6501          ACE_SCORING_EVENT("onDragEnd");
6502          auto extraParams = JsonUtil::Create(true);
6503          PipelineContext::SetCallBackNode(node);
6504          func->Execute(info, extraParams->ToString());
6505      };
6506  
6507      ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
6508  }
6509  
JsOnDragMove(const JSCallbackInfo & info)6510  void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
6511  {
6512      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6513      auto jsVal = info[0];
6514      if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
6515          return;
6516      }
6517      RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6518      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6519      auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
6520                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6521          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6522          ACE_SCORING_EVENT("onDragMove");
6523          PipelineContext::SetCallBackNode(node);
6524          func->Execute(info, extraParams);
6525      };
6526  
6527      ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
6528  }
6529  
JsOnDragLeave(const JSCallbackInfo & info)6530  void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
6531  {
6532      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6533      auto jsVal = info[0];
6534      if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
6535          return;
6536      }
6537      RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6538      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6539      auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
6540                             const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6541          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6542          ACE_SCORING_EVENT("onDragLeave");
6543          PipelineContext::SetCallBackNode(node);
6544          func->Execute(info, extraParams);
6545      };
6546  
6547      ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
6548  }
6549  
JsOnDrop(const JSCallbackInfo & info)6550  void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
6551  {
6552      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6553      auto jsVal = info[0];
6554      if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
6555          return;
6556      }
6557      RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6558      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6559      auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
6560                        const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6561          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6562          ACE_SCORING_EVENT("onDrop");
6563          PipelineContext::SetCallBackNode(node);
6564          func->Execute(info, extraParams);
6565      };
6566  
6567      ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
6568  }
6569  
JsOnAreaChange(const JSCallbackInfo & info)6570  void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
6571  {
6572      auto jsVal = info[0];
6573      if (jsVal->IsUndefined() && IsDisableEventVersion()) {
6574          ViewAbstractModel::GetInstance()->DisableOnAreaChange();
6575          return;
6576      }
6577      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6578      if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
6579          return;
6580      }
6581      auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6582  
6583      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6584      auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
6585                               node = frameNode](
6586                               const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
6587          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6588          ACE_SCORING_EVENT("onAreaChange");
6589          PipelineContext::SetCallBackNode(node);
6590          func->Execute(oldRect, oldOrigin, rect, origin);
6591      };
6592      ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
6593  }
6594  
JsOnSizeChange(const JSCallbackInfo & info)6595  void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
6596  {
6597      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6598      auto jsVal = info[0];
6599      if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
6600          return;
6601      }
6602      auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6603  
6604      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6605      auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
6606                              node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
6607          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6608          ACE_SCORING_EVENT("onSizeChange");
6609          PipelineContext::SetCallBackNode(node);
6610          func->Execute(oldRect, rect);
6611      };
6612      ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
6613  }
6614  
6615  #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)6616  void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
6617  {
6618      if (info.Length() < 2) {
6619          return;
6620      }
6621      if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) {
6622          return;
6623      }
6624      auto popupParam = AceType::MakeRefPtr<PopupParam>();
6625      // Set IsShow to popupParam
6626      if (info[0]->IsBoolean()) {
6627          popupParam->SetIsShow(info[0]->ToBoolean());
6628      } else {
6629          JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
6630          auto callback = ParseDoubleBindCallback(info, showObj);
6631          popupParam->SetOnStateChange(std::move(callback));
6632          popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
6633      }
6634      // Set popup to popupParam
6635      auto popupObj = JSRef<JSObject>::Cast(info[1]);
6636      SetPopupDismiss(info, popupObj, popupParam);
6637      if (popupObj->GetProperty("message")->IsString()) {
6638          ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
6639          ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6640      } else if (!popupObj->GetProperty("builder").IsEmpty()) {
6641          ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
6642          auto builderValue = popupObj->GetProperty("builder");
6643          auto builder = builderValue;
6644          if (!builderValue->IsObject()) {
6645              return;
6646          }
6647          if (!builderValue->IsFunction()) {
6648              JSRef<JSObject> builderObj;
6649              builderObj = JSRef<JSObject>::Cast(builderValue);
6650              builder = builderObj->GetProperty("builder");
6651              if (!builder->IsFunction()) {
6652                  return;
6653              }
6654          }
6655          if (popupParam->IsShow() && !IsPopupCreated()) {
6656              auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6657              CHECK_NULL_VOID(builderFunc);
6658              ViewStackModel::GetInstance()->NewScope();
6659              builderFunc->Execute();
6660              auto customNode = ViewStackModel::GetInstance()->Finish();
6661              ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
6662          } else {
6663              ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6664          }
6665      } else {
6666          return;
6667      }
6668  }
6669  
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)6670  void JSViewAbstract::SetPopupDismiss(
6671      const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
6672  {
6673      auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
6674      if (onWillDismissFunc->IsBoolean()) {
6675          bool onWillDismissBool = onWillDismissFunc->ToBoolean();
6676          popupParam->SetInteractiveDismiss(onWillDismissBool);
6677          popupParam->SetOnWillDismiss(nullptr);
6678          if (onWillDismissBool) {
6679              TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6680          }
6681      } else if (onWillDismissFunc->IsFunction()) {
6682          auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
6683          popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
6684          popupParam->SetInteractiveDismiss(true);
6685          if (onWillDismissCallback != nullptr) {
6686              TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6687          }
6688      }
6689  }
6690  
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)6691  PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
6692  {
6693      auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6694      if (!onWillDismissFunc->IsFunction()) {
6695          return PopupOnWillDismiss();
6696      }
6697      RefPtr<JsFunction> jsFunc =
6698          AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6699      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6700      auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6701                            node = frameNode](int32_t reason) {
6702          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6703          ACE_SCORING_EVENT("Bindpopup.dismiss");
6704          PipelineContext::SetCallBackNode(node);
6705  
6706          JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6707          objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6708          JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6709          dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
6710          dismissObj->SetProperty<int32_t>("reason", reason);
6711          JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6712  
6713          func->ExecuteJS(1, &newJSVal);
6714      };
6715      return onWillDismiss;
6716  }
6717  
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)6718  panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6719  {
6720      ViewAbstractModel::GetInstance()->DismissPopup();
6721      return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6722  }
6723  #endif
6724  
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info)> & onWillDismiss)6725  void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
6726      std::function<void(const int32_t& info)>& onWillDismiss)
6727  {
6728      auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6729      if (onWillDismissFunc->IsFunction()) {
6730          auto jsFunc =
6731              AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6732          onWillDismiss = [func = std::move(jsFunc)](const int32_t& info) {
6733              JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6734              objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6735              JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6736              dismissObj->SetPropertyObject(
6737                  "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
6738              dismissObj->SetProperty<int32_t>("reason", info);
6739              JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6740              func->ExecuteJS(1, &newJSVal);
6741          };
6742      }
6743  }
6744  
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)6745  panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6746  {
6747      ViewAbstractModel::GetInstance()->DismissDialog();
6748      return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6749  }
6750  
JsLinearGradient(const JSCallbackInfo & info)6751  void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
6752  {
6753      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6754      auto jsVal = info[0];
6755      if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
6756          NG::Gradient newGradient;
6757          newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6758          ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6759          return;
6760      }
6761      NG::Gradient newGradient;
6762      NewJsLinearGradient(info, newGradient);
6763      ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6764  }
6765  
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6766  void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6767  {
6768      if (!info[0]->IsObject()) {
6769          return;
6770      }
6771      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6772      newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6773      // angle
6774      std::optional<float> degree;
6775      if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6776          GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
6777      } else {
6778          GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
6779      }
6780      if (degree) {
6781          newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
6782          degree.reset();
6783      }
6784      // direction
6785      auto direction = static_cast<GradientDirection>(
6786          jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
6787      switch (direction) {
6788          case GradientDirection::LEFT:
6789              newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6790              break;
6791          case GradientDirection::RIGHT:
6792              newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6793              break;
6794          case GradientDirection::TOP:
6795              newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6796              break;
6797          case GradientDirection::BOTTOM:
6798              newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6799              break;
6800          case GradientDirection::LEFT_TOP:
6801              newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6802              newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6803              break;
6804          case GradientDirection::LEFT_BOTTOM:
6805              newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6806              newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6807              break;
6808          case GradientDirection::RIGHT_TOP:
6809              newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6810              newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6811              break;
6812          case GradientDirection::RIGHT_BOTTOM:
6813              newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6814              newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6815              break;
6816          case GradientDirection::NONE:
6817          case GradientDirection::START_TO_END:
6818          case GradientDirection::END_TO_START:
6819          default:
6820              break;
6821      }
6822      auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6823      newGradient.SetRepeat(repeating);
6824      NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6825  }
6826  
JsRadialGradient(const JSCallbackInfo & info)6827  void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
6828  {
6829      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6830      auto jsVal = info[0];
6831      if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
6832          NG::Gradient newGradient;
6833          newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6834          ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6835          return;
6836      }
6837      NG::Gradient newGradient;
6838      NewJsRadialGradient(info, newGradient);
6839      ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6840  }
6841  
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6842  void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6843  {
6844      JSRef<JSVal> arg = info[0];
6845      if (!arg->IsObject()) {
6846          return;
6847      }
6848      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6849      newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6850      // center
6851      JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6852      if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6853          CalcDimension value;
6854          JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6855          if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6856              newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
6857              if (value.Unit() == DimensionUnit::PERCENT) {
6858                  // [0,1] -> [0, 100]
6859                  newGradient.GetRadialGradient()->radialCenterX =
6860                      CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6861              }
6862          }
6863          if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6864              newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
6865              if (value.Unit() == DimensionUnit::PERCENT) {
6866                  // [0,1] -> [0, 100]
6867                  newGradient.GetRadialGradient()->radialCenterY =
6868                      CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6869              }
6870          }
6871      }
6872      // radius
6873      CalcDimension radius;
6874      if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6875          newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6876          newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6877      }
6878      // repeating
6879      auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6880      newGradient.SetRepeat(repeating);
6881      // color stops
6882      NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6883  }
6884  
JsSweepGradient(const JSCallbackInfo & info)6885  void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6886  {
6887      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6888      auto jsVal = info[0];
6889      if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6890          NG::Gradient newGradient;
6891          newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6892          ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6893          return;
6894      }
6895  
6896      NG::Gradient newGradient;
6897      NewJsSweepGradient(info, newGradient);
6898      ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6899  }
6900  
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6901  void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6902  {
6903      JSRef<JSVal> arg = info[0];
6904      if (!arg->IsObject()) {
6905          return;
6906      }
6907      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6908      newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6909      // center
6910      JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6911      if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6912          CalcDimension value;
6913          JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6914          if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6915              newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6916              if (value.Unit() == DimensionUnit::PERCENT) {
6917                  // [0,1] -> [0, 100]
6918                  newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6919              }
6920          }
6921          if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6922              newGradient.GetSweepGradient()->centerY = CalcDimension(value);
6923              if (value.Unit() == DimensionUnit::PERCENT) {
6924                  // [0,1] -> [0, 100]
6925                  newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6926              }
6927          }
6928      }
6929      // start, end and rotation
6930      ParseSweepGradientPartly(jsObj, newGradient);
6931      // repeating
6932      auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6933      newGradient.SetRepeat(repeating);
6934      // color stops
6935      NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6936  }
6937  
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)6938  void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
6939  {
6940      std::optional<float> degreeStart;
6941      std::optional<float> degreeEnd;
6942      std::optional<float> degreeRotation;
6943      if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6944          GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
6945          GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
6946          GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
6947      } else {
6948          GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
6949          GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
6950          GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
6951      }
6952      if (degreeStart) {
6953          CheckAngle(degreeStart);
6954          newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
6955      }
6956      if (degreeEnd) {
6957          CheckAngle(degreeEnd);
6958          newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
6959      }
6960      if (degreeRotation) {
6961          CheckAngle(degreeRotation);
6962          newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
6963      }
6964  }
6965  
JsMotionPath(const JSCallbackInfo & info)6966  void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
6967  {
6968      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6969      auto jsVal = info[0];
6970      if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
6971          ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6972          return;
6973      }
6974      MotionPathOption motionPathOption;
6975      if (ParseMotionPath(jsVal, motionPathOption)) {
6976          ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
6977      } else {
6978          TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
6979          ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6980      }
6981  }
6982  
JsShadow(const JSCallbackInfo & info)6983  void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
6984  {
6985      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6986      auto jsVal = info[0];
6987      if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
6988          Shadow shadow;
6989          std::vector<Shadow> shadows { shadow };
6990          ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6991          return;
6992      }
6993      Shadow shadow;
6994      if (!ParseShadowProps(jsVal, shadow)) {
6995          info.ReturnSelf();
6996          return;
6997      }
6998      std::vector<Shadow> shadows { shadow };
6999      ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
7000  }
7001  
JsBlendMode(const JSCallbackInfo & info)7002  void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
7003  {
7004      if (info.Length() == 0) {
7005          return;
7006      }
7007      BlendMode blendMode = BlendMode::NONE;
7008      BlendApplyType blendApplyType = BlendApplyType::FAST;
7009      // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7010      constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7011      constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7012      constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7013      constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7014      if (info[0]->IsNumber()) {
7015          auto blendModeNum = info[0]->ToNumber<int32_t>();
7016          if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7017              blendMode = static_cast<BlendMode>(blendModeNum);
7018          } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7019              // backward compatibility code, will remove soon
7020              blendMode = BlendMode::SRC_OVER;
7021              blendApplyType = BlendApplyType::OFFSCREEN;
7022          } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7023              // backward compatibility code, will remove soon
7024              blendMode = BlendMode::SRC_IN;
7025              blendApplyType = BlendApplyType::OFFSCREEN;
7026          } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7027              // backward compatibility code, will remove soon
7028              blendMode = BlendMode::DST_IN;
7029              blendApplyType = BlendApplyType::OFFSCREEN;
7030          } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7031              blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7032          }
7033      }
7034      if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7035          auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7036          if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7037              blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7038          }
7039      }
7040      ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7041      ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7042  }
7043  
JsAdvancedBlendMode(const JSCallbackInfo & info)7044  void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
7045  {
7046      if (info.Length() == 0) {
7047          return;
7048      }
7049      BlendMode blendMode = BlendMode::NONE;
7050      BlendApplyType blendApplyType = BlendApplyType::FAST;
7051      // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7052      constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7053      constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7054      constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7055      constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7056      if (info[0]->IsNumber()) {
7057          auto blendModeNum = info[0]->ToNumber<int32_t>();
7058          if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7059              blendMode = static_cast<BlendMode>(blendModeNum);
7060          } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7061              // backward compatibility code, will remove soon
7062              blendMode = BlendMode::SRC_OVER;
7063              blendApplyType = BlendApplyType::OFFSCREEN;
7064          } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7065              // backward compatibility code, will remove soon
7066              blendMode = BlendMode::SRC_IN;
7067              blendApplyType = BlendApplyType::OFFSCREEN;
7068          } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7069              // backward compatibility code, will remove soon
7070              blendMode = BlendMode::DST_IN;
7071              blendApplyType = BlendApplyType::OFFSCREEN;
7072          } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7073              blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7074          }
7075      } else if (info[0]->IsObject()) {
7076          auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
7077          ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
7078      }
7079      if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7080          auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7081          if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7082              blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7083          }
7084      }
7085      if (!info[0]->IsObject()) {
7086          ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7087      }
7088      ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7089  }
7090  
JsGrayScale(const JSCallbackInfo & info)7091  void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
7092  {
7093      CalcDimension value;
7094      if (!ParseJsDimensionVp(info[0], value)) {
7095          value.SetValue(0.0);
7096          ViewAbstractModel::GetInstance()->SetGrayScale(value);
7097          return;
7098      }
7099  
7100      if (LessNotEqual(value.Value(), 0.0)) {
7101          value.SetValue(0.0);
7102      }
7103  
7104      if (GreatNotEqual(value.Value(), 1.0)) {
7105          value.SetValue(1.0);
7106      }
7107  
7108      ViewAbstractModel::GetInstance()->SetGrayScale(value);
7109  }
7110  
JsBrightness(const JSCallbackInfo & info)7111  void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
7112  {
7113      CalcDimension value;
7114      if (!ParseJsDimensionVp(info[0], value)) {
7115          value.SetValue(1.0);
7116          ViewAbstractModel::GetInstance()->SetBrightness(value);
7117          return;
7118      }
7119  
7120      ViewAbstractModel::GetInstance()->SetBrightness(value);
7121  }
7122  
JsContrast(const JSCallbackInfo & info)7123  void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
7124  {
7125      CalcDimension value;
7126      if (!ParseJsDimensionVp(info[0], value)) {
7127          value.SetValue(1.0);
7128          ViewAbstractModel::GetInstance()->SetContrast(value);
7129          return;
7130      }
7131  
7132      if (LessNotEqual(value.Value(), 0.0)) {
7133          value.SetValue(0.0);
7134      }
7135  
7136      ViewAbstractModel::GetInstance()->SetContrast(value);
7137  }
7138  
JsSaturate(const JSCallbackInfo & info)7139  void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
7140  {
7141      CalcDimension value;
7142      if (!ParseJsDimensionVp(info[0], value)) {
7143          value.SetValue(1.0);
7144          ViewAbstractModel::GetInstance()->SetSaturate(value);
7145          return;
7146      }
7147  
7148      if (LessNotEqual(value.Value(), 0.0)) {
7149          value.SetValue(0.0);
7150      }
7151  
7152      ViewAbstractModel::GetInstance()->SetSaturate(value);
7153  }
7154  
JsSepia(const JSCallbackInfo & info)7155  void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
7156  {
7157      CalcDimension value;
7158      if (!ParseJsDimensionVp(info[0], value)) {
7159          value.SetValue(0.0);
7160          ViewAbstractModel::GetInstance()->SetSepia(value);
7161          return;
7162      }
7163  
7164      if (LessNotEqual(value.Value(), 0.0)) {
7165          value.SetValue(0.0);
7166      }
7167  
7168      ViewAbstractModel::GetInstance()->SetSepia(value);
7169  }
7170  
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)7171  bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
7172  {
7173      double invertValue = 0.0;
7174      if (ParseJsDouble(jsValue, invertValue)) {
7175          invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
7176          return true;
7177      }
7178      auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
7179      if (!argsPtrItem || argsPtrItem->IsNull()) {
7180          return false;
7181      }
7182      InvertOption option;
7183      double low = 0.0;
7184      if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
7185          option.low_ = std::clamp(low, 0.0, 1.0);
7186      }
7187      double high = 0.0;
7188      if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
7189          option.high_ = std::clamp(high, 0.0, 1.0);
7190      }
7191      double threshold = 0.0;
7192      if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
7193          option.threshold_ = std::clamp(threshold, 0.0, 1.0);
7194      }
7195      double thresholdRange = 0.0;
7196      if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
7197          option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
7198      }
7199      invert = option;
7200      return true;
7201  }
7202  
JsInvert(const JSCallbackInfo & info)7203  void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
7204  {
7205      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7206      InvertVariant invert = 0.0f;
7207      auto jsVal = info[0];
7208      if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
7209          ViewAbstractModel::GetInstance()->SetInvert(invert);
7210          return;
7211      }
7212      if (ParseInvertProps(jsVal, invert)) {
7213          ViewAbstractModel::GetInstance()->SetInvert(invert);
7214      }
7215      ViewAbstractModel::GetInstance()->SetInvert(invert);
7216  }
7217  
JsSystemBarEffect(const JSCallbackInfo & info)7218  void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
7219  {
7220      ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
7221  }
7222  
JsHueRotate(const JSCallbackInfo & info)7223  void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
7224  {
7225      std::optional<float> degree;
7226      JSRef<JSVal> arg = info[0];
7227      if (arg->IsString()) {
7228          degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
7229      } else if (arg->IsNumber()) {
7230          degree = static_cast<float>(arg->ToNumber<int32_t>());
7231      } else {
7232          ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
7233          return;
7234      }
7235      float deg = 0.0f;
7236      if (degree) {
7237          deg = degree.value();
7238          degree.reset();
7239      }
7240      deg = std::fmod(deg, ROUND_UNIT);
7241      if (deg < 0.0f) {
7242          deg += ROUND_UNIT;
7243      }
7244      ViewAbstractModel::GetInstance()->SetHueRotate(deg);
7245  }
7246  
JsClip(const JSCallbackInfo & info)7247  void JSViewAbstract::JsClip(const JSCallbackInfo& info)
7248  {
7249      JSRef<JSVal> arg = info[0];
7250      if (arg->IsUndefined()) {
7251          ViewAbstractModel::GetInstance()->SetClipEdge(false);
7252          return;
7253      }
7254      if (arg->IsObject()) {
7255          JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7256          if (clipShape == nullptr) {
7257              return;
7258          }
7259          ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7260      } else if (arg->IsBoolean()) {
7261          ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
7262      }
7263  }
7264  
JsClipShape(const JSCallbackInfo & info)7265  void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
7266  {
7267      if (info[0]->IsObject()) {
7268          JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7269          if (clipShape == nullptr) {
7270              return;
7271          }
7272          ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7273      }
7274  }
7275  
JsMask(const JSCallbackInfo & info)7276  void JSViewAbstract::JsMask(const JSCallbackInfo& info)
7277  {
7278      JSRef<JSVal> arg = info[0];
7279      if (!arg->IsObject()) {
7280          ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
7281          return;
7282      }
7283      auto paramObject = JSRef<JSObject>::Cast(arg);
7284      JSRef<JSVal> typeParam = paramObject->GetProperty("type");
7285      if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
7286          typeParam->ToString() == "ProgressMask") {
7287          auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
7288          JSRef<JSVal> jValue = paramObject->GetProperty("value");
7289          auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
7290          if (value < 0.0f) {
7291              value = 0.0f;
7292          }
7293          progressMask->SetValue(value);
7294          JSRef<JSVal> jTotal = paramObject->GetProperty("total");
7295          auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
7296          if (total < 0.0f) {
7297              total = DEFAULT_PROGRESS_TOTAL;
7298          }
7299          progressMask->SetMaxValue(total);
7300          JSRef<JSVal> jColor = paramObject->GetProperty("color");
7301          Color colorVal;
7302          if (ParseJsColor(jColor, colorVal)) {
7303              progressMask->SetColor(colorVal);
7304          } else {
7305              RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
7306              progressMask->SetColor(theme->GetMaskColor());
7307          }
7308          JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
7309          if (jEnableBreathe->IsBoolean()) {
7310              progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
7311          }
7312          ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
7313      } else {
7314          JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7315          if (maskShape == nullptr) {
7316              return;
7317          };
7318          ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7319      }
7320  }
7321  
JsMaskShape(const JSCallbackInfo & info)7322  void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
7323  {
7324      if (!info[0]->IsObject()) {
7325          return;
7326      }
7327  
7328      JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7329      if (maskShape == nullptr) {
7330          return;
7331      };
7332      ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7333  }
7334  
JsFocusable(const JSCallbackInfo & info)7335  void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
7336  {
7337      if (!info[0]->IsBoolean()) {
7338          return;
7339      }
7340      ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
7341  }
7342  
JsTabStop(const JSCallbackInfo & info)7343  void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
7344  {
7345      if (!info[0]->IsBoolean()) {
7346          ViewAbstractModel::GetInstance()->SetTabStop(false);
7347          return;
7348      }
7349      ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
7350  }
7351  
JsFocusBox(const JSCallbackInfo & info)7352  void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
7353  {
7354      if (!info[0]->IsObject() || info.Length() != 1) {
7355          return;
7356      }
7357      auto obj = JSRef<JSObject>::Cast(info[0]);
7358      NG::FocusBoxStyle style;
7359  
7360      CalcDimension margin;
7361      if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
7362          style.margin = margin;
7363      }
7364      CalcDimension strokeWidth;
7365      if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
7366          style.strokeWidth = strokeWidth;
7367      }
7368      Color strokeColor;
7369      if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
7370          style.strokeColor = strokeColor;
7371      }
7372  
7373      ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
7374  }
7375  
JsOnFocusMove(const JSCallbackInfo & args)7376  void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
7377  {
7378      JSRef<JSVal> arg = args[0];
7379      if (arg->IsFunction()) {
7380          RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7381          auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7382          auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
7383                                 int info) {
7384              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7385              ACE_SCORING_EVENT("onFocusMove");
7386              PipelineContext::SetCallBackNode(node);
7387              func->Execute(info);
7388          };
7389          ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
7390      }
7391  }
7392  
JsOnKeyEvent(const JSCallbackInfo & args)7393  void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
7394  {
7395      JSRef<JSVal> arg = args[0];
7396      if (arg->IsUndefined() && IsDisableEventVersion()) {
7397          ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
7398          return;
7399      }
7400      if (!arg->IsFunction()) {
7401          return;
7402      }
7403      RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
7404      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7405      auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
7406                            KeyEventInfo& info) -> bool {
7407          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
7408          ACE_SCORING_EVENT("onKey");
7409          PipelineContext::SetCallBackNode(node);
7410          auto ret = func->ExecuteWithValue(info);
7411          return ret->IsBoolean() ? ret->ToBoolean() : false;
7412      };
7413      ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
7414  }
7415  
JsOnFocus(const JSCallbackInfo & args)7416  void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
7417  {
7418      JSRef<JSVal> arg = args[0];
7419      if (arg->IsUndefined() && IsDisableEventVersion()) {
7420          ViewAbstractModel::GetInstance()->DisableOnFocus();
7421          return;
7422      }
7423      if (!arg->IsFunction()) {
7424          return;
7425      }
7426      RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7427      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7428      auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
7429          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7430          ACE_SCORING_EVENT("onFocus");
7431          PipelineContext::SetCallBackNode(node);
7432          func->Execute();
7433      };
7434  
7435      ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
7436  }
7437  
JsOnBlur(const JSCallbackInfo & args)7438  void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
7439  {
7440      JSRef<JSVal> arg = args[0];
7441      if (arg->IsUndefined() && IsDisableEventVersion()) {
7442          ViewAbstractModel::GetInstance()->DisableOnBlur();
7443          return;
7444      }
7445      if (!arg->IsFunction()) {
7446          return;
7447      }
7448      RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7449      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7450      auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
7451          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7452          ACE_SCORING_EVENT("onBlur");
7453          PipelineContext::SetCallBackNode(node);
7454          func->Execute();
7455      };
7456  
7457      ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
7458  }
7459  
JsTabIndex(const JSCallbackInfo & info)7460  void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
7461  {
7462      JSRef<JSVal> arg = info[0];
7463      if (!arg->IsNumber()) {
7464          return;
7465      }
7466      ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
7467  }
7468  
JsFocusOnTouch(const JSCallbackInfo & info)7469  void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
7470  {
7471      JSRef<JSVal> arg = info[0];
7472      if (!arg->IsBoolean()) {
7473          return;
7474      }
7475      auto isFocusOnTouch = arg->ToBoolean();
7476      ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
7477  }
7478  
JsDefaultFocus(const JSCallbackInfo & info)7479  void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
7480  {
7481      JSRef<JSVal> arg = info[0];
7482      if (!arg->IsBoolean()) {
7483          return;
7484      }
7485      auto isDefaultFocus = arg->ToBoolean();
7486      ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
7487  }
7488  
JsGroupDefaultFocus(const JSCallbackInfo & info)7489  void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
7490  {
7491      JSRef<JSVal> arg = info[0];
7492      if (!arg->IsBoolean()) {
7493          return;
7494      }
7495      auto isGroupDefaultFocus = arg->ToBoolean();
7496      ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
7497  }
7498  
JsKey(const std::string & key)7499  void JSViewAbstract::JsKey(const std::string& key)
7500  {
7501      ViewAbstractModel::GetInstance()->SetInspectorId(key);
7502  }
7503  
JsId(const JSCallbackInfo & info)7504  void JSViewAbstract::JsId(const JSCallbackInfo& info)
7505  {
7506      JSRef<JSVal> arg = info[0];
7507      if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
7508          return;
7509      }
7510      std::string id = arg->ToString();
7511      if (id.empty()) {
7512          return;
7513      }
7514      JsKey(id);
7515  }
7516  
JsRestoreId(int32_t restoreId)7517  void JSViewAbstract::JsRestoreId(int32_t restoreId)
7518  {
7519      ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
7520  }
7521  
JsDebugLine(const JSCallbackInfo & info)7522  void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
7523  {
7524      std::string debugLine;
7525      auto length = info.Length();
7526      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
7527  
7528      if (length == 1) { // deprecated version of debug line
7529          auto jsVal = info[0];
7530          if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
7531              return;
7532          }
7533          debugLine = jsVal->ToString();
7534      } else if (length == 2) { // debug line with extra package name
7535          auto line = info[0];
7536          auto packageName = info[1];
7537          if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
7538              !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
7539              return;
7540          }
7541          auto json = JsonUtil::Create(true);
7542          json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
7543          json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
7544          debugLine = json->ToString();
7545      }
7546  
7547      ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
7548  }
7549  
JsOpacityPassThrough(const JSCallbackInfo & info)7550  void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
7551  {
7552      double opacity = 1.0;
7553      if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7554          if (ParseJsDouble(info[0], opacity)) {
7555              opacity = std::clamp(opacity, 0.0, 1.0);
7556          }
7557      } else {
7558          if (!ParseJsDouble(info[0], opacity)) {
7559              return;
7560          }
7561          if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
7562              opacity = 1.0;
7563          }
7564      }
7565  
7566      ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
7567  }
7568  
JsTransitionPassThrough(const JSCallbackInfo & info)7569  void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
7570  {
7571      if (info.Length() == 0) {
7572          ViewAbstractModel::GetInstance()->SetTransition(
7573              NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
7574          return;
7575      }
7576      if (!info[0]->IsObject()) {
7577          if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7578              ViewAbstractModel::GetInstance()->CleanTransition();
7579              ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
7580          }
7581          return;
7582      }
7583      auto obj = JSRef<JSObject>::Cast(info[0]);
7584      if (!obj->GetProperty("successor_")->IsUndefined()) {
7585          auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
7586          std::function<void(bool)> finishCallback;
7587          if (info.Length() > 1 && info[1]->IsFunction()) {
7588              finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
7589          }
7590          ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
7591          return;
7592      }
7593      auto options = ParseJsTransition(obj);
7594      ViewAbstractModel::GetInstance()->SetTransition(options, true);
7595  }
7596  
JsAccessibilityGroup(const JSCallbackInfo & info)7597  void JSViewAbstract::JsAccessibilityGroup(const JSCallbackInfo& info)
7598  {
7599      bool isGroup = false;
7600      if (info[0]->IsBoolean()) {
7601          isGroup = info[0]->ToBoolean();
7602      }
7603      ViewAbstractModel::GetInstance()->SetAccessibilityGroup(isGroup);
7604  
7605      if (info.Length() > 1 && info[1]->IsObject()) {
7606          auto obj = JSRef<JSObject>::Cast(info[1]);
7607  
7608          auto preferAccessibilityTextObj = obj->GetProperty("accessibilityPreferred");
7609          auto preferAccessibilityText = preferAccessibilityTextObj->IsBoolean() ? preferAccessibilityTextObj->ToBoolean() : false;
7610          ViewAbstractModel::GetInstance()->SetAccessibilityTextPreferred(preferAccessibilityText);
7611      }
7612  }
7613  
JsAccessibilityText(const JSCallbackInfo & info)7614  void JSViewAbstract::JsAccessibilityText(const JSCallbackInfo& info)
7615  {
7616      const JSRef<JSVal>& jsValue = info[0];
7617      std::string text;
7618      if (!ParseJsString(jsValue, text)) {
7619          return;
7620      }
7621      ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
7622  }
7623  
JsAccessibilityTextHint(const std::string & text)7624  void JSViewAbstract::JsAccessibilityTextHint(const std::string& text)
7625  {
7626      ViewAbstractModel::GetInstance()->SetAccessibilityTextHint(text);
7627  }
7628  
JsAccessibilityDescription(const JSCallbackInfo & info)7629  void JSViewAbstract::JsAccessibilityDescription(const JSCallbackInfo& info)
7630  {
7631      const JSRef<JSVal>& jsValue = info[0];
7632      std::string description;
7633      if (!ParseJsString(jsValue, description)) {
7634          return;
7635      }
7636      std::pair<bool, std::string> autoEventPair(false, "");
7637      std::pair<bool, std::string> descriptionPair(false, "");
7638      ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair);
7639      if (descriptionPair.first) {
7640          ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second);
7641      } else {
7642          ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
7643      }
7644      if (autoEventPair.first) {
7645          ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second);
7646      }
7647  }
7648  
ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)7649  void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description,
7650      std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair)
7651  {
7652      if (description.empty()) {
7653          return;
7654      }
7655      if (!StartWith(description, "{") || !EndWith(description, "}")) {
7656          return;
7657      }
7658      auto jsonObj = JsonUtil::ParseJsonString(description);
7659      if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) {
7660          return;
7661      }
7662      if (jsonObj->Contains("$autoEventParam")) {
7663          auto param = jsonObj->GetValue("$autoEventParam");
7664          if (param) {
7665              autoEventPair = std::make_pair(true, param->ToString());
7666          }
7667      }
7668      if (jsonObj->Contains("$accessibilityDescription")) {
7669          descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription"));
7670      } else if (jsonObj->Contains("$autoEventParam")) {
7671          descriptionPair = std::make_pair(true, "");
7672      }
7673  }
7674  
JsAccessibilityImportance(const std::string & importance)7675  void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
7676  {
7677      ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
7678  }
7679  
JsAccessibilityLevel(const std::string & level)7680  void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
7681  {
7682      ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
7683  }
7684  
JsAccessibilityVirtualNode(const JSCallbackInfo & info)7685  void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info)
7686  {
7687      // parse builder
7688      if (!info[0]->IsObject()) {
7689          return;
7690      }
7691      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7692      auto builder = obj->GetProperty("builder");
7693      if (builder->IsFunction()) {
7694          auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7695          CHECK_NULL_VOID(builderFunc);
7696          auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
7697              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7698              ACE_SCORING_EVENT("AccessibilityVirtualNode");
7699              func->Execute();
7700          };
7701          NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc));
7702      }
7703  }
7704  
JsAccessibilitySelected(const JSCallbackInfo & info)7705  void JSViewAbstract::JsAccessibilitySelected(const JSCallbackInfo& info)
7706  {
7707      bool selected = false;
7708      bool resetValue = false;
7709      JSRef<JSVal> arg = info[0];
7710      if (arg->IsUndefined()) {
7711          resetValue = true;
7712      } else if (arg->IsBoolean()) {
7713          selected = arg->ToBoolean();
7714      } else {
7715          return;
7716      }
7717  
7718      ViewAbstractModel::GetInstance()->SetAccessibilitySelected(selected, resetValue);
7719  }
7720  
JsAccessibilityChecked(const JSCallbackInfo & info)7721  void JSViewAbstract::JsAccessibilityChecked(const JSCallbackInfo& info)
7722  {
7723      bool checked = false;
7724      bool resetValue = false;
7725      JSRef<JSVal> arg = info[0];
7726      if (arg->IsUndefined()) {
7727          resetValue = true;
7728      } else if (arg->IsBoolean()) {
7729          checked = arg->ToBoolean();
7730      } else {
7731          return;
7732      }
7733  
7734      ViewAbstractModel::GetInstance()->SetAccessibilityChecked(checked, resetValue);
7735  }
7736  
JsBackground(const JSCallbackInfo & info)7737  void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
7738  {
7739      // Check the parameters
7740      if (info.Length() <= 0 || !info[0]->IsObject()) {
7741          return;
7742      }
7743      JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
7744      auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
7745      if (!builder->IsFunction()) {
7746          return;
7747      }
7748      auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7749      CHECK_NULL_VOID(builderFunc);
7750      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7751      auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7752          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7753          ACE_SCORING_EVENT("BindBackground");
7754          PipelineContext::SetCallBackNode(node);
7755          func->Execute();
7756      };
7757      Alignment alignment = Alignment::CENTER;
7758      if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
7759          JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
7760          auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
7761          auto value = align->ToNumber<int32_t>();
7762          alignment = ParseAlignment(value);
7763      }
7764      ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
7765  }
7766  
JsBindContextMenu(const JSCallbackInfo & info)7767  void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
7768  {
7769      NG::MenuParam menuParam;
7770      // Check the parameters
7771      if (info.Length() <= 0) {
7772          return;
7773      }
7774      size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
7775      if (!info[builderIndex]->IsObject()) {
7776          return;
7777      }
7778  
7779      JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
7780      auto builder = menuObj->GetProperty("builder");
7781      if (!builder->IsFunction()) {
7782          return;
7783      }
7784      auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7785      CHECK_NULL_VOID(builderFunc);
7786  
7787      ResponseType responseType = ResponseType::LONG_PRESS;
7788      if (!info[0]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7789          auto response = info[1]->ToNumber<int32_t>();
7790          responseType = static_cast<ResponseType>(response);
7791      }
7792      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7793      std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7794                                            node = frameNode]() {
7795          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7796          ACE_SCORING_EVENT("BuildContextMenu");
7797          PipelineContext::SetCallBackNode(node);
7798          func->Execute();
7799      };
7800  
7801      menuParam.previewMode = MenuPreviewMode::NONE;
7802      std::function<void()> previewBuildFunc = nullptr;
7803      if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
7804          ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc);
7805      }
7806  
7807      if (responseType != ResponseType::LONG_PRESS) {
7808          menuParam.previewMode = MenuPreviewMode::NONE;
7809          menuParam.isShowHoverImage = false;
7810          menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
7811      }
7812      menuParam.type = NG::MenuType::CONTEXT_MENU;
7813      ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
7814      ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
7815  }
7816  
ParseBindContentCoverIsShow(const JSCallbackInfo & info)7817  bool ParseBindContentCoverIsShow(const JSCallbackInfo& info)
7818  {
7819      bool isShow = false;
7820      if (info[0]->IsBoolean()) {
7821          isShow = info[0]->ToBoolean();
7822      } else if (info[0]->IsObject()) {
7823          JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7824          auto isShowObj = callbackObj->GetProperty("value");
7825          isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7826      }
7827      TAG_LOGD(AceLogTag::ACE_SHEET, "ContentCover get isShow is: %{public}d", isShow);
7828      return isShow;
7829  }
7830  
JsBindContentCover(const JSCallbackInfo & info)7831  void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
7832  {
7833      // parse isShow
7834      bool isShow = ParseBindContentCoverIsShow(info);
7835      DoubleBindCallback callback = nullptr;
7836      if (info[0]->IsObject()) {
7837          JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7838          callback = ParseDoubleBindCallback(info, callbackObj);
7839      }
7840  
7841      // parse builder
7842      if (!info[1]->IsObject()) {
7843          return;
7844      }
7845      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7846      auto builder = obj->GetProperty("builder");
7847      if (!builder->IsFunction()) {
7848          return;
7849      }
7850      auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7851      CHECK_NULL_VOID(builderFunc);
7852      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7853      auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7854          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7855          ACE_SCORING_EVENT("BindContentCover");
7856          PipelineContext::SetCallBackNode(node);
7857          func->Execute();
7858      };
7859  
7860      // parse ModalTransition
7861      NG::ModalStyle modalStyle;
7862      modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
7863      std::function<void()> onShowCallback;
7864      std::function<void()> onDismissCallback;
7865      std::function<void()> onWillShowCallback;
7866      std::function<void()> onWillDismissCallback;
7867      NG::ContentCoverParam contentCoverParam;
7868      std::function<void(const int32_t&)> onWillDismissFunc;
7869      if (info.Length() == 3) {
7870          if (info[2]->IsObject()) {
7871              ParseOverlayCallback(info[2], onShowCallback, onDismissCallback, onWillShowCallback, /* 2:args index */
7872                  onWillDismissCallback, onWillDismissFunc);
7873              ParseModalStyle(info[2], modalStyle);
7874              contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
7875              ParseModalTransitonEffect(info[2], contentCoverParam, info.GetExecutionContext()); /* 2:args index */
7876          } else if (info[2]->IsNumber()) {
7877              auto transitionNumber = info[2]->ToNumber<int32_t>();
7878              if (transitionNumber >= 0 && transitionNumber <= 2) {
7879                  modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7880              }
7881          }
7882      }
7883      ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
7884          std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
7885          std::move(onWillDismissCallback), contentCoverParam);
7886  }
7887  
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)7888  void JSViewAbstract::ParseModalTransitonEffect(
7889      const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
7890  {
7891      auto transitionEffectValue = paramObj->GetProperty("transition");
7892      if (transitionEffectValue->IsObject()) {
7893          JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
7894          contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
7895      }
7896  }
7897  
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)7898  void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
7899  {
7900      auto modalTransition = paramObj->GetProperty("modalTransition");
7901      auto backgroundColor = paramObj->GetProperty("backgroundColor");
7902      if (modalTransition->IsNumber()) {
7903          auto transitionNumber = modalTransition->ToNumber<int32_t>();
7904          if (transitionNumber >= 0 && transitionNumber <= 2) {
7905              modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7906          }
7907      }
7908      Color color;
7909      if (ParseJsColor(backgroundColor, color)) {
7910          modalStyle.backgroundColor = color;
7911      }
7912  }
7913  
ParseSheetIsShow(const JSCallbackInfo & info,bool & isShow,std::function<void (const std::string &)> & callback)7914  void JSViewAbstract::ParseSheetIsShow(
7915      const JSCallbackInfo& info, bool& isShow, std::function<void(const std::string&)>& callback)
7916  {
7917      if (info[0]->IsBoolean()) {
7918          isShow = info[0]->ToBoolean();
7919      } else if (info[0]->IsObject()) {
7920          JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7921          callback = ParseDoubleBindCallback(info, callbackObj);
7922          auto isShowObj = callbackObj->GetProperty("value");
7923          isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7924      }
7925      TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet get isShow is: %{public}d", isShow);
7926  }
7927  
JsBindSheet(const JSCallbackInfo & info)7928  void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
7929  {
7930      // parse isShow and builder
7931      bool isShow = false;
7932      DoubleBindCallback callback = nullptr;
7933      ParseSheetIsShow(info, isShow, callback);
7934      if (!info[1]->IsObject())
7935          return;
7936      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7937      auto builder = obj->GetProperty("builder");
7938      if (!builder->IsFunction())
7939          return;
7940      auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7941      CHECK_NULL_VOID(builderFunc);
7942      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7943      auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7944          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7945          ACE_SCORING_EVENT("BindSheet");
7946          PipelineContext::SetCallBackNode(node);
7947          func->Execute();
7948      };
7949      // parse SheetStyle and callbacks
7950      NG::SheetStyle sheetStyle;
7951      sheetStyle.sheetMode = NG::SheetMode::LARGE;
7952      sheetStyle.showDragBar = true;
7953      sheetStyle.showCloseIcon = true;
7954      sheetStyle.showInPage = false;
7955      std::function<void()> onAppearCallback;
7956      std::function<void()> onDisappearCallback;
7957      std::function<void()> onWillAppearCallback;
7958      std::function<void()> onWillDisappearCallback  ;
7959      std::function<void()> shouldDismissFunc;
7960      std::function<void(const int32_t)> onWillDismissCallback;
7961      std::function<void(const float)> onHeightDidChangeCallback;
7962      std::function<void(const float)> onDetentsDidChangeCallback;
7963      std::function<void(const float)> onWidthDidChangeCallback;
7964      std::function<void(const float)> onTypeDidChangeCallback;
7965      std::function<void()> titleBuilderFunction;
7966      std::function<void()> sheetSpringBackFunc;
7967      if (info.Length() == PARAMETER_LENGTH_THIRD && info[SECOND_INDEX]->IsObject()) {
7968          ParseSheetCallback(info[SECOND_INDEX], onAppearCallback, onDisappearCallback, shouldDismissFunc,
7969              onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
7970              onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
7971          ParseSheetStyle(info[2], sheetStyle);
7972          ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction);
7973      }
7974      ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
7975          std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
7976          std::move(shouldDismissFunc), std::move(onWillDismissCallback),  std::move(onWillAppearCallback),
7977          std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
7978          std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
7979  }
7980  
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)7981  void JSViewAbstract::ParseSheetStyle(
7982      const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
7983  {
7984      auto height = paramObj->GetProperty("height");
7985      auto showDragBar = paramObj->GetProperty("dragBar");
7986      auto backgroundColor = paramObj->GetProperty("backgroundColor");
7987      auto maskColor = paramObj->GetProperty("maskColor");
7988      auto sheetDetents = paramObj->GetProperty("detents");
7989      auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
7990      auto showCloseIcon = paramObj->GetProperty("showClose");
7991      auto type = paramObj->GetProperty("preferType");
7992      auto interactive = paramObj->GetProperty("enableOutsideInteractive");
7993      auto showMode = paramObj->GetProperty("mode");
7994      auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
7995      auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
7996      auto uiContextObj = paramObj->GetProperty("uiContext");
7997      if (uiContextObj->IsObject()) {
7998          JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
7999          auto prop = obj->GetProperty("instanceId_");
8000          if (prop->IsNumber()) {
8001              sheetStyle.instanceId = prop->ToNumber<int32_t>();
8002          }
8003      }
8004      NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
8005      if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
8006          sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
8007      }
8008  
8009      std::vector<NG::SheetHeight> detents;
8010      if (ParseSheetDetents(sheetDetents, detents)) {
8011          sheetStyle.detents = detents;
8012      }
8013      BlurStyleOption styleOption;
8014      if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
8015          sheetStyle.backgroundBlurStyle = styleOption;
8016      }
8017      bool showClose = true;
8018      if (ParseJsBool(showCloseIcon, showClose)) {
8019          sheetStyle.showCloseIcon = showClose;
8020      } else if (!isPartialUpdate) {
8021          sheetStyle.showCloseIcon = true;
8022      }
8023  
8024      bool isInteractive = false;
8025      if (ParseJsBool(interactive, isInteractive)) {
8026          sheetStyle.interactive = isInteractive;
8027      }
8028  
8029      if (showDragBar->IsBoolean()) {
8030          sheetStyle.showDragBar = showDragBar->ToBoolean();
8031      } else if (isPartialUpdate) {
8032          sheetStyle.showDragBar.reset();
8033      } else {
8034          sheetStyle.showDragBar = true;
8035      }
8036  
8037      if (type->IsNull() || type->IsUndefined()) {
8038          sheetStyle.sheetType.reset();
8039      } else {
8040          if (type->IsNumber()) {
8041              auto sheetType = type->ToNumber<int32_t>();
8042              if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
8043                  sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
8044                  sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
8045              }
8046          }
8047      }
8048      if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
8049          sheetStyle.scrollSizeMode.reset();
8050      } else if (scrollSizeMode->IsNumber()) {
8051          auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
8052          if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
8053              sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
8054              sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
8055          }
8056      }
8057  
8058      if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
8059          sheetStyle.sheetKeyboardAvoidMode.reset();
8060      } else if (keyboardAvoidMode->IsNumber()) {
8061          auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
8062          if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
8063              sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
8064              sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
8065          }
8066      }
8067  
8068      Color color;
8069      if (ParseJsColor(backgroundColor, color)) {
8070          sheetStyle.backgroundColor = color;
8071      }
8072      // parse maskColor
8073      Color parseMaskColor;
8074      if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
8075          sheetStyle.maskColor = std::move(parseMaskColor);
8076      }
8077  
8078      // Parse border width
8079      auto borderWidthValue = paramObj->GetProperty("borderWidth");
8080      NG::BorderWidthProperty borderWidth;
8081      if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
8082          sheetStyle.borderWidth = borderWidth;
8083          // Parse border color
8084          auto colorValue = paramObj->GetProperty("borderColor");
8085          NG::BorderColorProperty borderColor;
8086          if (ParseBorderColorProps(colorValue, borderColor)) {
8087              sheetStyle.borderColor = borderColor;
8088          } else {
8089              sheetStyle.borderColor =
8090                  NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
8091          }
8092          // Parse border style
8093          auto styleValue = paramObj->GetProperty("borderStyle");
8094          NG::BorderStyleProperty borderStyle;
8095          if (ParseBorderStyleProps(styleValue, borderStyle)) {
8096              sheetStyle.borderStyle = borderStyle;
8097          } else {
8098              sheetStyle.borderStyle = NG::BorderStyleProperty(
8099                  { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
8100          }
8101      }
8102      if (isPartialUpdate) {
8103          auto colorValue = paramObj->GetProperty("borderColor");
8104          NG::BorderColorProperty borderColor;
8105          if (ParseBorderColorProps(colorValue, borderColor)) {
8106              sheetStyle.borderColor = borderColor;
8107          } else {
8108              sheetStyle.borderColor.reset();
8109          }
8110          auto styleValue = paramObj->GetProperty("borderStyle");
8111          NG::BorderStyleProperty borderStyle;
8112          if (ParseBorderStyleProps(styleValue, borderStyle)) {
8113              sheetStyle.borderStyle = borderStyle;
8114          } else {
8115              sheetStyle.borderStyle.reset();
8116          }
8117      }
8118  
8119      // Parse shadow
8120      Shadow shadow;
8121      auto shadowValue = paramObj->GetProperty("shadow");
8122      if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
8123          sheetStyle.shadow = shadow;
8124      }
8125  
8126      // Parse hoverMode
8127      auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
8128      if (enableHoverModeValue->IsBoolean()) {
8129          sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
8130      }
8131      auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
8132      if (hoverModeAreaValue->IsNumber()) {
8133          auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
8134          if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
8135              sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
8136          }
8137      }
8138  
8139      auto widthValue = paramObj->GetProperty("width");
8140      CalcDimension width;
8141      if (ParseJsDimensionVpNG(widthValue, width, true)) {
8142          sheetStyle.width = width;
8143      }
8144  
8145      CalcDimension sheetHeight;
8146      if (height->IsString()) {
8147          std::string heightStr = height->ToString();
8148          // Remove all " ".
8149          heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8150          std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8151          if (heightStr == SHEET_HEIGHT_MEDIUM) {
8152              sheetStyle.sheetMode = NG::SheetMode::MEDIUM;
8153              sheetStyle.height.reset();
8154              return;
8155          }
8156          if (heightStr == SHEET_HEIGHT_LARGE) {
8157              sheetStyle.sheetMode = NG::SheetMode::LARGE;
8158              sheetStyle.height.reset();
8159              return;
8160          }
8161          if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8162              sheetStyle.sheetMode = NG::SheetMode::AUTO;
8163              sheetStyle.height.reset();
8164              return;
8165          }
8166          if (heightStr.find("calc") != std::string::npos) {
8167              sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8168          } else {
8169              sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8170          }
8171          if (sheetHeight.Value() < 0) {
8172              sheetStyle.sheetMode = NG::SheetMode::LARGE;
8173              sheetStyle.height.reset();
8174              return;
8175          }
8176      }
8177      if (!ParseJsDimensionVpNG(height, sheetHeight)) {
8178          if (isPartialUpdate) {
8179              sheetStyle.sheetMode.reset();
8180          } else {
8181              sheetStyle.sheetMode = NG::SheetMode::LARGE;
8182          }
8183          sheetStyle.height.reset();
8184      } else {
8185          sheetStyle.height = sheetHeight;
8186          sheetStyle.sheetMode.reset();
8187      }
8188  }
8189  
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)8190  bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
8191  {
8192      if (!args->IsArray()) {
8193          return false;
8194      }
8195      JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
8196      NG::SheetHeight sheetDetent;
8197      for (size_t i = 0; i < array->Length(); i++) {
8198          ParseSheetDetentHeight(array->GetValueAt(i), sheetDetent);
8199          if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
8200              continue;
8201          }
8202          sheetDetents.emplace_back(sheetDetent);
8203          sheetDetent.height.reset();
8204          sheetDetent.sheetMode.reset();
8205      }
8206      return true;
8207  }
8208  
ParseSheetDetentHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent)8209  void JSViewAbstract::ParseSheetDetentHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent)
8210  {
8211      CalcDimension sheetHeight;
8212      if (args->IsString()) {
8213          std::string heightStr = args->ToString();
8214          // Remove all " ".
8215          heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8216          std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8217          if (heightStr == SHEET_HEIGHT_MEDIUM) {
8218              detent.sheetMode = NG::SheetMode::MEDIUM;
8219              detent.height.reset();
8220              return;
8221          }
8222          if (heightStr == SHEET_HEIGHT_LARGE) {
8223              detent.sheetMode = NG::SheetMode::LARGE;
8224              detent.height.reset();
8225              return;
8226          }
8227          if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8228              detent.sheetMode = NG::SheetMode::AUTO;
8229              detent.height.reset();
8230              return;
8231          }
8232          if (heightStr.find("calc") != std::string::npos) {
8233              sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8234          } else {
8235              sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8236          }
8237          if (sheetHeight.Value() < 0) {
8238              detent.sheetMode = NG::SheetMode::LARGE;
8239              detent.height.reset();
8240              return;
8241          }
8242      }
8243      if (!ParseJsDimensionVpNG(args, sheetHeight)) {
8244          detent.sheetMode = NG::SheetMode::LARGE;
8245          detent.height.reset();
8246      } else {
8247          detent.height = sheetHeight;
8248          detent.sheetMode.reset();
8249      }
8250  }
8251  
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)8252  bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
8253  {
8254      if (args->IsNumber()) {
8255          auto sheetBlurStyle = args->ToNumber<int32_t>();
8256          if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
8257              sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
8258              blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
8259          } else {
8260              return false;
8261          }
8262      } else {
8263          return false;
8264      }
8265      return true;
8266  }
8267  
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)8268  bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
8269  {
8270      if (!args->IsNumber()) {
8271          return false;
8272      }
8273      auto sheetMode = args->ToNumber<int32_t>();
8274      if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
8275          sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
8276          sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
8277          return true;
8278      }
8279      return false;
8280  }
8281  
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)8282  void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
8283      std::function<void(const float)>& callbackDidChange, const char* prop)
8284  {
8285      auto callBack = paramObj->GetProperty(prop);
8286      if (callBack->IsFunction()) {
8287          RefPtr<JsFunction> jsFunc =
8288              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
8289          callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
8290              JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
8291              func->ExecuteJS(1, &param);
8292          };
8293      }
8294  }
8295  
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)8296  void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
8297      std::function<void()>& lifeCycleCallBack, const char* prop)
8298  {
8299      auto callback = paramObj->GetProperty(prop);
8300      if (callback->IsFunction()) {
8301          RefPtr<JsFunction> jsFunc =
8302              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8303          lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
8304      }
8305  }
8306  
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)8307  void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
8308      std::function<void()>& sheetSpringBack, const char* prop)
8309  {
8310      auto sheetSpringBackCallback = paramObj->GetProperty(prop);
8311      if (sheetSpringBackCallback->IsFunction()) {
8312          RefPtr<JsFunction> jsFunc =
8313              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
8314          sheetSpringBack = [func = std::move(jsFunc)]() {
8315              JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8316              objectTemplate->SetInternalFieldCount(1);
8317              JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8318              dismissObj->SetPropertyObject(
8319                  "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
8320              JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8321              func->ExecuteJS(1, &newJSVal);
8322          };
8323      }
8324  }
8325  
ParseSheetCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & shouldDismiss,std::function<void (const int32_t info)> & onWillDismiss,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const float)> & onHeightDidChange,std::function<void (const float)> & onDetentsDidChange,std::function<void (const float)> & onWidthDidChange,std::function<void (const float)> & onTypeDidChange,std::function<void ()> & sheetSpringBack)8326  void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8327      std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
8328      std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
8329      std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
8330      std::function<void(const float)>& onDetentsDidChange,
8331      std::function<void(const float)>& onWidthDidChange,
8332      std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
8333  {
8334      auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
8335      auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8336      ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
8337      ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
8338      ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
8339      ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
8340      if (shouldDismissFunc->IsFunction()) {
8341          RefPtr<JsFunction> jsFunc =
8342              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
8343          shouldDismiss = [func = std::move(jsFunc)]() {
8344              JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8345              objectTemplate->SetInternalFieldCount(1);
8346              JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8347              dismissObj->SetPropertyObject(
8348                  "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8349              JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8350              func->ExecuteJS(1, &newJSVal);
8351          };
8352      }
8353      if (onWillDismissFunc->IsFunction()) {
8354          RefPtr<JsFunction> jsFunc =
8355              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8356          onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
8357              JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8358              objectTemplate->SetInternalFieldCount(1);
8359              JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8360              dismissObj->SetPropertyObject(
8361                  "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8362              dismissObj->SetProperty<int32_t>("reason", info);
8363              JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8364              func->ExecuteJS(1, &newJSVal);
8365          };
8366      }
8367      ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
8368      ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
8369      ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
8370      ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
8371      ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
8372  }
8373  
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)8374  void JSViewAbstract::ParseSheetTitle(
8375      const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
8376  {
8377      auto title = paramObj->GetProperty("title");
8378      std::string mainTitle;
8379      std::string subtitle;
8380      if (title->IsFunction()) {
8381          sheetStyle.isTitleBuilder = true;
8382          auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
8383          CHECK_NULL_VOID(titleBuilderFunc);
8384          titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
8385              ACE_SCORING_EVENT("BindSheet");
8386              func->Execute();
8387          };
8388      } else if (title->IsObject()) {
8389          JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
8390          sheetStyle.isTitleBuilder = false;
8391          auto sheetTitle = obj->GetProperty("title");
8392          auto sheetSubtitle = obj->GetProperty("subtitle");
8393          if (ParseJsString(sheetTitle, mainTitle)) {
8394              sheetStyle.sheetTitle = mainTitle;
8395          }
8396          if (ParseJsString(sheetSubtitle, subtitle)) {
8397              sheetStyle.sheetSubtitle = subtitle;
8398          }
8399      }
8400  }
8401  
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)8402  panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8403  {
8404      ViewAbstractModel::GetInstance()->DismissSheet();
8405      return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8406  }
8407  
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)8408  panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8409  {
8410      ViewAbstractModel::GetInstance()->DismissContentCover();
8411      return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8412  }
8413  
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)8414  panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8415  {
8416      ViewAbstractModel::GetInstance()->SheetSpringBack();
8417      return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8418  }
8419  
ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const int32_t & info)> & onWillDismiss)8420  void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8421      std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
8422      std::function<void(const int32_t& info)>& onWillDismiss)
8423  {
8424      auto showCallback = paramObj->GetProperty("onAppear");
8425      auto dismissCallback = paramObj->GetProperty("onDisappear");
8426      auto willShowCallback = paramObj->GetProperty("onWillAppear");
8427      auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
8428      auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8429      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8430      if (showCallback->IsFunction()) {
8431          RefPtr<JsFunction> jsFunc =
8432              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
8433          onAppear = [func = std::move(jsFunc), node = frameNode]() {
8434              PipelineContext::SetCallBackNode(node);
8435              func->Execute();
8436          };
8437      }
8438      if (dismissCallback->IsFunction()) {
8439          RefPtr<JsFunction> jsFunc =
8440              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
8441          onDisappear = [func = std::move(jsFunc), node = frameNode]() {
8442              PipelineContext::SetCallBackNode(node);
8443              func->Execute();
8444          };
8445      }
8446      if (willShowCallback->IsFunction()) {
8447          RefPtr<JsFunction> jsFunc =
8448              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
8449          onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
8450      }
8451      if (willDismissCallback->IsFunction()) {
8452          RefPtr<JsFunction> jsFunc =
8453              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
8454          onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
8455      }
8456      if (onWillDismissFunc->IsFunction()) {
8457          RefPtr<JsFunction> jsFunc =
8458              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8459          onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
8460              ACE_SCORING_EVENT("contentCover.dismiss");
8461              PipelineContext::SetCallBackNode(node);
8462              JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8463              objectTemplate->SetInternalFieldCount(1);
8464              JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8465              dismissObj->SetPropertyObject(
8466                  "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
8467              dismissObj->SetProperty<int32_t>("reason", info);
8468              JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8469              func->ExecuteJS(1, &newJSVal);
8470          };
8471      }
8472  }
8473  
JSCreateAnimatableProperty(const JSCallbackInfo & info)8474  void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
8475  {
8476      if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
8477          return;
8478      }
8479  
8480      JSRef<JSVal> callback = info[2]; /* 2:args index */
8481      if (!callback->IsFunction()) {
8482          return;
8483      }
8484      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8485      std::string propertyName = info[0]->ToString();
8486      if (info[1]->IsNumber()) {
8487          float numValue = info[1]->ToNumber<float>();
8488          std::function<void(float)> onCallbackEvent;
8489          RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8490          onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8491                                node = frameNode](const float val) {
8492              ContainerScope scope(id);
8493              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8494              auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
8495              PipelineContext::SetCallBackNode(node);
8496              func->ExecuteJS(1, &newJSVal);
8497          };
8498          ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
8499      } else if (info[1]->IsObject()) {
8500          JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8501          RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8502              AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8503          RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8504              AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8505          std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
8506          RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8507          onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8508                                node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
8509              ContainerScope scope(id);
8510              RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
8511              if (!impl) {
8512                  return;
8513              }
8514              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8515              auto newJSVal = JSRef<JSVal>(impl->GetObject());
8516              PipelineContext::SetCallBackNode(node);
8517              func->ExecuteJS(1, &newJSVal);
8518          };
8519          ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
8520              propertyName, animatableArithmetic, onCallbackEvent);
8521      }
8522  }
8523  
JSUpdateAnimatableProperty(const JSCallbackInfo & info)8524  void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
8525  {
8526      if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
8527          return;
8528      }
8529  
8530      std::string propertyName = info[0]->ToString();
8531      float numValue = 0.0;
8532      if (info[1]->IsNumber()) {
8533          numValue = info[1]->ToNumber<float>();
8534          ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
8535      } else if (info[1]->IsObject()) {
8536          JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8537          RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8538              AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8539          RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8540              AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8541          ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
8542      }
8543  }
8544  
JsExpandSafeArea(const JSCallbackInfo & info)8545  void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
8546  {
8547      NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
8548      if (info.Length() >= 1 && info[0]->IsArray()) {
8549          auto paramArray = JSRef<JSArray>::Cast(info[0]);
8550          uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
8551          for (size_t i = 0; i < paramArray->Length(); ++i) {
8552              if (!paramArray->GetValueAt(i)->IsNumber() ||
8553                  paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
8554                  safeAreaType = NG::SAFE_AREA_TYPE_ALL;
8555                  break;
8556              }
8557              safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8558          }
8559          opts.type = safeAreaType;
8560      }
8561      if (info.Length() >= 2 && info[1]->IsArray()) {
8562          auto paramArray = JSRef<JSArray>::Cast(info[1]);
8563          uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
8564          for (size_t i = 0; i < paramArray->Length(); ++i) {
8565              if (!paramArray->GetValueAt(i)->IsNumber() ||
8566                  paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
8567                  safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
8568                  break;
8569              }
8570              safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8571          }
8572          opts.edges = safeAreaEdge;
8573      }
8574  
8575      ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
8576  }
8577  
ParseJSLightSource(JSRef<JSObject> & lightSource)8578  void ParseJSLightSource(JSRef<JSObject>& lightSource)
8579  {
8580      if (lightSource->IsUndefined()) {
8581          return;
8582      }
8583      JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
8584      JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
8585      JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
8586      JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
8587      JSRef<JSVal> color = lightSource->GetProperty("color");
8588  
8589      CalcDimension dimPositionX;
8590      CalcDimension dimPositionY;
8591      CalcDimension dimPositionZ;
8592      if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
8593          JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
8594          JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
8595          ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
8596      }
8597  
8598      if (intensity->IsNumber()) {
8599          float intensityValue = intensity->ToNumber<float>();
8600          ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
8601      }
8602  
8603      Color lightColor;
8604      if (JSViewAbstract::ParseJsColor(color, lightColor)) {
8605          ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
8606      }
8607  }
8608  
JsPointLight(const JSCallbackInfo & info)8609  void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
8610  {
8611  #ifdef POINT_LIGHT_ENABLE
8612      if (!info[0]->IsObject()) {
8613          return;
8614      }
8615  
8616      JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
8617      JSRef<JSObject> lightSource = object->GetProperty("lightSource");
8618      ParseJSLightSource(lightSource);
8619  
8620      auto resourceWrapper = CreateResourceWrapper();
8621      if (!resourceWrapper) {
8622          return;
8623      }
8624      double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
8625      Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
8626      Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
8627  
8628      JSRef<JSVal> illuminated = object->GetProperty("illuminated");
8629      if (illuminated->IsNumber()) {
8630          uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
8631          ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
8632          ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
8633      }
8634  
8635      JSRef<JSVal> bloom = object->GetProperty("bloom");
8636      if (bloom->IsNumber()) {
8637          float bloomValue = bloom->ToNumber<float>();
8638          ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
8639  
8640          Shadow shadow;
8641          shadow.SetBlurRadius(bloomValue * bloomRadius);
8642          shadow.SetColor(bloomColor);
8643          std::vector<Shadow> shadows { shadow };
8644          ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8645      }
8646  #endif
8647  }
8648  
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)8649  void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
8650  {
8651      if (info[0]->IsBoolean()) {
8652          ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
8653      }
8654  }
8655  
JSBind(BindingTarget globalObj)8656  void JSViewAbstract::JSBind(BindingTarget globalObj)
8657  {
8658      JSClass<JSViewAbstract>::Declare("JSViewAbstract");
8659  
8660      // static methods
8661      MethodOptions opt = MethodOptions::NONE;
8662      JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
8663  
8664      JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
8665      JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
8666      JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
8667      JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
8668      JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
8669      JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
8670      JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
8671      JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound);
8672      JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
8673      JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSViewAbstract::JsChainWeight);
8674  
8675      JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
8676      JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
8677      JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
8678      JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
8679      JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
8680  
8681      JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
8682      JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
8683      JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
8684      JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
8685      JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
8686      JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
8687  
8688      JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
8689      JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
8690      JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
8691      JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
8692      JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
8693      JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
8694      JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
8695      JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
8696      JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
8697      JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
8698      JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
8699      JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
8700      JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
8701      JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
8702      JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
8703      JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
8704      JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
8705      JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
8706      JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
8707      JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
8708      JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
8709      JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
8710      JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
8711      JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
8712  
8713      JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
8714      JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
8715      JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
8716      JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
8717      JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
8718      JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
8719      JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
8720      JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
8721      JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
8722      JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
8723      JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
8724      JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
8725  
8726      JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
8727      JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
8728      JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
8729      JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
8730      JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
8731      JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
8732      JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
8733  
8734      JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
8735      JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
8736      JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
8737      JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
8738      JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
8739      JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
8740      JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
8741      JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
8742      JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal",
8743          &JSViewAbstract::JsBackgroundBrightnessInternal);
8744      JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
8745      JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
8746      JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
8747      JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
8748      JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
8749      JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
8750      JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
8751      JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
8752      JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
8753      JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
8754      JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
8755      JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
8756  #ifndef WEARABLE_PRODUCT
8757      JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
8758  #endif
8759  
8760      JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
8761      JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
8762      JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
8763      JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
8764      JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
8765      JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
8766      JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
8767      JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
8768      JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
8769      JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
8770      JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
8771      JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
8772      JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
8773      JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
8774  
8775      JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
8776      JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
8777      JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
8778      JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
8779      JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
8780      JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
8781      JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
8782      JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
8783      JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
8784      JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
8785      JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
8786      JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
8787      JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
8788      JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
8789      JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
8790      JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
8791      JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
8792      JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
8793      JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
8794      JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
8795      JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
8796      JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
8797      JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
8798      JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
8799      JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
8800      JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
8801      JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
8802      JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
8803      JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
8804      JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
8805      JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
8806      JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
8807      JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
8808      JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
8809      JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
8810      JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
8811      JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
8812      JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
8813      JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
8814      JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
8815      JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
8816      JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
8817      JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
8818      JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
8819      JSClass<JSViewAbstract>::StaticMethod(
8820          "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
8821      JSClass<JSViewAbstract>::StaticMethod(
8822          "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
8823      JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
8824      JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
8825      JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
8826      JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
8827      JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
8828      JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
8829      JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
8830  
8831      JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
8832      JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
8833      JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
8834      JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
8835      JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
8836      JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
8837      JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
8838      JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
8839      JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
8840  
8841      JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
8842      JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
8843      JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
8844      JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
8845      JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
8846      JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
8847      JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
8848      JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
8849      JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
8850      JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
8851      JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
8852  
8853      JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
8854      JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
8855      JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
8856      JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
8857  
8858      JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
8859  
8860      JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
8861  
8862      JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
8863      JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
8864      JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
8865  
8866      JSClass<JSViewAbstract>::StaticMethod(
8867          "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
8868  
8869      JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
8870      JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
8871  
8872      JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
8873      JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
8874      JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
8875      JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
8876  
8877      JSClass<JSViewAbstract>::Bind(globalObj);
8878  }
8879  
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)8880  void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
8881  {
8882      auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
8883          auto vm = info->GetVM();
8884          CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
8885          Local<JSValueRef> thisObj = info->GetFunctionRef();
8886          auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
8887          if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
8888              return panda::JSValueRef::Undefined(vm);
8889          }
8890  
8891          auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
8892          if (weak->Invalid()) {
8893              return panda::JSValueRef::Undefined(vm);
8894          }
8895  
8896          auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
8897          if (frameNode) {
8898              const auto& extensionHandler = frameNode->GetExtensionHandler();
8899              if (extensionHandler) {
8900                  extensionHandler->InvalidateRender();
8901              } else {
8902                  frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
8903              }
8904          }
8905  
8906          return panda::JSValueRef::Undefined(vm);
8907      };
8908      auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
8909      if (frameNode) {
8910          const auto& extensionHandler = frameNode->GetExtensionHandler();
8911          if (extensionHandler) {
8912              extensionHandler->InvalidateRender();
8913          } else {
8914              frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
8915          }
8916      }
8917      auto vm = jsInvalidate->GetEcmaVM();
8918      auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
8919      jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
8920      jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
8921      jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
8922  }
8923  
JsDrawModifier(const JSCallbackInfo & info)8924  void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
8925  {
8926      if (!info[0]->IsObject()) {
8927          return;
8928      }
8929  
8930      auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
8931      bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
8932      if (!IsSupportDrawModifier) {
8933          return;
8934      }
8935      auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
8936      RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
8937      auto execCtx = info.GetExecutionContext();
8938      auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
8939          JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
8940          if (!drawMethod->IsFunction()) {
8941              return nullptr;
8942          }
8943  
8944          auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
8945              JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
8946  
8947          return GetDrawCallback(jsDrawFunc, execCtx);
8948      };
8949  
8950      drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
8951      drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
8952      drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
8953  
8954      ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
8955      AddInvalidateFunc(jsDrawModifier, frameNode);
8956  }
8957  
JsAllowDrop(const JSCallbackInfo & info)8958  void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
8959  {
8960      std::set<std::string> allowDropSet;
8961      allowDropSet.clear();
8962      if (!info[0]->IsUndefined() && info[0]->IsArray()) {
8963          auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
8964          std::string allowDrop;
8965          for (size_t i = 0; i < allowDropArray->Length(); i++) {
8966              allowDrop = allowDropArray->GetValueAt(i)->ToString();
8967              allowDropSet.insert(allowDrop);
8968          }
8969          ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
8970      } else if (info[0]->IsNull()) {
8971          ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
8972      } else {
8973          ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
8974      }
8975      ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
8976  }
8977  
JsOnPreDrag(const JSCallbackInfo & info)8978  void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
8979  {
8980      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8981      auto jsVal = info[0];
8982      if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
8983          return;
8984      }
8985      RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8986      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8987      auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
8988                           const PreDragStatus preDragStatus) {
8989          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8990          ACE_SCORING_EVENT("onPreDrag");
8991          PipelineContext::SetCallBackNode(node);
8992          func->PreDragExecute(preDragStatus);
8993      };
8994      ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
8995  }
8996  
JsDragPreview(const JSCallbackInfo & info)8997  void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
8998  {
8999      auto jsVal = info[0];
9000      if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
9001          return;
9002      }
9003      NG::DragDropInfo dragPreviewInfo;
9004      JSRef<JSVal> builder;
9005      JSRef<JSVal> pixelMap;
9006      JSRef<JSVal> extraInfo;
9007      if (jsVal->IsFunction()) {
9008          builder = jsVal;
9009      } else if (jsVal->IsObject()) {
9010          auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
9011          builder = dragItemInfo->GetProperty("builder");
9012  #if defined(PIXEL_MAP_SUPPORTED)
9013          pixelMap = dragItemInfo->GetProperty("pixelMap");
9014          dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
9015  #endif
9016          extraInfo = dragItemInfo->GetProperty("extraInfo");
9017          ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
9018      } else if (jsVal->IsString()) {
9019          auto inspectorId = jsVal;
9020          ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
9021      } else {
9022          return;
9023      }
9024  
9025      if (builder->IsFunction()) {
9026          RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9027          if (builderFunc != nullptr) {
9028              ViewStackModel::GetInstance()->NewScope();
9029              {
9030                  ACE_SCORING_EVENT("dragPreview.builder");
9031                  builderFunc->Execute();
9032              }
9033              RefPtr<AceType> node = ViewStackModel::GetInstance()->Finish();
9034              dragPreviewInfo.customNode = AceType::DynamicCast<NG::UINode>(node);
9035          }
9036      }
9037      ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
9038  }
9039  
JsAlignRules(const JSCallbackInfo & info)9040  void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
9041  {
9042      if (!info[0]->IsObject()) {
9043          return;
9044      }
9045  
9046      JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
9047      if (valueObj->IsEmpty()) {
9048          return;
9049      }
9050      const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
9051      std::map<AlignDirection, AlignRule> alignRules;
9052      BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
9053      for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
9054          auto rule = valueObj->GetProperty(keys[i]);
9055          if (rule->IsObject()) {
9056              JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
9057              JSRef<JSVal> align = val->GetProperty("align");
9058              AlignRule alignRule;
9059              alignRule.anchor = val->GetProperty("anchor")->ToString();
9060              if (i < HORIZONTAL_DIRECTION_RANGE) {
9061                  alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9062              } else {
9063                  alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9064              }
9065              if (i < VERTICAL_DIRECTION_RANGE) {
9066                  alignRules[static_cast<AlignDirection>(i)] = alignRule;
9067              } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
9068                  alignRules[AlignDirection::LEFT] = alignRule;
9069              } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
9070                  alignRules[AlignDirection::RIGHT] = alignRule;
9071              }
9072              auto biasX = val->GetProperty("horizontal");
9073              if (biasX->IsNumber()) {
9074                  biasPair.first = biasX->ToNumber<float>();
9075              }
9076              auto biasY = val->GetProperty("vertical");
9077              if (biasY->IsNumber()) {
9078                  biasPair.second = biasY->ToNumber<float>();
9079              }
9080          }
9081      }
9082  
9083      ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
9084      ViewAbstractModel::GetInstance()->SetBias(biasPair);
9085  }
9086  
JsChainMode(const JSCallbackInfo & info)9087  void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
9088  {
9089      ChainInfo chainInfo;
9090      if (info.Length() >= 1) {
9091          auto tmpDirection = info[0];
9092          if (tmpDirection->IsUndefined()) {
9093              chainInfo.direction = std::nullopt;
9094          } else if (tmpDirection->IsNumber()) {
9095              auto direction = tmpDirection->ToNumber<int32_t>();
9096              chainInfo.direction = static_cast<LineDirection>(direction);
9097          }
9098      }
9099  
9100      if (info.Length() >= 2) { // 2 : two args
9101          auto tmpStyle = info[1];
9102          if (tmpStyle->IsUndefined()) {
9103              chainInfo.style = std::nullopt;
9104          } else if (tmpStyle->IsNumber()) {
9105              auto style = tmpStyle->ToNumber<int32_t>();
9106              chainInfo.style = static_cast<ChainStyle>(style);
9107          }
9108      }
9109      ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
9110  }
9111  
SetMarginTop(const JSCallbackInfo & info)9112  void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
9113  {
9114      CalcDimension value;
9115      if (!ParseJsDimensionVp(info[0], value)) {
9116          return;
9117      }
9118      ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
9119  }
9120  
SetMarginBottom(const JSCallbackInfo & info)9121  void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
9122  {
9123      CalcDimension value;
9124      if (!ParseJsDimensionVp(info[0], value)) {
9125          return;
9126      }
9127      ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
9128  }
9129  
SetMarginLeft(const JSCallbackInfo & info)9130  void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
9131  {
9132      CalcDimension value;
9133      if (!ParseJsDimensionVp(info[0], value)) {
9134          return;
9135      }
9136      ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
9137  }
9138  
SetMarginRight(const JSCallbackInfo & info)9139  void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
9140  {
9141      CalcDimension value;
9142      if (!ParseJsDimensionVp(info[0], value)) {
9143          return;
9144      }
9145      ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
9146  }
9147  
SetPaddingTop(const JSCallbackInfo & info)9148  void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
9149  {
9150      CalcDimension value;
9151      if (!ParseJsDimensionVp(info[0], value)) {
9152          return;
9153      }
9154      ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
9155  }
9156  
SetPaddingBottom(const JSCallbackInfo & info)9157  void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
9158  {
9159      CalcDimension value;
9160      if (!ParseJsDimensionVp(info[0], value)) {
9161          return;
9162      }
9163      ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
9164  }
9165  
SetPaddingLeft(const JSCallbackInfo & info)9166  void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
9167  {
9168      CalcDimension value;
9169      if (!ParseJsDimensionVp(info[0], value)) {
9170          return;
9171      }
9172      ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
9173  }
9174  
SetPaddingRight(const JSCallbackInfo & info)9175  void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
9176  {
9177      CalcDimension value;
9178      if (!ParseJsDimensionVp(info[0], value)) {
9179          return;
9180      }
9181      ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
9182  }
9183  
SetSafeAreaPadding(const JSCallbackInfo & info)9184  void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
9185  {
9186      ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
9187  }
9188  
SetColorBlend(Color color)9189  void JSViewAbstract::SetColorBlend(Color color)
9190  {
9191      ViewAbstractModel::GetInstance()->SetColorBlend(color);
9192  }
9193  
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)9194  void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
9195  {
9196      ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
9197  }
9198  
SetDynamicLightUp(float rate,float lightUpDegree)9199  void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
9200  {
9201      ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
9202  }
9203  
SetBgDynamicBrightness(BrightnessOption brightnessOption)9204  void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
9205  {
9206      ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
9207  }
9208  
SetFgDynamicBrightness(BrightnessOption brightnessOption)9209  void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
9210  {
9211      ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
9212  }
9213  
SetWindowBlur(float progress,WindowBlurStyle blurStyle)9214  void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
9215  {
9216      ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
9217  }
9218  
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)9219  bool JSViewAbstract::ParseJsonDimension(
9220      const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
9221  {
9222      if (!jsonValue || jsonValue->IsNull()) {
9223          return false;
9224      }
9225      if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9226          return false;
9227      }
9228      if (jsonValue->IsNumber()) {
9229          result = Dimension(jsonValue->GetDouble(), defaultUnit);
9230          return true;
9231      }
9232      if (jsonValue->IsString()) {
9233          if (checkIllegal) {
9234              return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
9235          }
9236          result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
9237          return true;
9238      }
9239      auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9240      auto resId = resVal->GetValue("id");
9241      if (!resId || !resId->IsNumber()) {
9242          return false;
9243      }
9244  
9245      auto resourceWrapper = CreateResourceWrapper();
9246      if (!resourceWrapper) {
9247          return false;
9248      }
9249      result = resourceWrapper->GetDimension(resId->GetUInt());
9250      return true;
9251  }
9252  
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)9253  bool JSViewAbstract::ParseJsonDimensionVp(
9254      const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
9255  {
9256      if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9257          return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
9258      }
9259      return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
9260  }
9261  
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)9262  bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
9263  {
9264      if (!jsonValue || jsonValue->IsNull()) {
9265          return false;
9266      }
9267      if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9268          return false;
9269      }
9270      if (jsonValue->IsNumber()) {
9271          result = jsonValue->GetDouble();
9272          return true;
9273      }
9274      if (jsonValue->IsString()) {
9275          result = StringUtils::StringToDouble(jsonValue->GetString());
9276          return true;
9277      }
9278      // parse json Resource
9279      auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9280      auto resId = resVal->GetValue("id");
9281      CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
9282      auto id = resId->GetUInt();
9283      auto resType = resVal->GetValue("type");
9284      CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
9285      auto type = resType->GetUInt();
9286  
9287      auto resourceWrapper = CreateResourceWrapper();
9288      if (!resourceWrapper) {
9289          return false;
9290      }
9291      if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9292          auto numberString = resourceWrapper->GetString(id);
9293          return StringUtils::StringToDouble(numberString, result);
9294      }
9295      if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9296          result = resourceWrapper->GetInt(id);
9297          return true;
9298      }
9299      if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9300          result = resourceWrapper->GetDouble(id);
9301          return true;
9302      }
9303      return false;
9304  }
9305  
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)9306  bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
9307  {
9308      if (!jsonValue || jsonValue->IsNull()) {
9309          return false;
9310      }
9311      if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9312          return false;
9313      }
9314      if (jsonValue->IsNumber()) {
9315          result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
9316          return true;
9317      }
9318  
9319      bool isSetColor = false;
9320      if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
9321          isSetColor = jsonValue->IsString();
9322      } else {
9323          isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
9324      }
9325      if (isSetColor) {
9326          result = Color::FromString(jsonValue->GetString());
9327          return true;
9328      }
9329      auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9330      auto resId = resVal->GetValue("id");
9331      if (!resId || !resId->IsNumber()) {
9332          return false;
9333      }
9334      auto resourceWrapper = CreateResourceWrapper();
9335      if (!resourceWrapper) {
9336          return false;
9337      }
9338      result = resourceWrapper->GetColor(resId->GetUInt());
9339      return true;
9340  }
9341  
ParseShadowOffsetX(const JSRef<JSObject> & jsObj,CalcDimension & offsetX,Shadow & shadow)9342  void JSViewAbstract::ParseShadowOffsetX(const JSRef<JSObject>& jsObj, CalcDimension& offsetX, Shadow& shadow)
9343  {
9344      auto jsOffsetX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_X));
9345      bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
9346      if (ParseJsResource(jsOffsetX, offsetX)) {
9347          double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9348          shadow.SetOffsetX(xValue);
9349      } else {
9350          if (ParseJsDimensionVp(jsOffsetX, offsetX)) {
9351              double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9352              shadow.SetOffsetX(xValue);
9353          }
9354      }
9355  }
9356  
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)9357  bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
9358  {
9359      int32_t shadowStyle = 0;
9360      if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
9361          auto style = static_cast<ShadowStyle>(shadowStyle);
9362          return GetShadowFromTheme(style, shadow);
9363      }
9364      if (!jsValue->IsObject()) {
9365          return false;
9366      }
9367      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9368      double radius = 0.0;
9369      ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
9370      if (LessNotEqual(radius, 0.0)) {
9371          radius = 0.0;
9372      }
9373      shadow.SetBlurRadius(radius);
9374      CalcDimension offsetX;
9375      ParseShadowOffsetX(jsObj, offsetX, shadow);
9376      CalcDimension offsetY;
9377      auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
9378      if (ParseJsResource(jsOffsetY, offsetY)) {
9379          shadow.SetOffsetY(offsetY.Value());
9380      } else {
9381          if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
9382              shadow.SetOffsetY(offsetY.Value());
9383          }
9384      }
9385      Color color;
9386      ShadowColorStrategy shadowColorStrategy;
9387      auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
9388      if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
9389          shadow.SetShadowColorStrategy(shadowColorStrategy);
9390      } else if (ParseJsColor(jsColor, color)) {
9391          shadow.SetColor(color);
9392      }
9393      int32_t type = static_cast<int32_t>(ShadowType::COLOR);
9394      JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
9395      if (type != static_cast<int32_t>(ShadowType::BLUR)) {
9396          type = static_cast<int32_t>(ShadowType::COLOR);
9397      }
9398      shadow.SetShadowType(static_cast<ShadowType>(type));
9399      bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
9400      shadow.SetIsFilled(isFilled);
9401      return true;
9402  }
9403  
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)9404  bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
9405  {
9406      auto colorMode = SystemProperties::GetColorMode();
9407      if (shadowStyle == ShadowStyle::None) {
9408          return true;
9409      }
9410  
9411      auto container = Container::Current();
9412      CHECK_NULL_RETURN(container, false);
9413      auto pipelineContext = container->GetPipelineContext();
9414      CHECK_NULL_RETURN(pipelineContext, false);
9415  
9416      auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
9417      if (!shadowTheme) {
9418          return false;
9419      }
9420  
9421      shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
9422      return true;
9423  }
9424  
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)9425  bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
9426  {
9427      if (!jsValue->IsObject()) {
9428          return false;
9429      }
9430      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9431      uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
9432      if (type == 0) {
9433          return false;
9434      }
9435      auto resourceWrapper = CreateResourceWrapper();
9436      CHECK_NULL_RETURN(resourceWrapper, false);
9437      if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9438          auto value = resourceWrapper->GetString(
9439              jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9440          return StringUtils::StringToCalcDimensionNG(value, result, false);
9441      }
9442      if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9443          auto value = std::to_string(
9444              resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
9445          StringUtils::StringToDimensionWithUnitNG(value, result);
9446          return true;
9447      }
9448  
9449      if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9450          result = resourceWrapper->GetDimension(
9451              jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9452          return true;
9453      }
9454      return false;
9455  }
9456  
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)9457  bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
9458  {
9459      JSRef<JSVal> arg = info[0];
9460      if (!arg->IsObject()) {
9461          return false;
9462      }
9463      JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
9464      JSRef<JSVal> typeValue = obj->GetProperty("types");
9465      if (!typeValue->IsArray()) {
9466          return false;
9467      }
9468      JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
9469      for (size_t i = 0; i < array->Length(); i++) {
9470          JSRef<JSVal> value = array->GetValueAt(i);
9471          auto index = value->ToNumber<int32_t>();
9472          if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
9473              return false;
9474          }
9475          if (i != 0) {
9476              textDetectConfig.types.append(",");
9477          }
9478          textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
9479      }
9480      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9481      JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
9482      if (resultCallback->IsFunction()) {
9483          auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
9484          textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
9485                         const std::string& result) {
9486              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9487              PipelineContext::SetCallBackNode(node);
9488              func->Execute(result);
9489          };
9490      }
9491  
9492      return ParseAIEntityColor(obj, textDetectConfig);
9493  }
9494  
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)9495  bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
9496  {
9497      JSRef<JSVal> entityColorValue = obj->GetProperty("color");
9498      ParseJsColor(entityColorValue, textDetectConfig.entityColor);
9499  
9500      JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
9501      if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
9502          textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9503          return true;
9504      }
9505      JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
9506      JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
9507      JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
9508      JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
9509  
9510      if (typeValue->IsNumber()) {
9511          textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
9512      } else {
9513          textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
9514      }
9515      if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
9516          textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9517      }
9518      if (styleValue->IsNumber()) {
9519           textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
9520      } else {
9521          textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
9522      }
9523  
9524      return true;
9525  }
9526  
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)9527  void JSViewAbstract::GetAngle(
9528      const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
9529  {
9530      auto value = jsonValue->GetValue(key);
9531      if (value && value->IsString()) {
9532          angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
9533      } else if (value && value->IsNumber()) {
9534          angle = static_cast<float>(value->GetDouble());
9535      }
9536  }
9537  
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)9538  void JSViewAbstract::GetJsAngle(
9539      int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
9540  {
9541      if (!jsValue->IsObject()) {
9542          return;
9543      }
9544      JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
9545      if (value->IsString()) {
9546          angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
9547      } else if (value->IsNumber()) {
9548          angle = value->ToNumber<float>();
9549      }
9550  }
9551  
9552  // if angle is not string or number, return directly. If angle is invalid string, use defaultValue.
GetJsAngleWithDefault(int32_t key,const JSRef<JSObject> & jsObj,std::optional<float> & angle,float defaultValue)9553  void JSViewAbstract::GetJsAngleWithDefault(
9554      int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
9555  {
9556      JSRef<JSVal> value = jsObj->GetProperty(key);
9557      if (value->IsString()) {
9558          double temp = 0.0;
9559          if (StringUtils::StringToDegree(value->ToString(), temp)) {
9560              angle = static_cast<float>(temp);
9561          } else {
9562              angle = defaultValue;
9563          }
9564      } else if (value->IsNumber()) {
9565          angle = value->ToNumber<float>();
9566      }
9567  }
9568  
CheckAngle(std::optional<float> & angle)9569  inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
9570  {
9571      angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
9572  }
9573  
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)9574  void JSViewAbstract::GetPerspective(
9575      const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
9576  {
9577      auto value = jsonValue->GetValue(key);
9578      if (value && value->IsNumber()) {
9579          perspective = static_cast<float>(value->GetDouble());
9580      }
9581  }
9582  
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)9583  void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
9584  {
9585      auto value = jsValue->GetProperty(key);
9586      if (value->IsNumber()) {
9587          perspective = value->ToNumber<float>();
9588      }
9589  }
9590  
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9591  void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9592  {
9593      if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9594          return;
9595      }
9596  
9597      for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9598          GradientColor gradientColor;
9599          auto item = colorStops->GetArrayItem(i);
9600          if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9601              auto colorParams = item->GetArrayItem(0);
9602              // color
9603              Color color;
9604              if (!ParseJsonColor(colorParams, color)) {
9605                  continue;
9606              }
9607              gradientColor.SetColor(color);
9608              gradientColor.SetHasValue(false);
9609              // stop value
9610              if (item->GetArraySize() <= 1) {
9611                  continue;
9612              }
9613              auto stopValue = item->GetArrayItem(1);
9614              double value = 0.0;
9615              if (ParseJsonDouble(stopValue, value)) {
9616                  value = std::clamp(value, 0.0, 1.0);
9617                  gradientColor.SetHasValue(true);
9618                  gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9619              }
9620              gradient.AddColor(gradientColor);
9621          }
9622      }
9623  }
9624  
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9625  void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9626  {
9627      if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9628          return;
9629      }
9630  
9631      for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9632          NG::GradientColor gradientColor;
9633          auto item = colorStops->GetArrayItem(i);
9634          if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9635              auto colorParams = item->GetArrayItem(0);
9636              // color
9637              Color color;
9638              if (!ParseJsonColor(colorParams, color)) {
9639                  continue;
9640              }
9641              gradientColor.SetColor(color);
9642              gradientColor.SetHasValue(false);
9643              // stop value
9644              if (item->GetArraySize() <= 1) {
9645                  continue;
9646              }
9647              auto stopValue = item->GetArrayItem(1);
9648              double value = 0.0;
9649              if (ParseJsonDouble(stopValue, value)) {
9650                  value = std::clamp(value, 0.0, 1.0);
9651                  gradientColor.SetHasValue(true);
9652                  //  [0, 1] -> [0, 100.0];
9653                  gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9654              }
9655              gradient.AddColor(gradientColor);
9656          }
9657      }
9658  }
9659  
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)9660  void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
9661  {
9662      if (!colorStops->IsArray()) {
9663          return;
9664      }
9665  
9666      JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
9667      size_t length = jsArray->Length();
9668      for (size_t i = 0; i < length; i++) {
9669          NG::GradientColor gradientColor;
9670          JSRef<JSVal> item = jsArray->GetValueAt(i);
9671          if (!item->IsArray()) {
9672              continue;
9673          }
9674          JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
9675          if (subArray->Length() < 2) {
9676              continue;
9677          }
9678          // color
9679          Color color;
9680          if (!ParseJsColor(subArray->GetValueAt(0), color)) {
9681              continue;
9682          }
9683          gradientColor.SetColor(color);
9684          gradientColor.SetHasValue(false);
9685          // stop value
9686          double value = 0.0;
9687          if (ParseJsDouble(subArray->GetValueAt(1), value)) {
9688              value = std::clamp(value, 0.0, 1.0);
9689              gradientColor.SetHasValue(true);
9690          }
9691          //  [0, 1] -> [0, 100.0];
9692          gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9693          gradient.AddColor(gradientColor);
9694      }
9695  }
9696  
SetDirection(const std::string & dir)9697  void JSViewAbstract::SetDirection(const std::string& dir)
9698  {
9699      TextDirection direction = TextDirection::AUTO;
9700      if (dir == "Ltr") {
9701          direction = TextDirection::LTR;
9702      } else if (dir == "Rtl") {
9703          direction = TextDirection::RTL;
9704      } else if (dir == "Auto") {
9705          direction = TextDirection::AUTO;
9706      } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9707          direction = TextDirection::AUTO;
9708      }
9709      ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
9710  }
9711  
GetThemeConstants(const JSRef<JSObject> & jsObj)9712  RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
9713  {
9714      std::string bundleName;
9715      std::string moduleName;
9716      if (!jsObj->IsUndefined()) {
9717          JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
9718          JSRef<JSVal> module = jsObj->GetProperty("moduleName");
9719          if (bundle->IsString() && module->IsString()) {
9720              bundleName = bundle->ToString();
9721              moduleName = module->ToString();
9722          }
9723      }
9724  
9725      auto cardId = CardScope::CurrentId();
9726      if (cardId != INVALID_CARD_ID) {
9727          auto container = Container::Current();
9728          auto weak = container->GetCardPipeline(cardId);
9729          auto cardPipelineContext = weak.Upgrade();
9730          CHECK_NULL_RETURN(cardPipelineContext, nullptr);
9731          auto cardThemeManager = cardPipelineContext->GetThemeManager();
9732          CHECK_NULL_RETURN(cardThemeManager, nullptr);
9733          return cardThemeManager->GetThemeConstants(bundleName, moduleName);
9734      }
9735  
9736  #ifdef PLUGIN_COMPONENT_SUPPORTED
9737      if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
9738          auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
9739          if (!pluginContainer) {
9740              return nullptr;
9741          }
9742          auto pluginPipelineContext = pluginContainer->GetPipelineContext();
9743          if (!pluginPipelineContext) {
9744              return nullptr;
9745          }
9746          auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
9747          if (!pluginThemeManager) {
9748              return nullptr;
9749          }
9750          return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
9751      }
9752  #endif
9753      auto container = Container::Current();
9754      CHECK_NULL_RETURN(container, nullptr);
9755      auto pipelineContext = container->GetPipelineContext();
9756      CHECK_NULL_RETURN(pipelineContext, nullptr);
9757      auto themeManager = pipelineContext->GetThemeManager();
9758      CHECK_NULL_RETURN(themeManager, nullptr);
9759      return themeManager->GetThemeConstants(bundleName, moduleName);
9760  }
9761  
JsHoverEffect(const JSCallbackInfo & info)9762  void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
9763  {
9764      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
9765      auto jsVal = info[0];
9766      if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
9767          ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
9768          return;
9769      }
9770      if (!jsVal->IsNumber()) {
9771          return;
9772      }
9773      ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
9774  }
9775  
JsOnMouse(const JSCallbackInfo & info)9776  void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
9777  {
9778      if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9779          ViewAbstractModel::GetInstance()->DisableOnMouse();
9780          return;
9781      }
9782      if (!info[0]->IsFunction()) {
9783          return;
9784      }
9785  
9786      RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
9787      WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9788      auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
9789                         MouseInfo& mouseInfo) {
9790          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9791          ACE_SCORING_EVENT("onMouse");
9792          PipelineContext::SetCallBackNode(node);
9793          func->Execute(mouseInfo);
9794      };
9795      ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
9796  }
9797  
JsOnHover(const JSCallbackInfo & info)9798  void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
9799  {
9800      if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9801          ViewAbstractModel::GetInstance()->DisableOnHover();
9802          return;
9803      }
9804      if (!info[0]->IsFunction()) {
9805          return;
9806      }
9807  
9808      RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
9809      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9810      auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
9811                         bool isHover, HoverInfo& hoverInfo) {
9812          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9813          ACE_SCORING_EVENT("onHover");
9814          PipelineContext::SetCallBackNode(node);
9815          func->HoverExecute(isHover, hoverInfo);
9816      };
9817      ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
9818  }
9819  
JsOnAccessibilityHover(const JSCallbackInfo & info)9820  void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
9821  {
9822      if (info[0]->IsUndefined()) {
9823          ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
9824          return;
9825      }
9826      if (!info[0]->IsFunction()) {
9827          return;
9828      }
9829  
9830      RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
9831      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9832      auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
9833                                      node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
9834          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9835          ACE_SCORING_EVENT("onAccessibilityHover");
9836          PipelineContext::SetCallBackNode(node);
9837          func->AccessibilityHoverExecute(isHover, hoverInfo);
9838      };
9839      ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
9840  }
9841  
JsOnClick(const JSCallbackInfo & info)9842  void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
9843  {
9844      auto arg = info[0];
9845      if (arg->IsUndefined() && IsDisableEventVersion()) {
9846          ViewAbstractModel::GetInstance()->DisableOnClick();
9847          return;
9848      }
9849      if (!arg->IsFunction()) {
9850          return;
9851      }
9852  
9853      auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
9854      WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9855      auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
9856                       BaseEventInfo* info) {
9857          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9858          auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
9859          ACE_SCORING_EVENT("onClick");
9860          PipelineContext::SetCallBackNode(node);
9861          func->Execute(*tapInfo);
9862  #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
9863          JSInteractableView::ReportClickEvent(node);
9864  #endif
9865      };
9866      auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
9867      auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
9868                         const ClickInfo* info) {
9869          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9870          ACE_SCORING_EVENT("onClick");
9871          PipelineContext::SetCallBackNode(node);
9872          func->Execute(*info);
9873  #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
9874          JSInteractableView::ReportClickEvent(node);
9875  #endif
9876      };
9877  
9878      double distanceThreshold = std::numeric_limits<double>::infinity();
9879      if (info.Length() > 1 && info[1]->IsNumber()) {
9880          distanceThreshold = info[1]->ToNumber<double>();
9881          if (distanceThreshold < 0) {
9882              distanceThreshold = std::numeric_limits<double>::infinity();
9883          }
9884      }
9885      distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
9886      ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
9887  }
9888  
JsOnGestureJudgeBegin(const JSCallbackInfo & info)9889  void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
9890  {
9891      if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9892          ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
9893          return;
9894      }
9895  
9896      auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
9897      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9898      auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
9899                                    const RefPtr<NG::GestureInfo>& gestureInfo,
9900                                    const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
9901          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
9902          ACE_SCORING_EVENT("onGestureJudgeBegin");
9903          return func->Execute(gestureInfo, info);
9904      };
9905      ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
9906  }
9907  
JsOnTouchIntercept(const JSCallbackInfo & info)9908  void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
9909  {
9910      if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9911          ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
9912          return;
9913      }
9914  
9915      auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
9916      auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9917      auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
9918                                      TouchEventInfo& info) -> NG::HitTestMode {
9919          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
9920          ACE_SCORING_EVENT("onTouchIntercept");
9921          PipelineContext::SetCallBackNode(node);
9922          return func->Execute(info);
9923      };
9924      ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
9925  }
9926  
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)9927  void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
9928  {
9929      if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9930          ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
9931          return;
9932      }
9933  
9934      auto jsParallelInnerGestureToFunc =
9935          AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
9936      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9937      auto shouldBuiltInRecognizerParallelWithFunc =
9938          [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
9939              const RefPtr<NG::NGGestureRecognizer>& current,
9940              const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
9941          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9942          ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
9943          PipelineContext::SetCallBackNode(node);
9944          return func->Execute(current, others);
9945      };
9946      ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
9947          std::move(shouldBuiltInRecognizerParallelWithFunc));
9948  }
9949  
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)9950  void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
9951  {
9952      if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9953          ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
9954          return;
9955      }
9956  
9957      auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
9958      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9959      auto onGestureRecognizerJudgefunc =
9960          [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
9961              const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
9962              const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
9963          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
9964          ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
9965          PipelineContext::SetCallBackNode(node);
9966          return func->Execute(info, current, others);
9967      };
9968  
9969      bool exposeInnerGestureFlag = false;
9970      if (info.Length() > 1 && info[1]->IsBoolean()) {
9971          exposeInnerGestureFlag = info[1]->ToBoolean();
9972      }
9973      ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
9974          std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
9975  }
9976  
JsClickEffect(const JSCallbackInfo & info)9977  void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
9978  {
9979      JSRef<JSVal> arg = info[0];
9980      if (arg->IsUndefined() || arg->IsNull()) {
9981          ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
9982          return;
9983      }
9984      if (!arg->IsObject()) {
9985          return;
9986      }
9987      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
9988      JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
9989      int32_t clickEffectLevelValue = 0;
9990      if (clickEffectLevel->IsNumber()) {
9991          clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
9992          if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
9993              clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
9994              clickEffectLevelValue = 0;
9995          }
9996      }
9997  
9998      JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
9999      float scaleNumberValue = DEFAULT_SCALE_LIGHT;
10000      if (!scaleNumber->IsNumber()) {
10001          if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10002              (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10003              scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10004          }
10005          ViewAbstractModel::GetInstance()->SetClickEffectLevel(
10006              (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10007          return;
10008      }
10009  
10010      scaleNumberValue = scaleNumber->ToNumber<float>();
10011      if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
10012          if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10013              (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10014              scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10015          } else {
10016              scaleNumberValue = DEFAULT_SCALE_LIGHT;
10017          }
10018      }
10019  
10020      ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10021  }
10022  
JsOnVisibleAreaChange(const JSCallbackInfo & info)10023  void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
10024  {
10025      if (info.Length() != 2) {
10026          return;
10027      }
10028  
10029      if (!info[0]->IsArray() || !info[1]->IsFunction()) {
10030          return;
10031      }
10032  
10033      auto ratioArray = JSRef<JSArray>::Cast(info[0]);
10034      size_t size = ratioArray->Length();
10035      std::vector<double> ratioVec(size);
10036      ratioVec.clear();
10037      for (size_t i = 0; i < size; i++) {
10038          double ratio = 0.0;
10039          ParseJsDouble(ratioArray->GetValueAt(i), ratio);
10040          if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
10041              ratio = VISIBLE_RATIO_MIN;
10042          }
10043  
10044          if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
10045              ratio = VISIBLE_RATIO_MAX;
10046          }
10047          ratioVec.push_back(ratio);
10048      }
10049  
10050      RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
10051      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10052      auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
10053                                 bool visible, double ratio) {
10054          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10055          ACE_SCORING_EVENT("onVisibleAreaChange");
10056  
10057          JSRef<JSVal> params[2];
10058          params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
10059          params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
10060          PipelineContext::SetCallBackNode(node);
10061          func->ExecuteJS(2, params);
10062      };
10063      ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
10064  }
10065  
JsHitTestBehavior(const JSCallbackInfo & info)10066  void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
10067  {
10068      if (info.Length() != 1 || !info[0]->IsNumber()) {
10069          return;
10070      }
10071  
10072      NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
10073      hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
10074      ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
10075  }
10076  
JsOnChildTouchTest(const JSCallbackInfo & info)10077  void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
10078  {
10079      static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
10080      auto jsVal = info[0];
10081      if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
10082          return;
10083      }
10084  
10085      RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
10086          AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
10087  
10088      auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
10089                                 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
10090          NG::TouchResult touchRes;
10091          NG::TouchResult defaultRes;
10092          defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
10093          defaultRes.id = "";
10094          auto ret = func->Execute(touchInfo);
10095          if (!ret->IsObject()) {
10096              TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
10097              return defaultRes;
10098          }
10099  
10100          auto retObj = JSRef<JSObject>::Cast(ret);
10101          auto strategy = retObj->GetProperty("strategy");
10102          if (!strategy->IsNumber()) {
10103              TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
10104              return defaultRes;
10105          }
10106          touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
10107          auto id = retObj->GetProperty("id");
10108          if (!id->IsString()) {
10109              TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
10110              return defaultRes;
10111          }
10112          touchRes.id = id->ToString();
10113          return touchRes;
10114      };
10115      ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
10116  }
10117  
JsForegroundColor(const JSCallbackInfo & info)10118  void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
10119  {
10120      Color foregroundColor = Color::TRANSPARENT;
10121      ForegroundColorStrategy strategy;
10122      if (ParseJsColorStrategy(info[0], strategy)) {
10123          ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
10124          return;
10125      }
10126      ParseJsColor(info[0], foregroundColor);
10127      ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
10128  }
10129  
JsKeyboardShortcut(const JSCallbackInfo & info)10130  void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
10131  {
10132      // KeyboardShortcut only allows 2 or 3 params.
10133      if (info.Length() < 2 || info.Length() > 3) {
10134          return;
10135      }
10136      if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
10137          // clear shortcut key
10138          ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10139          return;
10140      }
10141  
10142      std::string value;
10143      if (info[0]->IsString()) {
10144          // common letter/number/symbol
10145          value = info[0]->ToString();
10146          if (value.size() != 1) {
10147              // clear shortcut key
10148              ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10149              return;
10150          }
10151      } else {
10152          // function keys such as F1-F10/ESC
10153          FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
10154          value = GetFunctionKeyName(functionkey);
10155      }
10156  
10157      auto keysArray = JSRef<JSArray>::Cast(info[1]);
10158      size_t size = keysArray->Length();
10159      std::vector<ModifierKey> keys(size);
10160      keys.clear();
10161      for (size_t i = 0; i < size; i++) {
10162          JSRef<JSVal> key = keysArray->GetValueAt(i);
10163          if (key->IsNumber()) {
10164              keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
10165          }
10166      }
10167  
10168      // KeyboardShortcut allows 3 params, the third param is function callback.
10169      if (info.Length() == 3 && info[2]->IsFunction()) {
10170          RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
10171          auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10172          auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10173                                              node = frameNode]() {
10174              JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10175              ACE_SCORING_EVENT("onKeyboardShortcutAction");
10176              PipelineContext::SetCallBackNode(node);
10177              func->ExecuteJS();
10178          };
10179          ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
10180          return;
10181      }
10182      ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
10183  }
10184  
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)10185  bool JSViewAbstract::CheckColor(
10186      const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
10187  {
10188      // Color is undefined or null
10189      if (jsValue->IsUndefined() || jsValue->IsNull()) {
10190          return false;
10191      }
10192      // input type is not in [number, string, Resource]
10193      if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10194          return false;
10195      }
10196      // Correct type, incorrect value parsing
10197      if (!ParseJsColor(jsValue, result)) {
10198          return false;
10199      }
10200      return true;
10201  }
10202  
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)10203  bool JSViewAbstract::CheckLength(
10204      const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
10205  {
10206      // Length is undefined or null
10207      if (jsValue->IsUndefined() || jsValue->IsNull()) {
10208          return false;
10209      }
10210      // input type is not in [number, string, Resource]
10211      if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10212          return false;
10213      }
10214      if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10215          return ParseJsDimensionVpNG(jsValue, result);
10216      }
10217      // Correct type, incorrect value parsing
10218      if (!ParseJsDimensionVp(jsValue, result)) {
10219          return false;
10220      }
10221      return true;
10222  }
10223  
10224  // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)10225  void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
10226  {
10227      JSRef<JSVal> arg = info[0];
10228      if (arg->IsUndefined() || arg->IsNull()) {
10229          std::vector<ObscuredReasons> reasons(0);
10230          ViewAbstractModel::GetInstance()->SetObscured(reasons);
10231          return;
10232      }
10233      if (!arg->IsArray()) {
10234          return;
10235      }
10236  
10237      auto obscuredArray = JSRef<JSArray>::Cast(arg);
10238      size_t size = obscuredArray->Length();
10239      std::vector<ObscuredReasons> reasons(size);
10240      reasons.clear();
10241      for (size_t i = 0; i < size; i++) {
10242          JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
10243          if (reason->IsNumber()) {
10244              reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
10245          }
10246      }
10247  
10248      ViewAbstractModel::GetInstance()->SetObscured(reasons);
10249  }
10250  
10251  // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)10252  void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
10253  {
10254      auto sensitiveInfo = info[0];
10255      if (sensitiveInfo->IsUndefined()) {
10256          ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
10257          return;
10258      }
10259      bool sensitive = false;
10260      if (sensitiveInfo->IsBoolean()) {
10261          sensitive = sensitiveInfo->ToBoolean();
10262      }
10263      ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
10264  }
10265  
JSRenderGroup(const JSCallbackInfo & info)10266  void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
10267  {
10268      if (info.Length() != 1) {
10269          return;
10270      }
10271      bool isRenderGroup = false;
10272      if (info[0]->IsBoolean()) {
10273          isRenderGroup = info[0]->ToBoolean();
10274      }
10275      ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
10276  }
10277  
JSRenderFit(const JSCallbackInfo & info)10278  void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
10279  {
10280      if (info.Length() != 1) {
10281          return;
10282      }
10283      RenderFit renderFit = RenderFit::TOP_LEFT;
10284      if (info[0]->IsNumber()) {
10285          int32_t fitNumber = info[0]->ToNumber<int32_t>();
10286          if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
10287              fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
10288              renderFit = static_cast<RenderFit>(fitNumber);
10289          }
10290      }
10291      // how content fills the node duration implicit animation
10292      ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
10293  }
10294  
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)10295  bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
10296  {
10297      if (!jsValue->IsObject() || jsValue->IsString()) {
10298          return false;
10299      }
10300      JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10301      if (!jsObj->IsUndefined()) {
10302          JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
10303          JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
10304          if (bundle->IsString() && module->IsString()) {
10305              bundleName = bundle->ToString();
10306              moduleName = module->ToString();
10307              return true;
10308          }
10309      }
10310      return false;
10311  }
10312  
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)10313  std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
10314      const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
10315  {
10316      std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx](
10317                                                                           NG::DrawingContext& context) -> void {
10318          JAVASCRIPT_EXECUTION_SCOPE(execCtx);
10319  
10320          JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
10321          objectTemplate->SetInternalFieldCount(1);
10322          JSRef<JSObject> contextObj = objectTemplate->NewInstance();
10323          JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
10324          sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
10325          sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
10326          contextObj->SetPropertyObject("size", sizeObj);
10327  
10328          JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
10329          sizeInPxObj->SetProperty<float>("height", context.height);
10330          sizeInPxObj->SetProperty<float>("width", context.width);
10331          contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
10332  
10333          auto engine = EngineHelper::GetCurrentEngine();
10334          CHECK_NULL_VOID(engine);
10335          NativeEngine* nativeEngine = engine->GetNativeEngine();
10336          napi_env env = reinterpret_cast<napi_env>(nativeEngine);
10337          ScopeRAII scope(env);
10338  
10339          auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
10340          OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
10341          napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
10342          if (unwrapCanvas) {
10343              unwrapCanvas->SaveCanvas();
10344              unwrapCanvas->ClipCanvas(context.width, context.height);
10345          }
10346          JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
10347          contextObj->SetPropertyObject("canvas", jsCanvasVal);
10348  
10349          auto jsVal = JSRef<JSVal>::Cast(contextObj);
10350          panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
10351          JSValueWrapper valueWrapper = value;
10352          napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
10353  
10354          napi_wrap(
10355              env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
10356  
10357          JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
10358          if (unwrapCanvas) {
10359              unwrapCanvas->RestoreCanvas();
10360              unwrapCanvas->ResetCanvas();
10361          }
10362      };
10363      return drawCallback;
10364  }
10365  
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)10366  bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
10367  {
10368      if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10369          return false;
10370      }
10371      Color borderColor;
10372      if (ParseJsColor(args, borderColor)) {
10373          colorProperty.SetColor(borderColor);
10374          return true;
10375      } else if (args->IsObject()) {
10376          JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10377          CommonColor commonColor;
10378          ParseCommonEdgeColors(obj, commonColor);
10379          colorProperty.topColor = commonColor.top;
10380          colorProperty.bottomColor = commonColor.bottom;
10381          colorProperty.leftColor = commonColor.left;
10382          colorProperty.rightColor = commonColor.right;
10383          colorProperty.multiValued = true;
10384          return true;
10385      }
10386      return false;
10387  }
10388  
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)10389  bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
10390  {
10391      if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10392          return false;
10393      }
10394      CalcDimension borderWidth;
10395      if (ParseJsDimensionVpNG(args, borderWidth, true)) {
10396          if (borderWidth.IsNegative()) {
10397              borderWidth.Reset();
10398          }
10399          borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth });
10400          return true;
10401      } else if (args->IsObject()) {
10402          JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10403          CommonCalcDimension commonCalcDimension;
10404          ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
10405          borderWidthProperty.topDimen = commonCalcDimension.top;
10406          borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
10407          borderWidthProperty.leftDimen = commonCalcDimension.left;
10408          borderWidthProperty.rightDimen = commonCalcDimension.right;
10409          borderWidthProperty.multiValued = true;
10410          return true;
10411      }
10412      return false;
10413  }
10414  
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)10415  bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
10416  {
10417      if (!args->IsObject() && !args->IsNumber()) {
10418          return false;
10419      }
10420      if (args->IsObject()) {
10421          JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10422          auto leftValue = obj->GetProperty("left");
10423          if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
10424              ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
10425          }
10426          auto rightValue = obj->GetProperty("right");
10427          if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
10428              ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
10429          }
10430          auto topValue = obj->GetProperty("top");
10431          if (!topValue->IsUndefined() && topValue->IsNumber()) {
10432              ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
10433          }
10434          auto bottomValue = obj->GetProperty("bottom");
10435          if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
10436              ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
10437          }
10438          borderStyleProperty.multiValued = true;
10439          return true;
10440      }
10441      std::optional<BorderStyle> borderStyle;
10442      if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
10443          borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
10444          return true;
10445      }
10446      return false;
10447  }
10448  
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10449  void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10450  {
10451      std::optional<CalcDimension> radiusTopLeft;
10452      std::optional<CalcDimension> radiusTopRight;
10453      std::optional<CalcDimension> radiusBottomLeft;
10454      std::optional<CalcDimension> radiusBottomRight;
10455      CalcDimension topLeft;
10456      if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
10457          radiusTopLeft = topLeft;
10458      }
10459      CalcDimension topRight;
10460      if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
10461          radiusTopRight = topRight;
10462      }
10463      CalcDimension bottomLeft;
10464      if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
10465          radiusBottomLeft = bottomLeft;
10466      }
10467      CalcDimension bottomRight;
10468      if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
10469          radiusBottomRight = bottomRight;
10470      }
10471      CheckLengthMetrics(object);
10472      radius.radiusTopLeft = radiusTopLeft;
10473      radius.radiusTopRight = radiusTopRight;
10474      radius.radiusBottomLeft = radiusBottomLeft;
10475      radius.radiusBottomRight = radiusBottomRight;
10476      radius.multiValued = true;
10477      return;
10478  }
10479  
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10480  void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10481  {
10482      if (CheckLengthMetrics(object)) {
10483          std::optional<CalcDimension> radiusTopStart;
10484          std::optional<CalcDimension> radiusTopEnd;
10485          std::optional<CalcDimension> radiusBottomStart;
10486          std::optional<CalcDimension> radiusBottomEnd;
10487          if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
10488              JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
10489              CalcDimension calcDimension;
10490              if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
10491                  CheckDimensionUnit(calcDimension, false, true);
10492                  radiusTopStart = calcDimension;
10493              }
10494          }
10495          if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
10496              JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
10497              CalcDimension calcDimension;
10498              if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
10499                  CheckDimensionUnit(calcDimension, false, true);
10500                  radiusTopEnd = calcDimension;
10501              }
10502          }
10503          if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
10504              JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
10505              CalcDimension calcDimension;
10506              if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
10507                  CheckDimensionUnit(calcDimension, false, true);
10508                  radiusBottomStart = calcDimension;
10509              }
10510          }
10511          if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
10512              JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
10513              CalcDimension calcDimension;
10514              if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
10515                  CheckDimensionUnit(calcDimension, false, true);
10516                  radiusBottomEnd = calcDimension;
10517              }
10518          }
10519          auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
10520          radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
10521          radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
10522          radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
10523          radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
10524          radius.multiValued = true;
10525          return;
10526      }
10527      ParseBorderRadiusProps(object, radius);
10528  }
10529  
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)10530  bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
10531  {
10532      if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10533          return false;
10534      }
10535      CalcDimension borderRadius;
10536      if (ParseJsDimensionVpNG(args, borderRadius, true)) {
10537          radius = NG::BorderRadiusProperty(borderRadius);
10538          radius.multiValued = false;
10539      } else if (args->IsObject()) {
10540          JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
10541          ParseCommonBorderRadiusProps(object, radius);
10542      } else {
10543          return false;
10544      }
10545      return true;
10546  }
10547  
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)10548  void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10549  {
10550      JSRef<JSVal> arg = info[0];
10551      if (!arg->IsObject()) {
10552          return;
10553      }
10554      JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10555      auto vm = info.GetVm();
10556      auto globalObj = JSNApi::GetGlobalObject(vm);
10557      auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
10558      JsiValue jsiValue(globalFunc);
10559      JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10560      if (globalFuncRef->IsFunction()) {
10561          auto modifierObj = obj->GetProperty("modifier");
10562          if (modifierObj->IsUndefined()) {
10563              option.onApply = nullptr;
10564          } else {
10565              RefPtr<JsFunction> jsFunc =
10566                  AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10567              auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10568                                 modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10569                  JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10570                  auto node = frameNode.Upgrade();
10571                  JSRef<JSVal> params[PARAMETER_LENGTH_SECOND];
10572                  params[0] = modifier;
10573                  params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10574                  PipelineContext::SetCallBackNode(node);
10575                  func->ExecuteJS(PARAMETER_LENGTH_SECOND, params);
10576              };
10577              option.onApply = onApply;
10578          }
10579      }
10580  }
10581  
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)10582  void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10583  {
10584      if (!info[0]->IsObject()) {
10585          return;
10586      }
10587      JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10588      auto numberBadge = obj->GetProperty("numberBadge");
10589      if (!numberBadge->IsEmpty()) {
10590          if (numberBadge->IsNumber()) {
10591              int64_t number = numberBadge->ToNumber<int64_t>();
10592              if (number < 0 || number > INT_MAX) {
10593                  option.isNumber = false;
10594                  option.isShowBadge = true;
10595              } else {
10596                  option.isNumber = true;
10597                  option.badgeNumber = numberBadge->ToNumber<int>();
10598              }
10599          } else if (numberBadge->IsBoolean()) {
10600              option.isNumber = false;
10601              option.isShowBadge = numberBadge->ToBoolean();
10602          }
10603      } else {
10604          option.isNumber = false;
10605          option.isShowBadge = true;
10606      }
10607  }
10608  
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10609  void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10610  {
10611      // Parse cornerRadius.
10612      auto cornerRadiusValue = obj->GetProperty("cornerRadius");
10613      NG::BorderRadiusProperty radius;
10614      if (ParseBorderRadius(cornerRadiusValue, radius)) {
10615          properties.borderRadius = radius;
10616      }
10617      // Parse border width
10618      auto borderWidthValue = obj->GetProperty("borderWidth");
10619      NG::BorderWidthProperty borderWidth;
10620      if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
10621          properties.borderWidth = borderWidth;
10622          auto colorValue = obj->GetProperty("borderColor");
10623          NG::BorderColorProperty borderColor;
10624          if (ParseBorderColorProps(colorValue, borderColor)) {
10625              properties.borderColor = borderColor;
10626          } else {
10627              borderColor.SetColor(Color::BLACK);
10628              properties.borderColor = borderColor;
10629          }
10630          // Parse border style
10631          auto styleValue = obj->GetProperty("borderStyle");
10632          NG::BorderStyleProperty borderStyle;
10633          if (ParseBorderStyleProps(styleValue, borderStyle)) {
10634              properties.borderStyle = borderStyle;
10635          } else {
10636              properties.borderStyle = NG::BorderStyleProperty(
10637                  { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
10638          }
10639      }
10640      auto shadowValue = obj->GetProperty("shadow");
10641      Shadow shadow;
10642      if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
10643          properties.shadow = shadow;
10644      }
10645      auto widthValue = obj->GetProperty("width");
10646      CalcDimension width;
10647      if (ParseJsDimensionVpNG(widthValue, width, true)) {
10648          properties.width = width;
10649      }
10650      auto heightValue = obj->GetProperty("height");
10651      CalcDimension height;
10652      if (ParseJsDimensionVpNG(heightValue, height, true)) {
10653          properties.height = height;
10654      }
10655  }
10656  
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10657  void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10658  {
10659      auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
10660      if (enableHoverModeValue->IsBoolean()) {
10661          properties.enableHoverMode = enableHoverModeValue->ToBoolean();
10662      }
10663  
10664      // Parse hoverModeArea
10665      auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
10666      if (hoverModeAreaValue->IsNumber()) {
10667          auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
10668          if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
10669              properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
10670          }
10671      }
10672  }
10673  
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)10674  std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
10675  {
10676      auto* vm = info.GetVm();
10677      return [vm, nodeId](const std::string& key) -> std::string {
10678          std::string resultString = std::string();
10679          CHECK_NULL_RETURN(vm, resultString);
10680          panda::LocalScope scope(vm);
10681          auto global = JSNApi::GetGlobalObject(vm);
10682          auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
10683          if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
10684              return resultString;
10685          }
10686          auto obj = getCustomProperty->ToObject(vm);
10687          panda::Local<panda::FunctionRef> func = obj;
10688          panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
10689              panda::StringRef::NewFromUtf8(vm, key.c_str()) };
10690          auto function = panda::CopyableGlobal(vm, func);
10691          auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
10692          if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
10693              return resultString;
10694          }
10695          auto value = callValue->ToString(vm)->ToString(vm);
10696          return value;
10697      };
10698  }
10699  
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)10700  std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
10701  {
10702      auto* vm = info.GetVm();
10703      panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
10704          info[1]->GetLocalHandle() };
10705      return [vm, params3]() -> bool {
10706          CHECK_NULL_RETURN(vm, false);
10707          panda::LocalScope scope(vm);
10708          auto global = JSNApi::GetGlobalObject(vm);
10709          auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
10710          if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
10711              return false;
10712          }
10713          auto obj = setCustomProperty->ToObject(vm);
10714          panda::Local<panda::FunctionRef> func = obj;
10715          auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10716          auto nodeId = frameNode->GetId();
10717          auto function = panda::CopyableGlobal(vm, func);
10718          auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
10719          if (customPropertyExisted) {
10720              frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
10721                  CHECK_NULL_VOID(vm);
10722                  panda::LocalScope scope(vm);
10723                  auto global = JSNApi::GetGlobalObject(vm);
10724                  auto removeCustomProperty =
10725                      global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
10726                  if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
10727                      return;
10728                  }
10729                  auto obj = removeCustomProperty->ToObject(vm);
10730                  panda::Local<panda::FunctionRef> func = obj;
10731                  panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
10732                  auto function = panda::CopyableGlobal(vm, func);
10733                  function->Call(vm, function.ToLocal(), params, 1);
10734              });
10735          }
10736          return true;
10737      };
10738  }
10739  
JsCustomProperty(const JSCallbackInfo & info)10740  void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
10741  {
10742      if (info[0]->GetLocalHandle()->IsUndefined()) {
10743          return;
10744      }
10745      auto* vm = info.GetVm();
10746      CHECK_NULL_VOID(vm);
10747      auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10748      auto nodeId = frameNode->GetId();
10749      auto getFunc = ParseJsGetFunc(info, nodeId);
10750      auto func = ParseJsFunc(info, nodeId);
10751      frameNode->SetJSCustomProperty(func, getFunc);
10752  }
10753  
JsGestureModifier(const JSCallbackInfo & info)10754  void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
10755  {
10756      auto* vm = info.GetExecutionContext().vm_;
10757      CHECK_NULL_VOID(vm);
10758      auto global = JSNApi::GetGlobalObject(vm);
10759      auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
10760      if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
10761          return;
10762      }
10763      auto obj = gestureModifier->ToObject(vm);
10764      panda::Local<panda::FunctionRef> func = obj;
10765      auto thisObj = info.This()->GetLocalHandle();
10766      panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
10767      func->Call(vm, thisObj, params, 1);
10768  }
10769  
JsBackgroundImageResizable(const JSCallbackInfo & info)10770  void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
10771  {
10772      auto infoObj = info[0];
10773      ImageResizableSlice sliceResult;
10774      if (!infoObj->IsObject()) {
10775          ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10776          return;
10777      }
10778      JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
10779      if (resizableObject->IsEmpty()) {
10780          ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10781          return;
10782      }
10783      auto sliceValue = resizableObject->GetProperty("slice");
10784      if (!sliceValue->IsObject()) {
10785          return;
10786      }
10787      JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
10788      if (sliceObj->IsEmpty()) {
10789          ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10790          return;
10791      }
10792      for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
10793          auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
10794          CalcDimension sliceDimension;
10795          if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
10796              continue;
10797          }
10798          if (!sliceDimension.IsValid()) {
10799              continue;
10800          }
10801          switch (static_cast<BorderImageDirection>(i)) {
10802              case BorderImageDirection::LEFT:
10803                  sliceResult.left = sliceDimension;
10804                  break;
10805              case BorderImageDirection::RIGHT:
10806                  sliceResult.right = sliceDimension;
10807                  break;
10808              case BorderImageDirection::TOP:
10809                  sliceResult.top = sliceDimension;
10810                  break;
10811              case BorderImageDirection::BOTTOM:
10812                  sliceResult.bottom = sliceDimension;
10813                  break;
10814              default:
10815                  break;
10816          }
10817      }
10818      ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10819  }
10820  
JsFocusScopeId(const JSCallbackInfo & info)10821  void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
10822  {
10823      if (info.Length() == 0) {
10824          return;
10825      }
10826  
10827      std::string focusScopeId;
10828      if (info[0]->IsString()) {
10829          focusScopeId = info[0]->ToString();
10830      }
10831  
10832      bool isGroup = false;
10833      if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
10834          info[1]->IsBoolean()) {
10835          isGroup = info[1]->ToBoolean();
10836      }
10837      bool arrowKeyStepOut = true;
10838      if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() &&
10839          info[2]->IsBoolean()) {
10840          arrowKeyStepOut = info[2]->ToBoolean();
10841      }
10842      ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
10843  }
10844  
JsFocusScopePriority(const JSCallbackInfo & info)10845  void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
10846  {
10847      if (info.Length() == 0) {
10848          return;
10849      }
10850  
10851      if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
10852          return;
10853      }
10854      std::string focusScopeId = info[0]->ToString();
10855  
10856      int32_t focusPriority = 0;
10857      if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
10858          info[1]->IsNumber()) {
10859          focusPriority = info[1]->ToNumber<int32_t>();
10860      }
10861      ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
10862  }
10863  
ParseJsPropertyId(const JSRef<JSVal> & jsValue)10864  int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
10865  {
10866      int32_t resId = 0;
10867      if (jsValue->IsObject()) {
10868          JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10869          JSRef<JSVal> tmp = jsObj->GetProperty("id");
10870          if (!tmp->IsNull() && tmp->IsNumber()) {
10871              resId = tmp->ToNumber<int32_t>();
10872          }
10873      }
10874      return resId;
10875  }
10876  
JsVisualEffect(const JSCallbackInfo & info)10877  void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
10878  {
10879      if (!info[0]->IsObject()) {
10880          return;
10881      }
10882      auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
10883      ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
10884  }
10885  
JsBackgroundFilter(const JSCallbackInfo & info)10886  void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
10887  {
10888      if (!info[0]->IsObject()) {
10889          return;
10890      }
10891      auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
10892      ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
10893  }
10894  
JsForegroundFilter(const JSCallbackInfo & info)10895  void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
10896  {
10897      if (!info[0]->IsObject()) {
10898          return;
10899      }
10900      auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
10901      ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
10902  }
10903  
JsCompositingFilter(const JSCallbackInfo & info)10904  void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
10905  {
10906      if (!info[0]->IsObject()) {
10907          return;
10908      }
10909      auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
10910      ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
10911  }
10912  
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)10913  void JSViewAbstract::ParseOnCreateMenu(
10914      const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
10915  {
10916      if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
10917          return;
10918      }
10919      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10920      auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
10921          JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
10922      auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
10923                            instanceId = Container::CurrentId(), node = frameNode](
10924                            const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
10925          ContainerScope scope(instanceId);
10926          std::vector<NG::MenuOptionsParam> menuParams;
10927          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
10928          auto pipelineContext = PipelineContext::GetCurrentContext();
10929          CHECK_NULL_RETURN(pipelineContext, menuParams);
10930  
10931          pipelineContext->UpdateCurrentActiveNode(node);
10932          auto menuItem = func->ExecuteWithValue(systemMenuItems);
10933          if (!menuItem->IsArray()) {
10934              return menuParams;
10935          }
10936          auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
10937          for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
10938              auto menuItem = menuItemsArray->GetValueAt(i);
10939              if (!menuItem->IsObject()) {
10940                  continue;
10941              }
10942              auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
10943              NG::MenuOptionsParam menuOptionsParam;
10944              auto jsContent = menuItemObject->GetProperty("content");
10945              std::string content;
10946              ParseJsString(jsContent, content);
10947              menuOptionsParam.content = content;
10948              auto jsStartIcon = menuItemObject->GetProperty("icon");
10949              std::string icon;
10950              ParseJsMedia(jsStartIcon, icon);
10951              menuOptionsParam.icon = icon;
10952              auto jsTextMenuId = menuItemObject->GetProperty("id");
10953              std::string id;
10954              if (jsTextMenuId->IsObject()) {
10955                  auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
10956                  auto jsId = textMenuIdObject->GetProperty("id_");
10957                  ParseJsString(jsId, id);
10958              }
10959              menuOptionsParam.id = id;
10960              menuParams.emplace_back(menuOptionsParam);
10961          }
10962          return menuParams;
10963      };
10964      onCreateMenuCallback = jsCallback;
10965  }
10966  
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)10967  JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
10968  {
10969      JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
10970      uint32_t idx = 0;
10971      for (const auto& item : systemMenuItems) {
10972          systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
10973      }
10974      return systemMenuItemsArray;
10975  }
10976  
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)10977  bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
10978      NG::OnMenuItemClickCallback& onMenuItemClick)
10979  {
10980      auto tmpInfo = info[0];
10981      if (info.Length() != 1 || !tmpInfo->IsObject()) {
10982          return false;
10983      }
10984      WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10985      auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
10986      auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
10987      ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
10988  
10989      auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
10990      if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
10991          return false;
10992      }
10993      RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
10994      auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10995                            onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
10996                            node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
10997          ContainerScope scope(instanceId);
10998          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
10999          auto pipelineContext = PipelineContext::GetCurrentContext();
11000          CHECK_NULL_RETURN(pipelineContext, false);
11001          pipelineContext->UpdateCurrentActiveNode(node);
11002          auto paramArray = onMenuItemCallback(menuOptionsParam);
11003          if (paramArray->Length() != 2) {
11004              return false;
11005          }
11006          JSRef<JSVal> params[2];
11007          params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
11008          params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
11009          auto ret = func->ExecuteJS(2, params);
11010          if (ret->IsBoolean()) {
11011              return ret->ToBoolean();
11012          }
11013          return false;
11014      };
11015      onMenuItemClick = jsCallback;
11016      return true;
11017  }
11018  
CreateJsTextMenuId(const std::string & id)11019  JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
11020  {
11021      JSRef<JSObject> empty;
11022      auto engine = EngineHelper::GetCurrentEngine();
11023      CHECK_NULL_RETURN(engine, empty);
11024      NativeEngine* nativeEngine = engine->GetNativeEngine();
11025      CHECK_NULL_RETURN(nativeEngine, empty);
11026      auto env = reinterpret_cast<napi_env>(nativeEngine);
11027  
11028      napi_value global;
11029      napi_status ret = napi_get_global(env, &global);
11030      if (ret != napi_ok) {
11031          return empty;
11032      }
11033      napi_value constructor;
11034      ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
11035      if (ret != napi_ok) {
11036          return empty;
11037      }
11038  
11039      napi_value obj;
11040      napi_value menuId = nullptr;
11041  
11042      ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
11043      if (ret != napi_ok) {
11044          return empty;
11045      }
11046      ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
11047      if (ret != napi_ok) {
11048          return empty;
11049      }
11050  
11051      JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
11052      if (!value->IsObject()) {
11053          return empty;
11054      }
11055  
11056      return JSRef<JSObject>::Cast(value);
11057  }
11058  
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)11059  JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
11060  {
11061      JSRef<JSArray> params = JSRef<JSArray>::New();
11062      params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
11063      params->SetValueAt(1, CreateJsTextRange(menuItemParam));
11064      return params;
11065  }
11066  
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)11067  JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
11068  {
11069      JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
11070      TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
11071      JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
11072      TextMenuItem->SetPropertyObject("id", obj);
11073      return JSRef<JSVal>::Cast(TextMenuItem);
11074  }
11075  
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)11076  JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
11077  {
11078      JSRef<JSObject> textRange = JSRef<JSObject>::New();
11079      textRange->SetProperty<int32_t>("start", menuItemParam.start);
11080      textRange->SetProperty<int32_t>("end", menuItemParam.end);
11081      return JSRef<JSVal>::Cast(textRange);
11082  }
11083  
OHOS_ACE_ParseJsMedia(void * value,void * resource)11084  extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
11085  {
11086      napi_value napiValue = reinterpret_cast<napi_value>(value);
11087      ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
11088      if (!napiValue || !res) {
11089          return;
11090      }
11091      JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
11092      std::string src;
11093      std::string bundleName;
11094      std::string moduleName;
11095      JSViewAbstract::ParseJsMedia(jsVal, src);
11096      JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
11097      res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
11098      res->src = src;
11099      res->bundleName = bundleName;
11100      res->moduleName = moduleName;
11101  }
11102  
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)11103  void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
11104      std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
11105  {
11106      if (!modifierObj->IsObject()) {
11107          textStyleApply = nullptr;
11108          return;
11109      }
11110      auto vm = info.GetVm();
11111      auto globalObj = JSNApi::GetGlobalObject(vm);
11112      auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
11113      JsiValue jsiValue(globalFunc);
11114      JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11115      if (!globalFuncRef->IsFunction()) {
11116          textStyleApply = nullptr;
11117          return;
11118      }
11119      RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11120      auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11121                      modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11122          JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11123          auto node = frameNode.Upgrade();
11124          CHECK_NULL_VOID(node);
11125          JSRef<JSVal> params[2];
11126          params[0] = modifierParam;
11127          params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11128          PipelineContext::SetCallBackNode(node);
11129          func->ExecuteJS(2, params);
11130      };
11131      textStyleApply = onApply;
11132  }
11133  
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)11134  void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
11135      std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
11136  {
11137      auto vm = info.GetVm();
11138      auto globalObj = JSNApi::GetGlobalObject(vm);
11139      auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
11140      JsiValue jsiValue(globalFunc);
11141      JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11142      if (globalFuncRef->IsFunction()) {
11143          RefPtr<JsFunction> jsFunc =
11144              AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11145          if (!modifierObj->IsObject()) {
11146              symbolApply = nullptr;
11147          } else {
11148              auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11149                                 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11150                  JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11151                  auto node = frameNode.Upgrade();
11152                  CHECK_NULL_VOID(node);
11153                  JSRef<JSVal> params[2];
11154                  params[0] = modifierParam;
11155                  params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11156                  PipelineContext::SetCallBackNode(node);
11157                  func->ExecuteJS(2, params);
11158              };
11159              symbolApply = onApply;
11160          }
11161      }
11162  }
11163  } // namespace OHOS::Ace::Framework
11164