• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/utils/utf_helper.h"
42 #include "bridge/common/utils/engine_helper.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_on_child_touch_test_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
52 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
53 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
54 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
55 #include "bridge/declarative_frontend/engine/js_types.h"
56 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h"
57 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
58 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
59 #include "bridge/declarative_frontend/engine/js_converter.h"
60 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
61 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
62 #include "bridge/declarative_frontend/jsview/js_utils.h"
63 #include "bridge/declarative_frontend/jsview/js_view_context.h"
64 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
65 #include "bridge/declarative_frontend/jsview/js_layoutable_view.h"
66 #include "core/event/focus_axis_event.h"
67 #include "canvas_napi/js_canvas.h"
68 #ifdef SUPPORT_DIGITAL_CROWN
69 #include "bridge/declarative_frontend/engine/functions/js_crown_function.h"
70 #endif
71 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
72 #include "core/components/text_overlay/text_overlay_theme.h"
73 #include "core/components/theme/shadow_theme.h"
74 #ifdef PLUGIN_COMPONENT_SUPPORTED
75 #include "core/common/plugin_manager.h"
76 #endif
77 #include "interfaces/native/node/resource.h"
78 
79 #include "core/common/card_scope.h"
80 #include "core/common/resource/resource_configuration.h"
81 #include "core/components_ng/base/view_abstract_model_ng.h"
82 #include "core/components_ng/base/view_stack_model.h"
83 #include "core/components_ng/base/inspector.h"
84 #include "core/event/key_event.h"
85 
86 namespace OHOS::Ace::NG {
87 constexpr uint32_t DEFAULT_GRID_SPAN = 1;
88 constexpr int32_t DEFAULT_GRID_OFFSET = 0;
89 }
90 
91 namespace OHOS::Ace {
92 namespace {
93 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
94 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
95 constexpr int32_t DIRECTION_COUNT = 4;
96 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
97 constexpr int NUM1 = 1;
98 constexpr int NUM2 = 2;
99 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
100     HoverModeAreaType::BOTTOM_SCREEN };
101 const std::string CUSTOM_SYMBOL_SUFFIX = "_CustomSymbol";
102 } // namespace
103 
GetInstance()104 ViewAbstractModel* ViewAbstractModel::GetInstance()
105 {
106 #ifdef NG_BUILD
107     static NG::ViewAbstractModelNG instance;
108     return &instance;
109 #else
110     if (Container::IsCurrentUseNewPipeline()) {
111         static NG::ViewAbstractModelNG instance;
112         return &instance;
113     } else {
114         static Framework::ViewAbstractModelImpl instance;
115         return &instance;
116     }
117 #endif
118 }
119 } // namespace OHOS::Ace
120 
121 namespace OHOS::Ace::Framework {
122 namespace {
123 
124 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
125 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
126 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
127 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
128 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
129 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
130 constexpr int32_t MAX_ALIGN_VALUE = 8;
131 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
132 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
133 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
134 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
135 constexpr double FULL_DIMENSION = 100.0;
136 constexpr double HALF_DIMENSION = 50.0;
137 constexpr double ROUND_UNIT = 360.0;
138 constexpr double VISIBLE_RATIO_MIN = 0.0;
139 constexpr double VISIBLE_RATIO_MAX = 1.0;
140 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
141 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
142 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
143 constexpr int32_t SECOND_INDEX = 2;
144 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
145 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
146 constexpr float MAX_ANGLE = 360.0f;
147 constexpr float DEFAULT_BIAS = 0.5f;
148 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
149 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
150 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
151 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
152 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
153 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
154 const std::vector<int32_t> LENGTH_METRICS_KEYS {
155     static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
156     static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
157 const char* START_PROPERTY = "start";
158 const char* END_PROPERTY = "end";
159 const char* TOP_PROPERTY = "top";
160 const char* BOTTOM_PROPERTY = "bottom";
161 const char* LEFT_PROPERTY = "left";
162 const char* RIGHT_PROPERTY = "right";
163 const char* TOP_START_PROPERTY = "topStart";
164 const char* TOP_END_PROPERTY = "topEnd";
165 const char* BOTTOM_START_PROPERTY = "bottomStart";
166 const char* BOTTOM_END_PROPERTY = "bottomEnd";
167 const char* DEBUG_LINE_INFO_LINE = "$line";
168 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
169 
170 enum class OperationType { COPY, PASTE, CUT, SELECT_ALL, UNKNOWN };
171 
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)172 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
173     CalcDimension& centerX, CalcDimension& centerY)
174 {
175     double xVal = 1.0;
176     double yVal = 1.0;
177     double zVal = 1.0;
178     if (!jsValue->IsObject()) {
179         scaleX = static_cast<float>(xVal);
180         scaleY = static_cast<float>(yVal);
181         scaleZ = static_cast<float>(zVal);
182         CalcDimension length;
183         centerX = length;
184         centerY = length;
185         return;
186     }
187     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
188     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
189     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
190     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
191     scaleX = static_cast<float>(xVal);
192     scaleY = static_cast<float>(yVal);
193     scaleZ = static_cast<float>(zVal);
194     // if specify centerX
195     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
196     // if specify centerY
197     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
198 }
199 
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)200 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
201     CalcDimension& translateZ)
202 {
203     if (!jsValue->IsObject()) {
204         return;
205     }
206     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
207     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
208     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
209     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
210 }
211 
GetDefaultRotateVector(double & dx,double & dy,double & dz)212 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
213 {
214     dx = 0.0;
215     dy = 0.0;
216     dz = 0.0;
217     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
218         dz = 1.0;
219     }
220 }
221 
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)222 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
223 {
224     if (!jsValue->IsObject()) {
225         return;
226     }
227     // default: dx, dy, dz (0.0, 0.0, 0.0)
228     double dxVal = 0.0;
229     double dyVal = 0.0;
230     double dzVal = 0.0;
231     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
232     auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
233     auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
234     auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
235     if (jsRotateX->IsUndefined()
236         && jsRotateY->IsUndefined()
237         && jsRotateZ->IsUndefined()) {
238         GetDefaultRotateVector(dxVal, dyVal, dzVal);
239     } else {
240         JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
241         JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
242         JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
243     }
244     rotate.xDirection = static_cast<float>(dxVal);
245     rotate.yDirection = static_cast<float>(dyVal);
246     rotate.zDirection = static_cast<float>(dzVal);
247     // if specify centerX
248     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
249         rotate.centerX)) {
250         rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
251     }
252     // if specify centerY
253     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
254         rotate.centerY)) {
255         rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
256     }
257     // if specify centerZ
258     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
259         rotate.centerZ)) {
260         rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
261     }
262     // if specify angle
263     JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
264     rotate.perspective = 0.0f;
265     JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
266 }
267 
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)268 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
269 {
270     if (!jsValue->IsObject()) {
271         return false;
272     }
273 
274     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
275     auto path = jsObj->GetPropertyValue<std::string>("path", "");
276     if (path.empty()) {
277         return false;
278     }
279     option.SetPath(path);
280     double from = 0.0;
281     double to = 1.0;
282     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
283     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
284     if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
285         from = 0.0;
286     }
287     if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
288         to = 1.0;
289     } else if (to < from) {
290         to = from;
291     }
292     option.SetBegin(static_cast<float>(from));
293     option.SetEnd(static_cast<float>(to));
294     option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
295     return true;
296 }
297 
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)298 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
299 {
300     isAuto = false;
301     switch (modeValue) {
302         case static_cast<int32_t>(NG::DragPreviewMode::AUTO):
303             previewOption.ResetDragPreviewMode();
304             isAuto = true;
305             break;
306         case static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE):
307             previewOption.isScaleEnabled = false;
308             break;
309         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW):
310             previewOption.isDefaultShadowEnabled = true;
311             break;
312         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS):
313             previewOption.isDefaultRadiusEnabled = true;
314             break;
315         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DRAG_ITEM_GRAY_EFFECT):
316             previewOption.isDefaultDragItemGrayEffectEnabled = true;
317             break;
318         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_MULTI_TILE_EFFECT):
319             previewOption.isMultiTiled = true;
320             break;
321         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW):
322             previewOption.isTouchPointCalculationBasedOnFinalPreviewEnable = true;
323             break;
324         default:
325             break;
326     }
327 }
328 
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)329 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
330     BackgroundImagePosition& bgImgPosition)
331 {
332     AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
333     bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
334     bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
335 }
336 
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)337 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
338 {
339     auto index = pos + containCount;
340     if (index < 0) {
341         return std::string();
342     }
343 
344     JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
345     if (type == "d") {
346         if (item->IsNumber()) {
347             return std::to_string(item->ToNumber<int32_t>());
348         } else if (item->IsObject()) {
349             int32_t result = 0;
350             JSViewAbstract::ParseJsInteger(item, result);
351             return std::to_string(result);
352         }
353     } else if (type == "s") {
354         if (item->IsString()) {
355             return item->ToString();
356         } else if (item->IsObject()) {
357             std::string result;
358             JSViewAbstract::ParseJsString(item, result);
359             return result;
360         }
361     } else if (type == "f") {
362         if (item->IsNumber()) {
363             return std::to_string(item->ToNumber<float>());
364         } else if (item->IsObject()) {
365             double result = 0.0;
366             JSViewAbstract::ParseJsDouble(item, result);
367             return std::to_string(result);
368         }
369     }
370     return std::string();
371 }
372 
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)373 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
374 {
375     auto size = static_cast<int32_t>(params->Length());
376     if (containCount == size) {
377         return;
378     }
379     std::string::const_iterator start = originStr.begin();
380     std::string::const_iterator end = originStr.end();
381     std::smatch matches;
382     bool shortHolderType = false;
383     bool firstMatch = true;
384     int searchTime = 0;
385     while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
386         std::string pos = matches[2];
387         std::string type = matches[4];
388         if (firstMatch) {
389             firstMatch = false;
390             shortHolderType = pos.length() == 0;
391         } else {
392             if (shortHolderType ^ (pos.length() == 0)) {
393                 return;
394             }
395         }
396 
397         std::string replaceContentStr;
398         if (shortHolderType) {
399             replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
400         } else {
401             replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
402         }
403 
404         originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
405         start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
406         end = originStr.end();
407         searchTime++;
408     }
409 }
410 
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)411 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
412 {
413     JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
414     JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
415     bool hasX = false;
416     bool hasY = false;
417     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
418         hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
419         hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
420     } else {
421         hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
422         hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
423     }
424     return hasX || hasY;
425 }
426 
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)427 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
428 {
429     bool useEdges = false;
430     CalcDimension top;
431     CalcDimension left;
432     CalcDimension bottom;
433     CalcDimension right;
434     JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
435     JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
436     JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
437     JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
438     if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
439         edges.SetTop(top);
440         useEdges = true;
441     }
442     if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
443         edges.SetLeft(left);
444         useEdges = true;
445     }
446     if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
447         edges.SetBottom(bottom);
448         useEdges = true;
449     }
450     if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
451         edges.SetRight(right);
452         useEdges = true;
453     }
454     return useEdges;
455 }
456 
457 decltype(JSViewAbstract::ParseJsLengthMetricsVp)* ParseJsLengthMetrics = JSViewAbstract::ParseJsLengthMetricsVp;
458 
ParseJsLengthMetricsToDimension(const JSRef<JSObject> & obj,Dimension & result)459 void ParseJsLengthMetricsToDimension(const JSRef<JSObject>& obj, Dimension& result)
460 {
461     auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
462     if (!value->IsNumber()) {
463         return;
464     }
465     auto unit = DimensionUnit::VP;
466     auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
467     if (jsUnit->IsNumber()) {
468         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
469     }
470     CalcDimension dimension(value->ToNumber<double>(), unit);
471     result = dimension;
472     return;
473 }
474 
CheckLengthMetrics(const JSRef<JSObject> & object)475 bool CheckLengthMetrics(const JSRef<JSObject>& object)
476 {
477     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
478         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
479         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
480         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
481         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
482         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
483         return true;
484     }
485     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
486     if (jsTop->IsObject()) {
487         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
488         if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
489             return true;
490         }
491     }
492     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
493     if (jsBottom->IsObject()) {
494         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
495         if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
496             return true;
497         }
498     }
499     return false;
500 }
501 
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)502 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
503 {
504     bool useLocalizedEdges = false;
505     CalcDimension start;
506     CalcDimension end;
507     CalcDimension top;
508     CalcDimension bottom;
509 
510     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
511     if (startVal->IsObject()) {
512         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
513         ParseJsLengthMetrics(startObj, start);
514         edges.start = start;
515         useLocalizedEdges = true;
516     }
517     JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
518     if (endVal->IsObject()) {
519         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
520         ParseJsLengthMetrics(endObj, end);
521         edges.end = end;
522         useLocalizedEdges = true;
523     }
524     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
525     if (topVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(topVal), top)) {
526         edges.SetTop(top);
527         useLocalizedEdges = true;
528     }
529     JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
530     if (bottomVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(bottomVal), bottom)) {
531         edges.SetBottom(bottom);
532         useLocalizedEdges = true;
533     }
534     return useLocalizedEdges;
535 }
536 
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)537 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
538 {
539     bool useMarkAnchorPosition = false;
540     CalcDimension start;
541     CalcDimension top;
542 
543     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
544     if (startVal->IsObject()) {
545         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
546         ParseJsLengthMetrics(startObj, start);
547         x = start;
548         useMarkAnchorPosition = true;
549     }
550     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
551     if (topVal->IsObject()) {
552         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
553         ParseJsLengthMetrics(topObj, top);
554         y = top;
555         useMarkAnchorPosition = true;
556     }
557     return useMarkAnchorPosition;
558 }
559 
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)560 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
561 {
562     JSRef<JSVal> builder;
563     if (info->IsObject()) {
564         auto builderObj = JSRef<JSObject>::Cast(info);
565         builder = builderObj->GetProperty("builder");
566     } else if (info->IsFunction()) {
567         builder = info;
568     } else {
569         return nullptr;
570     }
571 
572     if (!builder->IsFunction()) {
573         return nullptr;
574     }
575 
576     return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
577 }
578 
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)579 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
580     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
581 {
582     RefPtr<NG::ChainedTransitionEffect> effect;
583     if (effectOption->IsObject()) {
584         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
585         std::optional<float> angle;
586         ParseJsRotate(effectOption, rotate, angle);
587         if (angle.has_value()) {
588             rotate.angle = angle.value();
589             return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
590         }
591     }
592     return nullptr;
593 }
594 
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)595 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
596     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
597 {
598     double opacity = 1.0;
599     if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
600         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
601             if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
602                 opacity = 1.0;
603             }
604         } else {
605             opacity = std::clamp(opacity, 0.0, 1.0);
606         }
607         return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
608     }
609     return nullptr;
610 }
611 
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)612 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
613     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
614 {
615     if (effectOption->IsObject()) {
616         // default: x, y, z (0.0, 0.0, 0.0)
617         NG::TranslateOptions translate;
618         ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
619         return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
620     }
621     return nullptr;
622 }
623 
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)624 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
625     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
626 {
627     if (effectOption->IsObject()) {
628         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
629         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
630         ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
631         return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
632     }
633     return nullptr;
634 }
635 
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)636 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
637     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
638 {
639     int32_t edge = 0;
640     if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
641         if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
642             edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
643             edge = static_cast<int32_t>(NG::TransitionEdge::START);
644         }
645         return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
646     }
647     return nullptr;
648 }
649 
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)650 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
651     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
652 {
653     if (effectOption->IsObject()) {
654         auto effectObj = JSRef<JSObject>::Cast(effectOption);
655         auto appearJsVal = effectObj->GetProperty("appear");
656         auto disappearJsVal = effectObj->GetProperty("disappear");
657         RefPtr<NG::ChainedTransitionEffect> appearEffect;
658         RefPtr<NG::ChainedTransitionEffect> disappearEffect;
659         if (appearJsVal->IsObject()) {
660             auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
661             appearEffect = JSViewAbstract::ParseChainedTransition(appearObj, context);
662         }
663         if (disappearJsVal->IsObject()) {
664             auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
665             disappearEffect = JSViewAbstract::ParseChainedTransition(disappearObj, context);
666         }
667         return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
668     }
669     return nullptr;
670 }
671 
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)672 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
673 {
674     CHECK_NULL_RETURN(pipelineContext, 0);
675     return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
676 }
677 
678 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
679     const JSRef<JSVal>&, const JSExecutionContext&);
680 
GetBundleNameFromContainer()681 std::string GetBundleNameFromContainer()
682 {
683     auto container = Container::Current();
684     CHECK_NULL_RETURN(container, "");
685     return container->GetBundleName();
686 }
687 
GetModuleNameFromContainer()688 std::string GetModuleNameFromContainer()
689 {
690     auto container = Container::Current();
691     CHECK_NULL_RETURN(container, "");
692     return container->GetModuleName();
693 }
694 
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)695 void CompleteResourceObjectFromParams(
696     int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
697 {
698     JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
699     int32_t typeNum = -1;
700     if (type->IsNumber()) {
701         typeNum = type->ToNumber<int32_t>();
702     }
703 
704     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
705     if (!args->IsArray()) {
706         return;
707     }
708     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
709     if (resId != UNKNOWN_RESOURCE_ID) {
710         return;
711     }
712     JSRef<JSVal> identity = params->GetValueAt(0);
713 
714     bool isParseDollarResourceSuccess =
715         JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
716     if (!isParseDollarResourceSuccess) {
717         return;
718     }
719 
720     std::regex resNameRegex(RESOURCE_NAME_PATTERN);
721     std::smatch resNameResults;
722     if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
723         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
724     }
725 
726     if (typeNum == UNKNOWN_RESOURCE_TYPE) {
727         jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
728     }
729 }
730 
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)731 void CompleteResourceObjectFromId(
732     JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
733 {
734     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
735     if (!args->IsArray()) {
736         return;
737     }
738     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
739     auto paramCount = params->Length();
740     JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
741     if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
742         std::vector<JSRef<JSVal>> tmpParams;
743         for (uint32_t i = 0; i < paramCount; i++) {
744             auto param = params->GetValueAt(i);
745             tmpParams.insert(tmpParams.end(), param);
746         }
747         params->SetValueAt(0, name);
748         uint32_t paramIndex = 1;
749         if (!type->IsEmpty()) {
750             params->SetValueAt(paramIndex, type);
751             paramIndex++;
752         }
753         for (auto tmpParam : tmpParams) {
754             params->SetValueAt(paramIndex, tmpParam);
755             paramIndex++;
756         }
757     } else {
758         params->SetValueAt(0, name);
759     }
760     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
761     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
762     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
763         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
764     }
765     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
766         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
767     }
768 }
769 
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)770 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
771 {
772     if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
773         checkDimension.Reset();
774         return;
775     }
776     if (notNegative && checkDimension.IsNegative()) {
777         checkDimension.Reset();
778         return;
779     }
780 }
781 
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)782 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
783 {
784     Color left;
785     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
786         commonColor.left = left;
787     }
788     Color right;
789     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
790         commonColor.right = right;
791     }
792     Color top;
793     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
794         commonColor.top = top;
795     }
796     Color bottom;
797     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
798         commonColor.bottom = bottom;
799     }
800 }
801 
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)802 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
803 {
804     Color start;
805     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
806         localizedColor.start = start;
807     }
808     Color end;
809     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
810         localizedColor.end = end;
811     }
812     Color top;
813     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
814         localizedColor.top = top;
815     }
816     Color bottom;
817     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
818         localizedColor.bottom = bottom;
819     }
820 }
821 
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)822 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
823 {
824     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
825         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
826         LocalizedColor localizedColor;
827         ParseLocalizedEdgeColors(object, localizedColor);
828         commonColor.top = localizedColor.top;
829         commonColor.bottom = localizedColor.bottom;
830         commonColor.left = localizedColor.start;
831         commonColor.right = localizedColor.end;
832         return true;
833     }
834     ParseEdgeColors(object, commonColor);
835     return false;
836 }
837 
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)838 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
839 {
840     CalcDimension left;
841     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
842         CheckDimensionUnit(left, true, notNegative);
843         commonCalcDimension.left = left;
844     }
845     CalcDimension right;
846     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
847         CheckDimensionUnit(right, true, notNegative);
848         commonCalcDimension.right = right;
849     }
850     CalcDimension top;
851     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
852         CheckDimensionUnit(top, true, notNegative);
853         commonCalcDimension.top = top;
854     }
855     CalcDimension bottom;
856     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
857         CheckDimensionUnit(bottom, true, notNegative);
858         commonCalcDimension.bottom = bottom;
859     }
860 }
861 
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)862 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
863     bool notNegative, CalcDimension defaultValue)
864 {
865     CalcDimension left;
866     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
867         CheckDimensionUnit(left, notPercent, notNegative);
868         commonCalcDimension.left = left;
869     } else {
870         commonCalcDimension.left = defaultValue;
871     }
872     CalcDimension right;
873     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
874         CheckDimensionUnit(right, notPercent, notNegative);
875         commonCalcDimension.right = right;
876     } else {
877         commonCalcDimension.right = defaultValue;
878     }
879     CalcDimension top;
880     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
881         CheckDimensionUnit(top, notPercent, notNegative);
882         commonCalcDimension.top = top;
883     } else {
884         commonCalcDimension.top = defaultValue;
885     }
886     CalcDimension bottom;
887     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
888         CheckDimensionUnit(bottom, false, true);
889         commonCalcDimension.bottom = bottom;
890     } else {
891         commonCalcDimension.bottom = defaultValue;
892     }
893 }
894 
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)895 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
896                               bool notNegative)
897 {
898     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
899     if (jsStart->IsObject()) {
900         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
901         CalcDimension calcDimension;
902         if (ParseJsLengthMetrics(startObj, calcDimension)) {
903             CheckDimensionUnit(calcDimension, true, notNegative);
904             localizedCalcDimension.start = calcDimension;
905         }
906     }
907     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
908     if (jsEnd->IsObject()) {
909         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
910         CalcDimension calcDimension;
911         if (ParseJsLengthMetrics(endObj, calcDimension)) {
912             CheckDimensionUnit(calcDimension, true, notNegative);
913             localizedCalcDimension.end = calcDimension;
914         }
915     }
916     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
917     if (jsTop->IsObject()) {
918         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
919         CalcDimension calcDimension;
920         if (ParseJsLengthMetrics(topObj, calcDimension)) {
921             CheckDimensionUnit(calcDimension, true, notNegative);
922             localizedCalcDimension.top = calcDimension;
923         }
924     }
925     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
926     if (jsBottom->IsObject()) {
927         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
928         CalcDimension calcDimension;
929         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
930             CheckDimensionUnit(calcDimension, true, notNegative);
931             localizedCalcDimension.bottom = calcDimension;
932         }
933     }
934 }
935 
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)936 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
937 {
938     if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
939         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
940         CalcDimension calcDimension;
941         if (ParseJsLengthMetrics(startObj, calcDimension)) {
942             CheckDimensionUnit(calcDimension, false, true);
943             localizedCalcDimension.start = calcDimension;
944         }
945     }
946     if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
947         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
948         CalcDimension calcDimension;
949         if (ParseJsLengthMetrics(endObj, calcDimension)) {
950             CheckDimensionUnit(calcDimension, false, true);
951             localizedCalcDimension.end = calcDimension;
952         }
953     }
954     if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
955         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
956         CalcDimension calcDimension;
957         if (ParseJsLengthMetrics(topObj, calcDimension)) {
958             CheckDimensionUnit(calcDimension, false, true);
959             localizedCalcDimension.top = calcDimension;
960         }
961     }
962     if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
963         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
964         CalcDimension calcDimension;
965         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
966             CheckDimensionUnit(calcDimension, false, true);
967             localizedCalcDimension.bottom = calcDimension;
968         }
969     }
970 }
971 
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)972 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
973 {
974     if (CheckLengthMetrics(object)) {
975         LocalizedCalcDimension localizedCalcDimension;
976         ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
977         commonCalcDimension.top = localizedCalcDimension.top;
978         commonCalcDimension.bottom = localizedCalcDimension.bottom;
979         commonCalcDimension.left = localizedCalcDimension.start;
980         commonCalcDimension.right = localizedCalcDimension.end;
981         return true;
982     }
983     ParseEdgeWidths(object, commonCalcDimension, notNegative);
984     return false;
985 }
986 
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)987 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
988 {
989     if (CheckLengthMetrics(object)) {
990         LocalizedCalcDimension localizedCalcDimension;
991         ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
992         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
993         commonCalcDimension.top = localizedCalcDimension.top;
994         commonCalcDimension.bottom = localizedCalcDimension.bottom;
995         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
996         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
997         return;
998     }
999     ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1000 }
1001 
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1002 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1003 {
1004     if (CheckLengthMetrics(object)) {
1005         LocalizedCalcDimension localizedCalcDimension;
1006         ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1007         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1008         commonCalcDimension.top = localizedCalcDimension.top;
1009         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1010         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1011         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1012         return;
1013     }
1014     ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1015 }
1016 
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1017 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1018 {
1019     auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1020     auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1021     auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1022         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1023         NG::PipelineContext::SetCallBackNode(targetNode);
1024         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1025         jsFuncFinish->ExecuteJS(1, &newJSVal);
1026     };
1027     return finishCallback;
1028 }
1029 } // namespace
1030 
GetResourceObject(const JSRef<JSObject> & jsObj)1031 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1032 {
1033     auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1034     auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1035     auto args = jsObj->GetProperty("params");
1036 
1037     std::string bundleName;
1038     std::string moduleName;
1039     auto bundle = jsObj->GetProperty("bundleName");
1040     auto module = jsObj->GetProperty("moduleName");
1041     if (bundle->IsString() && module->IsString()) {
1042         bundleName = bundle->ToString();
1043         moduleName = module->ToString();
1044     }
1045     if (!args->IsArray()) {
1046         return nullptr;
1047     }
1048     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1049     std::vector<ResourceObjectParams> resObjParamsList;
1050     auto size = static_cast<int32_t>(params->Length());
1051     for (int32_t i = 0; i < size; i++) {
1052         auto item = params->GetValueAt(i);
1053         ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1054         if (item->IsString()) {
1055             resObjParams.type = ResourceObjectParamType::STRING;
1056         } else if (item->IsNumber()) {
1057             if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1058                 resObjParams.type = ResourceObjectParamType::FLOAT;
1059             } else {
1060                 resObjParams.type = ResourceObjectParamType::INT;
1061             }
1062         }
1063         resObjParamsList.push_back(resObjParams);
1064     }
1065     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(
1066         id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely());
1067     return resourceObject;
1068 }
1069 
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1070 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1071 {
1072     auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1073     auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1074     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName, Container::CurrentIdSafely());
1075     return resourceObject;
1076 }
1077 
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1078 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1079 {
1080     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1081     RefPtr<ThemeConstants> themeConstants = nullptr;
1082     if (SystemProperties::GetResourceDecoupling()) {
1083         resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1084         if (!resourceAdapter) {
1085             return nullptr;
1086         }
1087     } else {
1088         themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1089         if (!themeConstants) {
1090             return nullptr;
1091         }
1092     }
1093     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1094     return resourceWrapper;
1095 }
1096 
CreateResourceWrapper()1097 RefPtr<ResourceWrapper> CreateResourceWrapper()
1098 {
1099     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1100     RefPtr<ThemeConstants> themeConstants = nullptr;
1101     if (SystemProperties::GetResourceDecoupling()) {
1102         resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(Container::CurrentIdSafely());
1103         if (!resourceAdapter) {
1104             return nullptr;
1105         }
1106     } else {
1107         themeConstants = JSViewAbstract::GetThemeConstants();
1108         if (!themeConstants) {
1109             return nullptr;
1110         }
1111     }
1112     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1113     return resourceWrapper;
1114 }
1115 
ColorAlphaAdapt(uint32_t origin)1116 uint32_t ColorAlphaAdapt(uint32_t origin)
1117 {
1118     uint32_t result = origin;
1119     if (origin >> COLOR_ALPHA_OFFSET == 0) {
1120         result = origin | COLOR_ALPHA_VALUE;
1121     }
1122     return result;
1123 }
1124 
StringToOperationType(const std::string & id)1125 OperationType StringToOperationType(const std::string& id)
1126 {
1127     if (id == "OH_DEFAULT_COPY") {
1128         return OperationType::COPY;
1129     } else if (id == "OH_DEFAULT_PASTE") {
1130         return OperationType::PASTE;
1131     } else if (id == "OH_DEFAULT_CUT") {
1132         return OperationType::CUT;
1133     } else if (id == "OH_DEFAULT_SELECT_ALL") {
1134         return OperationType::SELECT_ALL;
1135     } else {
1136         return OperationType::UNKNOWN;
1137     }
1138 }
1139 
UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam> & params)1140 void UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam>& params)
1141 {
1142     for (auto& param : params) {
1143         auto opType = StringToOperationType(param.menuOptionsParam.id);
1144         auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1145         CHECK_NULL_VOID(pipeline);
1146         auto theme = pipeline->GetTheme<TextOverlayTheme>();
1147         CHECK_NULL_VOID(theme);
1148         switch (opType) {
1149             case OperationType::COPY:
1150                 param.menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
1151                 break;
1152             case OperationType::PASTE:
1153                 param.menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
1154                 break;
1155             case OperationType::CUT:
1156                 param.menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
1157                 break;
1158             case OperationType::SELECT_ALL:
1159                 param.menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
1160                 break;
1161             default:
1162                 param.menuOptionsParam.labelInfo = "";
1163                 break;
1164         }
1165     }
1166 }
1167 
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context,const RefPtr<NG::FrameNode> node)1168 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseChainedTransition(
1169     const JSRef<JSObject>& object, const JSExecutionContext& context, const RefPtr<NG::FrameNode> node)
1170 {
1171     auto propType = object->GetProperty("type_");
1172     if (!propType->IsString()) {
1173         return nullptr;
1174     }
1175     std::string type = propType->ToString();
1176     auto propEffectOption = object->GetProperty("effect_");
1177     auto propAnimationOption = object->GetProperty("animation_");
1178     auto propSuccessor = object->GetProperty("successor_");
1179     static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
1180         { "asymmetric", ParseChainedAsymmetricTransition },
1181         { "identity",
1182             [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
1183                 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
1184         { "move", ParseChainedMoveTransition },
1185         { "opacity", ParseChainedOpacityTransition },
1186         { "rotate", ParseChainedRotateTransition },
1187         { "scale", ParseChainedScaleTransition },
1188         { "slideSwitch",
1189             [](const JSRef<JSVal>& effectOption,
1190                 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
1191                 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
1192             } },
1193         { "translate", ParseChainedTranslateTransition },
1194     };
1195     int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
1196     if (index < 0) {
1197         return nullptr;
1198     }
1199     RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
1200     if (!result) {
1201         return nullptr;
1202     }
1203     if (propAnimationOption->IsObject()) {
1204         auto container = Container::Current();
1205         CHECK_NULL_RETURN(container, nullptr);
1206         auto pipelineContext = container->GetPipelineContext();
1207         CHECK_NULL_RETURN(pipelineContext, nullptr);
1208         auto animationOptionResult = std::make_shared<AnimationOption>(
1209             JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRenderExceptDynamicComponent()));
1210         // The maximum of the form-animation-playback duration value is 1000 ms.
1211         if (pipelineContext->IsFormRenderExceptDynamicComponent() && pipelineContext->IsFormAnimation()) {
1212             auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
1213             // If the duration exceeds 1000ms, init it to 0 ms.
1214             if (formAnimationTimeInterval > DEFAULT_DURATION) {
1215                 animationOptionResult->SetDuration(0);
1216             } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
1217                 // If remaining time is less than 1000ms, check for update duration.
1218                 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
1219                 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation]  Form Transition SetDuration: %{public}lld ms",
1220                     static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
1221             }
1222         }
1223         auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
1224         JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
1225         WeakPtr<NG::FrameNode> targetNode = nullptr;
1226         if (node) {
1227             targetNode = AceType::WeakClaim(AceType::RawPtr(node));
1228         } else {
1229             targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1230         }
1231         if (onFinish->IsFunction()) {
1232             RefPtr<JsFunction> jsFunc =
1233                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
1234             std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
1235                                                       id = Container::CurrentId(), node = targetNode]() {
1236                 ContainerScope scope(id);
1237                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1238                 PipelineContext::SetCallBackNode(node);
1239                 func->Execute();
1240             };
1241             animationOptionResult->SetOnFinishEvent(onFinishEvent);
1242         }
1243         result->SetAnimationOption(animationOptionResult);
1244     }
1245     if (propSuccessor->IsObject()) {
1246         result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
1247     }
1248     return result;
1249 }
1250 
JsScale(const JSCallbackInfo & info)1251 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1252 {
1253     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1254     auto jsVal = info[0];
1255     if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1256         SetDefaultScale();
1257         return;
1258     }
1259 
1260     if (jsVal->IsObject()) {
1261         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1262         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1263             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1264             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1265             // default: x, y, z (1.0, 1.0, 1.0)
1266             auto scaleX = 1.0f;
1267             auto scaleY = 1.0f;
1268             auto scaleZ = 1.0f;
1269             // default centerX, centerY 50% 50%;
1270             CalcDimension centerX = 0.5_pct;
1271             CalcDimension centerY = 0.5_pct;
1272             ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1273             ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1274             ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1275             return;
1276         } else {
1277             SetDefaultScale();
1278         }
1279     }
1280     double scale = 0.0;
1281     if (ParseJsDouble(jsVal, scale)) {
1282         ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1283     }
1284 }
1285 
SetDefaultScale()1286 void JSViewAbstract::SetDefaultScale()
1287 {
1288     ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1289     ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1290 }
1291 
JsScaleX(const JSCallbackInfo & info)1292 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1293 {
1294     double scaleVal = 0.0;
1295     if (!ParseJsDouble(info[0], scaleVal)) {
1296         return;
1297     }
1298     ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1299 }
1300 
JsScaleY(const JSCallbackInfo & info)1301 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1302 {
1303     double scaleVal = 0.0;
1304     if (!ParseJsDouble(info[0], scaleVal)) {
1305         return;
1306     }
1307     ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1308 }
1309 
JsOpacity(const JSCallbackInfo & info)1310 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1311 {
1312     double opacity = 0.0;
1313     if (!ParseJsDouble(info[0], opacity)) {
1314         ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1315         return;
1316     }
1317     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1318         opacity = std::clamp(opacity, 0.0, 1.0);
1319     } else {
1320         if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1321             opacity = 1.0;
1322         }
1323     }
1324     ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1325 }
1326 
JsTranslate(const JSCallbackInfo & info)1327 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1328 {
1329     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1330         JSCallbackInfoType::OBJECT };
1331     auto jsVal = info[0];
1332     if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1333         SetDefaultTranslate();
1334         return;
1335     }
1336 
1337     if (jsVal->IsObject()) {
1338         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1339         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1340             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1341             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1342             // default: x, y, z (0.0, 0.0, 0.0)
1343             auto translateX = CalcDimension(0.0);
1344             auto translateY = CalcDimension(0.0);
1345             auto translateZ = CalcDimension(0.0);
1346             ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1347             ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1348             return;
1349         } else {
1350             SetDefaultTranslate();
1351         }
1352     }
1353     CalcDimension value;
1354     if (ParseJsDimensionVp(jsVal, value)) {
1355         ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1356     }
1357 }
1358 
SetDefaultTranslate()1359 void JSViewAbstract::SetDefaultTranslate()
1360 {
1361     ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1362 }
1363 
JsTranslateX(const JSCallbackInfo & info)1364 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1365 {
1366     CalcDimension value;
1367     if (!ParseJsDimensionVp(info[0], value)) {
1368         return;
1369     }
1370     ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1371 }
1372 
JsTranslateY(const JSCallbackInfo & info)1373 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1374 {
1375     CalcDimension value;
1376     if (!ParseJsDimensionVp(info[0], value)) {
1377         return;
1378     }
1379     ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1380 }
1381 
JsRotate(const JSCallbackInfo & info)1382 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1383 {
1384     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1385     auto jsVal = info[0];
1386     if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1387         SetDefaultRotate();
1388         return;
1389     }
1390 
1391     if (jsVal->IsObject()) {
1392         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1393         std::optional<float> angle;
1394         ParseJsRotate(jsVal, rotate, angle);
1395         if (angle) {
1396             ViewAbstractModel::GetInstance()->SetRotate(
1397                 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1398             ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1399         } else {
1400             SetDefaultRotate();
1401         }
1402         return;
1403     }
1404     double rotateZ;
1405     if (ParseJsDouble(jsVal, rotateZ)) {
1406         ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1407     }
1408 }
1409 
SetDefaultRotate()1410 void JSViewAbstract::SetDefaultRotate()
1411 {
1412     NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1413     ViewAbstractModel::GetInstance()->SetRotate(
1414         rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1415     ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1416 }
1417 
JsRotateX(const JSCallbackInfo & info)1418 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1419 {
1420     double rotateVal = 0.0;
1421     if (!ParseJsDouble(info[0], rotateVal)) {
1422         return;
1423     }
1424     ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1425 }
1426 
JsRotateY(const JSCallbackInfo & info)1427 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1428 {
1429     double rotateVal = 0.0;
1430     if (!ParseJsDouble(info[0], rotateVal)) {
1431         return;
1432     }
1433     ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1434 }
1435 
JsTransform(const JSCallbackInfo & info)1436 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1437 {
1438     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1439     auto jsVal = info[0];
1440     if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1441         SetDefaultTransform();
1442         return;
1443     }
1444     JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1445     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1446     if (!array->IsArray()) {
1447         return;
1448     }
1449     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1450     if (jsArray->Length() != matrix4Len) {
1451         return;
1452     }
1453     std::vector<float> matrix(matrix4Len);
1454     for (int32_t i = 0; i < matrix4Len; i++) {
1455         double value = 0.0;
1456         ParseJsDouble(jsArray->GetValueAt(i), value);
1457         matrix[i] = static_cast<float>(value);
1458     }
1459     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1460 }
1461 
SetDefaultTransform()1462 void JSViewAbstract::SetDefaultTransform()
1463 {
1464     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1465     std::vector<float> matrix(matrix4Len);
1466     const int32_t initPosition = 5;
1467     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1468         double value = 1.0;
1469         matrix[i] = static_cast<float>(value);
1470     }
1471     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1472 }
1473 
ParseJsTransition(const JSRef<JSObject> & jsObj)1474 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1475 {
1476     NG::TransitionOptions transitionOption;
1477     bool hasEffect = false;
1478     transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1479     if (jsObj->HasProperty("opacity")) {
1480         double opacity = 1.0;
1481         ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1482         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1483             if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1484                 opacity = 1.0;
1485             }
1486         } else {
1487             opacity = std::clamp(opacity, 0.0, 1.0);
1488         }
1489         transitionOption.UpdateOpacity(static_cast<float>(opacity));
1490         hasEffect = true;
1491     }
1492     if (jsObj->HasProperty("translate")) {
1493         // default: x, y, z (0.0, 0.0, 0.0)
1494         NG::TranslateOptions translate;
1495         ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1496         transitionOption.UpdateTranslate(translate);
1497         hasEffect = true;
1498     }
1499     if (jsObj->HasProperty("scale")) {
1500         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1501         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1502         ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1503             scale.centerX, scale.centerY);
1504         transitionOption.UpdateScale(scale);
1505         hasEffect = true;
1506     }
1507     if (jsObj->HasProperty("rotate")) {
1508         // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1509         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1510         std::optional<float> angle;
1511         ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1512         if (angle.has_value()) {
1513             rotate.angle = angle.value();
1514             transitionOption.UpdateRotate(rotate);
1515             hasEffect = true;
1516         }
1517     }
1518     if (!hasEffect) {
1519         // default transition
1520         transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1521     }
1522     return transitionOption;
1523 }
1524 
ParseJsTransitionEffect(const JSCallbackInfo & info)1525 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1526 {
1527     JSRef<JSVal> arg = info[0];
1528     if (!arg->IsObject()) {
1529         return nullptr;
1530     }
1531     auto obj = JSRef<JSObject>::Cast(arg);
1532     auto transitionVal = obj->GetProperty("transition");
1533     if (!transitionVal->IsObject()) {
1534         return nullptr;
1535     }
1536     auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1537     auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
1538     return chainedEffect;
1539 }
1540 
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)1541 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
1542     const JSExecutionContext& context)
1543 {
1544     auto chainedEffect = ParseChainedTransition(object, context);
1545     return chainedEffect;
1546 }
1547 
JsTransition(const JSCallbackInfo & info)1548 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1549 {
1550     if (info.Length() < 1 || !info[0]->IsObject()) {
1551         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
1552             ViewAbstractModel::GetInstance()->CleanTransition();
1553             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
1554         }
1555         return;
1556     }
1557     auto obj = JSRef<JSObject>::Cast(info[0]);
1558     if (!obj->GetProperty("successor_")->IsUndefined()) {
1559         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1560         std::function<void(bool)> finishCallback;
1561         if (info.Length() > 1 && info[1]->IsFunction()) {
1562             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
1563         }
1564         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
1565         return;
1566     }
1567     auto options = ParseJsTransition(obj);
1568     ViewAbstractModel::GetInstance()->SetTransition(options);
1569 }
1570 
JsWidth(const JSCallbackInfo & info)1571 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1572 {
1573     JsWidth(info[0]);
1574 }
1575 
JsWidth(const JSRef<JSVal> & jsValue)1576 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1577 {
1578     CalcDimension value;
1579     if (jsValue->IsUndefined()) {
1580         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1581         return true;
1582     }
1583     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1584         if (!ParseJsDimensionVpNG(jsValue, value)) {
1585             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1586             return false;
1587         }
1588     } else if (!ParseJsDimensionVp(jsValue, value)) {
1589         return false;
1590     }
1591 
1592     if (LessNotEqual(value.Value(), 0.0)) {
1593         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1594             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1595             return true;
1596         } else {
1597             value.SetValue(0.0);
1598         }
1599     }
1600 
1601     ViewAbstractModel::GetInstance()->SetWidth(value);
1602     return true;
1603 }
1604 
JsHeight(const JSCallbackInfo & info)1605 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
1606 {
1607     JsHeight(info[0]);
1608 }
1609 
JsHeight(const JSRef<JSVal> & jsValue)1610 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
1611 {
1612     CalcDimension value;
1613     if (jsValue->IsUndefined()) {
1614         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1615         return true;
1616     }
1617     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1618         if (!ParseJsDimensionVpNG(jsValue, value)) {
1619             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1620             return false;
1621         }
1622     } else if (!ParseJsDimensionVp(jsValue, value)) {
1623         return false;
1624     }
1625 
1626     if (LessNotEqual(value.Value(), 0.0)) {
1627         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1628             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1629             return true;
1630         } else {
1631             value.SetValue(0.0);
1632         }
1633     }
1634 
1635     ViewAbstractModel::GetInstance()->SetHeight(value);
1636     return true;
1637 }
1638 
JsResponseRegion(const JSCallbackInfo & info)1639 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
1640 {
1641     std::vector<DimensionRect> result;
1642     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1643         ViewAbstractModel::GetInstance()->SetResponseRegion({});
1644         return;
1645     }
1646 
1647     ViewAbstractModel::GetInstance()->SetResponseRegion(result);
1648 }
1649 
JsMouseResponseRegion(const JSCallbackInfo & info)1650 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
1651 {
1652     std::vector<DimensionRect> result;
1653     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1654         ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
1655         return;
1656     }
1657     ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
1658 }
1659 
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)1660 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
1661 {
1662     result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
1663     result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
1664     if (!jsValue->IsObject()) {
1665         return true;
1666     }
1667 
1668     JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
1669     JSRef<JSVal> x = obj->GetProperty("x");
1670     JSRef<JSVal> y = obj->GetProperty("y");
1671     JSRef<JSVal> width = obj->GetProperty("width");
1672     JSRef<JSVal> height = obj->GetProperty("height");
1673     CalcDimension xDimen = result.GetOffset().GetX();
1674     CalcDimension yDimen = result.GetOffset().GetY();
1675     CalcDimension widthDimen = result.GetWidth();
1676     CalcDimension heightDimen = result.GetHeight();
1677     auto s1 = width->ToString();
1678     auto s2 = height->ToString();
1679     if (s1.find('-') != std::string::npos) {
1680         width = JSRef<JSVal>::Make(ToJSValue("100%"));
1681     }
1682     if (s2.find('-') != std::string::npos) {
1683         height = JSRef<JSVal>::Make(ToJSValue("100%"));
1684     }
1685     if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
1686         auto offset = result.GetOffset();
1687         offset.SetX(xDimen);
1688         result.SetOffset(offset);
1689     }
1690     if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
1691         auto offset = result.GetOffset();
1692         offset.SetY(yDimen);
1693         result.SetOffset(offset);
1694     }
1695     if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
1696         if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
1697             return true;
1698         }
1699         result.SetWidth(widthDimen);
1700     }
1701     if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
1702         if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
1703             return true;
1704         }
1705         result.SetHeight(heightDimen);
1706     }
1707     return true;
1708 }
1709 
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)1710 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
1711 {
1712     if (!jsValue->IsArray() && !jsValue->IsObject()) {
1713         return false;
1714     }
1715 
1716     if (jsValue->IsArray()) {
1717         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
1718         for (size_t i = 0; i < array->Length(); i++) {
1719             CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1720             CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1721             CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1722             CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1723             DimensionOffset offsetDimen(xDimen, yDimen);
1724             DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1725             if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
1726                 result.emplace_back(dimenRect);
1727             } else {
1728                 return false;
1729             }
1730         }
1731         return true;
1732     }
1733 
1734     CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1735     CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1736     CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1737     CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1738     DimensionOffset offsetDimen(xDimen, yDimen);
1739     DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1740     if (ParseJsDimensionRect(jsValue, dimenRect)) {
1741         result.emplace_back(dimenRect);
1742         return true;
1743     } else {
1744         return false;
1745     }
1746 }
1747 
JsSize(const JSCallbackInfo & info)1748 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
1749 {
1750     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1751     auto jsVal = info[0];
1752     if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
1753         return;
1754     }
1755 
1756     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
1757     JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
1758     JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
1759 }
1760 
JsConstraintSize(const JSCallbackInfo & info)1761 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
1762 {
1763     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1764     auto jsVal = info[0];
1765     if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
1766         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1767         ViewAbstractModel::GetInstance()->ResetMinSize(true);
1768         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1769         ViewAbstractModel::GetInstance()->ResetMinSize(false);
1770         return;
1771     }
1772 
1773     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
1774 
1775     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
1776     CalcDimension minWidth;
1777     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
1778     CalcDimension maxWidth;
1779     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
1780     CalcDimension minHeight;
1781     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
1782     CalcDimension maxHeight;
1783     bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
1784     if (ParseJsDimensionVp(minWidthValue, minWidth)) {
1785         ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
1786     } else if (version10OrLarger) {
1787         ViewAbstractModel::GetInstance()->ResetMinSize(true);
1788     }
1789 
1790     if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
1791         ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
1792     } else if (version10OrLarger) {
1793         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1794     }
1795 
1796     if (ParseJsDimensionVp(minHeightValue, minHeight)) {
1797         ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
1798     } else if (version10OrLarger) {
1799         ViewAbstractModel::GetInstance()->ResetMinSize(false);
1800     }
1801 
1802     if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
1803         ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
1804     } else if (version10OrLarger) {
1805         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1806     }
1807 }
1808 
JsLayoutPriority(const JSCallbackInfo & info)1809 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
1810 {
1811     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1812     auto jsVal = info[0];
1813     if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
1814         return;
1815     }
1816 
1817     int32_t priority;
1818     if (jsVal->IsNumber()) {
1819         priority = jsVal->ToNumber<int32_t>();
1820     } else {
1821         priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
1822     }
1823     ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
1824 }
1825 
JsLayoutWeight(const JSCallbackInfo & info)1826 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
1827 {
1828     float value = 0.0f;
1829     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1830     auto jsVal = info[0];
1831     if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
1832         if (!jsVal->IsUndefined()) {
1833             return;
1834         }
1835     }
1836 
1837     if (jsVal->IsNumber()) {
1838         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1839             value = jsVal->ToNumber<float>();
1840         } else {
1841             value = jsVal->ToNumber<int32_t>();
1842         }
1843     } else {
1844         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1845             value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
1846         } else {
1847             value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
1848         }
1849     }
1850 
1851     ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
1852 }
1853 
JsAlign(const JSCallbackInfo & info)1854 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
1855 {
1856     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
1857     auto jsVal = info[0];
1858     if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
1859         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1860         ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
1861         return;
1862     }
1863     auto value = jsVal->ToNumber<int32_t>();
1864     Alignment alignment = ParseAlignment(value);
1865     ViewAbstractModel::GetInstance()->SetAlign(alignment);
1866 }
1867 
JsPosition(const JSCallbackInfo & info)1868 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
1869 {
1870     CalcDimension x;
1871     CalcDimension y;
1872     OHOS::Ace::EdgesParam edges;
1873 
1874     auto jsArg = info[0];
1875     if (jsArg->IsObject()) {
1876         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
1877         if (ParseLocationProps(jsObj, x, y)) {
1878             return ViewAbstractModel::GetInstance()->SetPosition(x, y);
1879         } else if (ParseLocalizedEdges(jsObj, edges)) {
1880             ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
1881             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
1882         } else if (ParseLocationPropsEdges(jsObj, edges)) {
1883             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
1884         }
1885     }
1886     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1887         ViewAbstractModel::GetInstance()->ResetPosition();
1888     } else {
1889         ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
1890     }
1891 }
1892 
JsMarkAnchor(const JSCallbackInfo & info)1893 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
1894 {
1895     CalcDimension x;
1896     CalcDimension y;
1897 
1898     auto jsArg = info[0];
1899     if (jsArg->IsObject()) {
1900         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
1901         if (ParseMarkAnchorPosition(jsObj, x, y)) {
1902             ViewAbstractModel::GetInstance()->SetMarkAnchorStart(x);
1903             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
1904         } else if (ParseLocationProps(jsObj, x, y)) {
1905             ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
1906             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
1907         }
1908     }
1909     ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
1910     ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
1911 }
1912 
JsOffset(const JSCallbackInfo & info)1913 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
1914 {
1915     CalcDimension x;
1916     CalcDimension y;
1917     OHOS::Ace::EdgesParam edges;
1918     auto jsArg = info[0];
1919     if (jsArg->IsObject()) {
1920         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
1921         if (ParseLocalizedEdges(jsObj, edges)) {
1922             ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
1923             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
1924         } else if (ParseLocationProps(jsObj, x, y)) {
1925             return ViewAbstractModel::GetInstance()->SetOffset(x, y);
1926         } else if (ParseLocationPropsEdges(jsObj, edges)) {
1927             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
1928         }
1929     }
1930 
1931     ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
1932 }
1933 
JsEnabled(const JSCallbackInfo & info)1934 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
1935 {
1936     auto arg = info[0];
1937     if (!arg->IsBoolean()) {
1938         ViewAbstractModel::GetInstance()->SetEnabled(true);
1939     } else {
1940         ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
1941     }
1942 }
1943 
JsAspectRatio(const JSCallbackInfo & info)1944 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
1945 {
1946     double value = 0.0;
1947     auto jsAspectRatio = info[0];
1948     if (!ParseJsDouble(jsAspectRatio, value)) {
1949         // add version protection, undefined use default value
1950         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
1951             (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
1952             ViewAbstractModel::GetInstance()->ResetAspectRatio();
1953             return;
1954         } else {
1955             return;
1956         }
1957     }
1958 
1959     // negative use default value.
1960     if (LessOrEqual(value, 0.0)) {
1961         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1962             ViewAbstractModel::GetInstance()->ResetAspectRatio();
1963             return;
1964         } else {
1965             value = 1.0;
1966         }
1967     }
1968 
1969     ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
1970 }
1971 
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)1972 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
1973     std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
1974 {
1975     if (info[0]->IsString()) {
1976         std::string text = info[0]->ToString();
1977         ViewAbstractModel::GetInstance()->SetOverlay(
1978             text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
1979     } else if (info[0]->IsObject()) {
1980         JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
1981         auto builder = overlayObject->GetProperty("builder");
1982         if (builder->IsFunction()) {
1983             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1984             CHECK_NULL_VOID(builderFunc);
1985             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1986             auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
1987                                  node = targetNode]() {
1988                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1989                 ACE_SCORING_EVENT("Overlay");
1990                 PipelineContext::SetCallBackNode(node);
1991                 func->Execute();
1992             };
1993             ViewAbstractModel::GetInstance()->SetOverlay(
1994                 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
1995             return;
1996         }
1997 
1998         JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
1999         if (!builderNode->IsObject()) {
2000             return;
2001         }
2002         auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2003         JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2004         if (nodePtr.IsEmpty()) {
2005             return;
2006         }
2007         const auto* vm = nodePtr->GetEcmaVM();
2008         auto localHandle = nodePtr->GetLocalHandle();
2009         if (!localHandle->IsNativePointer(vm)) {
2010             return;
2011         }
2012         auto* node = localHandle->ToNativePointer(vm)->Value();
2013         auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2014         CHECK_NULL_VOID(frameNode);
2015         RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2016         ViewAbstractModel::GetInstance()->SetOverlay(
2017             "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2018     }
2019 }
2020 
JsOverlay(const JSCallbackInfo & info)2021 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2022 {
2023     if (info.Length() > 0 && (info[0]->IsUndefined())) {
2024         ViewAbstractModel::GetInstance()->SetOverlay(
2025             "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2026         return;
2027     }
2028 
2029     if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2030         return;
2031     }
2032     std::optional<Alignment> align;
2033     std::optional<CalcDimension> offsetX;
2034     std::optional<CalcDimension> offsetY;
2035 
2036     if (info[1]->IsObject()) {
2037         JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2038         JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2039         auto value = alignVal->ToNumber<int32_t>();
2040         Alignment alignment = ParseAlignment(value);
2041         align = alignment;
2042 
2043         JSRef<JSVal> val = optionObj->GetProperty("offset");
2044         if (val->IsObject()) {
2045             JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2046             JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2047             CalcDimension x;
2048             if (ParseJsDimensionVp(xVal, x)) {
2049                 offsetX = x;
2050             }
2051             JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2052             CalcDimension y;
2053             if (ParseJsDimensionVp(yVal, y)) {
2054                 offsetY = y;
2055             }
2056         }
2057     }
2058 
2059     ParseOverlayFirstParam(info, align, offsetX, offsetY);
2060 }
2061 
ParseAlignment(int32_t align)2062 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2063 {
2064     Alignment alignment = Alignment::CENTER;
2065     switch (align) {
2066         case 0:
2067             alignment = Alignment::TOP_LEFT;
2068             break;
2069         case 1:
2070             alignment = Alignment::TOP_CENTER;
2071             break;
2072         case 2:
2073             alignment = Alignment::TOP_RIGHT;
2074             break;
2075         case 3:
2076             alignment = Alignment::CENTER_LEFT;
2077             break;
2078         case 4:
2079             alignment = Alignment::CENTER;
2080             break;
2081         case 5:
2082             alignment = Alignment::CENTER_RIGHT;
2083             break;
2084         case 6:
2085             alignment = Alignment::BOTTOM_LEFT;
2086             break;
2087         case 7:
2088             alignment = Alignment::BOTTOM_CENTER;
2089             break;
2090         case 8:
2091             alignment = Alignment::BOTTOM_RIGHT;
2092             break;
2093         default:
2094             break;
2095     }
2096     return alignment;
2097 }
2098 
SetVisibility(const JSCallbackInfo & info)2099 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2100 {
2101     int32_t visible = 0;
2102     JSRef<JSVal> arg = info[0];
2103     if (arg->IsNull() || arg->IsUndefined()) {
2104         // undefined value use default value.
2105         visible = 0;
2106     } else if (!arg->IsNumber()) {
2107         return;
2108     } else {
2109         visible = arg->ToNumber<int32_t>();
2110     }
2111 
2112     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2113         (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2114         visible = 0;
2115     }
2116 
2117     if (info.Length() > 1 && info[1]->IsFunction()) {
2118         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2119         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2120         auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2121                                       int32_t visible) {
2122             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2123             ACE_SCORING_EVENT("onVisibilityChange");
2124             PipelineContext::SetCallBackNode(node);
2125             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2126             func->ExecuteJS(1, &newJSVal);
2127         };
2128         ViewAbstractModel::GetInstance()->SetVisibility(
2129             static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2130     } else {
2131         ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2132     }
2133 }
2134 
JsSetFreeze(const JSCallbackInfo & info)2135 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2136 {
2137     if (info[0]->IsBoolean()) {
2138         ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2139     }
2140 }
2141 
JsFlexBasis(const JSCallbackInfo & info)2142 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2143 {
2144     CalcDimension value;
2145     if (!ParseJsDimensionVp(info[0], value)) {
2146         value.SetUnit(DimensionUnit::AUTO);
2147     }
2148     // flexbasis don't support percent case.
2149     if (value.Unit() == DimensionUnit::PERCENT) {
2150         value.SetUnit(DimensionUnit::AUTO);
2151     }
2152     ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2153 }
2154 
JsFlexGrow(const JSCallbackInfo & info)2155 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2156 {
2157     double value = 0.0;
2158     if (!ParseJsDouble(info[0], value)) {
2159         if (info[0]->IsNull() || info[0]->IsUndefined()) {
2160             // undefined use default value.
2161             value = 0.0;
2162         } else {
2163             return;
2164         }
2165     }
2166     // negative use default value.
2167     if (value < 0.0) {
2168         value = 0.0;
2169     }
2170     ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2171 }
2172 
JsFlexShrink(const JSCallbackInfo & info)2173 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2174 {
2175     double value = 0.0;
2176     if (!ParseJsDouble(info[0], value)) {
2177         if (info[0]->IsNull() || info[0]->IsUndefined()) {
2178             // undefined use default value.
2179             ViewAbstractModel::GetInstance()->ResetFlexShrink();
2180             return;
2181         } else {
2182             return;
2183         }
2184     }
2185     // negative use default value.
2186     if (value < 0.0) {
2187         ViewAbstractModel::GetInstance()->ResetFlexShrink();
2188         return;
2189     }
2190     ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2191 }
2192 
JsDisplayPriority(const JSCallbackInfo & info)2193 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2194 {
2195     double value = 0.0;
2196     if (!ParseJsDouble(info[0], value)) {
2197         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2198             ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2199         }
2200         return;
2201     }
2202     ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2203 }
2204 
JsSharedTransition(const JSCallbackInfo & info)2205 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2206 {
2207     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2208     auto jsVal = info[0];
2209     if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2210         return;
2211     }
2212     // id
2213     auto id = jsVal->ToString();
2214     if (id.empty()) {
2215         return;
2216     }
2217     std::shared_ptr<SharedTransitionOption> sharedOption;
2218 
2219     // options
2220     if (info.Length() > 1 && info[1]->IsObject()) {
2221         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2222         sharedOption = std::make_shared<SharedTransitionOption>();
2223         // default: duration: 1000
2224         sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2225         if (sharedOption->duration < 0) {
2226             sharedOption->duration = DEFAULT_DURATION;
2227         }
2228         // default: delay: 0
2229         sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2230         if (sharedOption->delay < 0) {
2231             sharedOption->delay = 0;
2232         }
2233         // default: LinearCurve
2234         RefPtr<Curve> curve;
2235         JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2236         if (curveArgs->IsString()) {
2237             curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2238         } else if (curveArgs->IsObject()) {
2239             JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2240             if (!curveString->IsString()) {
2241                 return;
2242             }
2243             curve = CreateCurve(curveString->ToString(), false);
2244         }
2245         if (!curve) {
2246             curve = Curves::LINEAR;
2247         }
2248         sharedOption->curve = curve;
2249         // motionPath
2250         if (jsObj->HasProperty("motionPath")) {
2251             MotionPathOption motionPathOption;
2252             if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2253                 sharedOption->motionPathOption = motionPathOption;
2254             }
2255         }
2256         // zIndex
2257         sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2258         // type
2259         int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2260             static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2261         sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2262     }
2263     ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2264 }
2265 
JsGeometryTransition(const JSCallbackInfo & info)2266 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2267 {
2268     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2269     auto jsVal = info[0];
2270     if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2271         return;
2272     }
2273     // id
2274     auto id = jsVal->ToString();
2275     // follow flag
2276     bool followWithOutTransition = false;
2277     // hierarchy flag
2278     bool doRegisterSharedTransition = true;
2279     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2280         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2281         ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2282 
2283         auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2284         ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2285         switch (transitionHierarchyStrategy) {
2286             case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2287                 doRegisterSharedTransition = false;
2288                 break;
2289             case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2290                 doRegisterSharedTransition = true;
2291                 break;
2292             default:
2293                 break;
2294         }
2295     }
2296     ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2297 }
2298 
JsAlignSelf(const JSCallbackInfo & info)2299 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2300 {
2301     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2302     auto jsVal = info[0];
2303     if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2304         ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2305         return;
2306     }
2307     auto alignVal = jsVal->ToNumber<int32_t>();
2308 
2309     if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2310         ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2311     }
2312 }
2313 
JsBackgroundColor(const JSCallbackInfo & info)2314 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2315 {
2316     Color backgroundColor;
2317     if (!ParseJsColor(info[0], backgroundColor)) {
2318         backgroundColor = Color::TRANSPARENT;
2319     }
2320 
2321     ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2322 }
2323 
JsBackgroundImage(const JSCallbackInfo & info)2324 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2325 {
2326     int32_t resId = 0;
2327     std::string src;
2328     std::string bundle;
2329     std::string module;
2330     RefPtr<PixelMap> pixmap = nullptr;
2331     auto jsBackgroundImage = info[0];
2332     GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2333     int32_t repeatIndex = 0;
2334     bool syncMode = false;
2335     ParseBackgroundImageOption(info, repeatIndex, syncMode);
2336     ViewAbstractModel::GetInstance()->SetBackgroundImageSyncMode(syncMode);
2337     if (jsBackgroundImage->IsString()) {
2338         src = jsBackgroundImage->ToString();
2339         ViewAbstractModel::GetInstance()->SetBackgroundImage(
2340             ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2341     } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2342         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2343     } else {
2344 #if defined(PIXEL_MAP_SUPPORTED)
2345         if (IsDrawable(jsBackgroundImage)) {
2346             pixmap = GetDrawablePixmap(jsBackgroundImage);
2347         } else {
2348             pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2349         }
2350 #endif
2351         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2352     }
2353     if (info.Length() == 2) { // 2 is background image info length
2354         auto jsImageRepeat = info[1];
2355         if (jsImageRepeat->IsNumber()) {
2356             repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2357         }
2358     }
2359     auto repeat = static_cast<ImageRepeat>(repeatIndex);
2360     ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2361 }
2362 
ParseBackgroundImageOption(const JSCallbackInfo & info,int32_t & repeatIndex,bool & syncMode)2363 void JSViewAbstract::ParseBackgroundImageOption(const JSCallbackInfo& info, int32_t& repeatIndex, bool& syncMode)
2364 {
2365     if (info.Length() < 2) { // 2 represents the least para num;
2366         return;
2367     }
2368     if (!info[1]->IsObject()) {
2369         return;
2370     }
2371     JSRef<JSObject> jsOption  = JSRef<JSObject>::Cast(info[1]);
2372     if (jsOption->GetProperty("syncLoad")->IsBoolean()) {
2373         syncMode = jsOption->GetProperty("syncLoad")->ToBoolean();
2374     }
2375     if (jsOption->GetProperty("repeat")->IsNumber()) {
2376         repeatIndex = jsOption->GetProperty("repeat")->ToNumber<int32_t>();
2377     }
2378 }
2379 
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2380 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2381 {
2382     auto blurOptionProperty = jsBlurOption->GetProperty("grayscale");
2383     if (blurOptionProperty->IsArray()) {
2384         JSRef<JSArray> params = JSRef<JSArray>::Cast(blurOptionProperty);
2385         auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2386         auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2387         std::vector<float> greyVec(2); // 2 number
2388         greyVec[0] = grey1;
2389         greyVec[1] = grey2;
2390         blurOption.grayscale = greyVec;
2391     }
2392 }
2393 
ParseSysOptions(const JSRef<JSObject> & jsSysOptions,SysOptions & sysOptions)2394 void JSViewAbstract::ParseSysOptions(const JSRef<JSObject>& jsSysOptions, SysOptions& sysOptions)
2395 {
2396     auto disableAdaptation = jsSysOptions->GetProperty("disableSystemAdaptation");
2397     if (disableAdaptation->IsBoolean()) {
2398         sysOptions.disableSystemAdaptation = disableAdaptation->ToBoolean();
2399     }
2400 }
2401 
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2402 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
2403 {
2404     auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2405     ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2406     if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2407         colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2408         styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2409     }
2410     auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2411     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2412     if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2413         adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2414         styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2415     }
2416 
2417     // policy
2418     auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2419     ParseJsInt32(jsOption->GetProperty("policy"), policy);
2420     if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2421         policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2422         styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2423     }
2424 
2425     // blurType
2426     auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2427     ParseJsInt32(jsOption->GetProperty("type"), blurType);
2428     if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2429         blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2430         styleOption.blurType = static_cast<BlurType>(blurType);
2431     }
2432 
2433     // inactiveColor
2434     if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) {
2435         styleOption.isValidColor = true;
2436     }
2437 
2438     // scale
2439     if (jsOption->GetProperty("scale")->IsNumber()) {
2440         double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2441         styleOption.scale = std::clamp(scale, 0.0, 1.0);
2442     }
2443 
2444     if (jsOption->GetProperty("blurOptions")->IsObject()) {
2445         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2446         BlurOption blurOption;
2447         ParseBlurOption(jsBlurOption, blurOption);
2448         styleOption.blurOption = blurOption;
2449     }
2450 }
2451 
JsBackgroundBlurStyle(const JSCallbackInfo & info)2452 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2453 {
2454     if (info.Length() == 0) {
2455         return;
2456     }
2457     BlurStyleOption styleOption;
2458     if (info[0]->IsNumber()) {
2459         auto blurStyle = info[0]->ToNumber<int32_t>();
2460         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2461             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2462             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2463         }
2464     }
2465     if (info.Length() > 1 && info[1]->IsObject()) {
2466         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2467         ParseBlurStyleOption(jsOption, styleOption);
2468     }
2469     SysOptions sysOptions;
2470     sysOptions.disableSystemAdaptation = false;
2471     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
2472         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
2473         ParseSysOptions(jsSysOptions, sysOptions);
2474     }
2475     ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption, sysOptions);
2476 }
2477 
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2478 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2479 {
2480     double rate = 1.0f;
2481     auto jsRate = jsOption->GetProperty("rate");
2482     if (jsRate->IsNumber()) {
2483         rate = jsRate->ToNumber<double>();
2484     }
2485     double lightUpDegree = 0.0f;
2486     auto jslightUpDegree = jsOption->GetProperty("lightUpDegree");
2487     if (jslightUpDegree->IsNumber()) {
2488         lightUpDegree = jslightUpDegree->ToNumber<double>();
2489     }
2490     double cubicCoeff = 0.0f;
2491     auto jsCubicCoeff = jsOption->GetProperty("cubicCoeff");
2492     if (jsCubicCoeff->IsNumber()) {
2493         cubicCoeff = jsCubicCoeff->ToNumber<double>();
2494     }
2495     double quadCoeff = 0.0f;
2496     auto jsQuadCoeff = jsOption->GetProperty("quadCoeff");
2497     if (jsQuadCoeff->IsNumber()) {
2498         quadCoeff = jsQuadCoeff->ToNumber<double>();
2499     }
2500     double saturation = 1.0f;
2501     auto jsSaturation = jsOption->GetProperty("saturation");
2502     if (jsSaturation->IsNumber()) {
2503         saturation = jsSaturation->ToNumber<double>();
2504     }
2505     std::vector<float> posRGB(3, 0.0);
2506     auto jsPosRGB = jsOption->GetProperty("posRGB");
2507     if (jsPosRGB->IsArray()) {
2508         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsPosRGB);
2509         auto r = params->GetValueAt(0)->ToNumber<double>();
2510         auto g = params->GetValueAt(1)->ToNumber<double>();
2511         auto b = params->GetValueAt(2)->ToNumber<double>();
2512         posRGB[0] = r;
2513         posRGB[1] = g;
2514         posRGB[2] = b;
2515     }
2516     std::vector<float> negRGB(3, 0.0);
2517     auto jsNegRGB = jsOption->GetProperty("negRGB");
2518     if (jsNegRGB->IsArray()) {
2519         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsNegRGB);
2520         auto r = params->GetValueAt(0)->ToNumber<double>();
2521         auto g = params->GetValueAt(1)->ToNumber<double>();
2522         auto b = params->GetValueAt(2)->ToNumber<double>();
2523         negRGB[0] = r;
2524         negRGB[1] = g;
2525         negRGB[2] = b;
2526     }
2527     double fraction = 1.0f;
2528     auto jsFraction = jsOption->GetProperty("fraction");
2529     if (jsFraction->IsNumber()) {
2530         fraction = jsFraction->ToNumber<double>();
2531         fraction = std::clamp(fraction, 0.0, 1.0);
2532     }
2533     brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
2534 }
2535 
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2536 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
2537 {
2538     CalcDimension radius;
2539     if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2540         radius.SetValue(0.0f);
2541     }
2542     effectOption.radius = radius;
2543 
2544     double saturation = 1.0f;
2545     if (jsOption->GetProperty("saturation")->IsNumber()) {
2546         saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2547         saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2548     }
2549     effectOption.saturation = saturation;
2550 
2551     double brightness = 1.0f;
2552     if (jsOption->GetProperty("brightness")->IsNumber()) {
2553         brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2554         brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2555     }
2556     effectOption.brightness = brightness;
2557 
2558     ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
2559 
2560     auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2561     auto adaptiveColor = AdaptiveColor::DEFAULT;
2562     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
2563     if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2564         adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2565         adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
2566     }
2567     effectOption.adaptiveColor = adaptiveColor;
2568 
2569     // policy
2570     auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2571     ParseJsInt32(jsOption->GetProperty("policy"), policy);
2572     if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2573         policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2574         effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2575     }
2576 
2577     // blurType
2578     auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2579     ParseJsInt32(jsOption->GetProperty("type"), blurType);
2580     if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2581         blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2582         effectOption.blurType = static_cast<BlurType>(blurType);
2583     }
2584 
2585     // inactiveColor
2586     if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
2587         effectOption.isValidColor = true;
2588     }
2589 
2590     BlurOption blurOption;
2591     if (jsOption->GetProperty("blurOptions")->IsObject()) {
2592         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2593         ParseBlurOption(jsBlurOption, blurOption);
2594         effectOption.blurOption = blurOption;
2595     }
2596 }
2597 
JsForegroundEffect(const JSCallbackInfo & info)2598 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
2599 {
2600     if (info.Length() == 0) {
2601         return;
2602     }
2603     float radius = 0.0;
2604     if (info[0]->IsObject()) {
2605         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2606         if (jsOption->GetProperty("radius")->IsNumber()) {
2607             radius = jsOption->GetProperty("radius")->ToNumber<float>();
2608         }
2609     }
2610     radius = std::max(radius, 0.0f);
2611     SysOptions sysOptions;
2612     sysOptions.disableSystemAdaptation = false;
2613     if (info.Length() > NUM1 && info[NUM1]->IsObject()) {
2614         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM1]);
2615         ParseSysOptions(jsSysOptions, sysOptions);
2616     }
2617     ViewAbstractModel::GetInstance()->SetForegroundEffect(radius, sysOptions);
2618 }
2619 
JsBackgroundEffect(const JSCallbackInfo & info)2620 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
2621 {
2622     if (info.Length() == 0) {
2623         return;
2624     }
2625     EffectOption option;
2626     if (info[0]->IsObject()) {
2627         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2628         ParseEffectOption(jsOption, option);
2629     }
2630     SysOptions sysOptions;
2631     sysOptions.disableSystemAdaptation = false;
2632     if (info.Length() > NUM1 && info[NUM1]->IsObject()) {
2633         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM1]);
2634         ParseSysOptions(jsSysOptions, sysOptions);
2635     }
2636     ViewAbstractModel::GetInstance()->SetBackgroundEffect(option, sysOptions);
2637 }
2638 
JsForegroundBlurStyle(const JSCallbackInfo & info)2639 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
2640 {
2641     if (info.Length() == 0) {
2642         return;
2643     }
2644     BlurStyleOption styleOption;
2645     if (info[0]->IsNumber()) {
2646         auto blurStyle = info[0]->ToNumber<int32_t>();
2647         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2648             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2649             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2650         }
2651     }
2652     if (info.Length() > 1 && info[1]->IsObject()) {
2653         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2654         auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2655         ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2656         if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2657             colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2658             styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2659         }
2660         auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2661         ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2662         if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2663             adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2664             styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2665         }
2666         if (jsOption->GetProperty("scale")->IsNumber()) {
2667             double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2668             styleOption.scale = std::clamp(scale, 0.0, 1.0);
2669         }
2670 
2671         if (jsOption->GetProperty("blurOptions")->IsObject()) {
2672             JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2673             BlurOption blurOption;
2674             ParseBlurOption(jsBlurOption, blurOption);
2675             styleOption.blurOption = blurOption;
2676         }
2677     }
2678     SysOptions sysOptions;
2679     sysOptions.disableSystemAdaptation = false;
2680     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
2681         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
2682         ParseSysOptions(jsSysOptions, sysOptions);
2683     }
2684     ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption, sysOptions);
2685 }
2686 
JsSphericalEffect(const JSCallbackInfo & info)2687 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
2688 {
2689     auto radio = 0.0;
2690     if (info[0]->IsNumber()) {
2691         radio = info[0]->ToNumber<double>();
2692     }
2693     ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
2694 }
2695 
JsPixelStretchEffect(const JSCallbackInfo & info)2696 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
2697 {
2698     if (!info[0]->IsObject()) {
2699         PixStretchEffectOption option;
2700         option.ResetValue();
2701         ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2702         return;
2703     }
2704     auto jsObject = JSRef<JSObject>::Cast(info[0]);
2705     CalcDimension left;
2706     ParseJsDimensionVp(jsObject->GetProperty("left"), left);
2707     CalcDimension right;
2708     ParseJsDimensionVp(jsObject->GetProperty("right"), right);
2709     CalcDimension top;
2710     ParseJsDimensionVp(jsObject->GetProperty("top"), top);
2711     CalcDimension bottom;
2712     ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
2713 
2714     PixStretchEffectOption option;
2715     bool illegalInput = InitPixStretchEffect(left, right, top, bottom);
2716     if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
2717         (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
2718         option.left = left;
2719         option.top = top;
2720         option.right = right;
2721         option.bottom = bottom;
2722     } else {
2723         illegalInput = true;
2724     }
2725     if (illegalInput) {
2726         option.ResetValue();
2727     }
2728     ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2729 }
2730 
InitPixStretchEffect(CalcDimension & left,CalcDimension & right,CalcDimension & top,CalcDimension bottom)2731 bool JSViewAbstract::InitPixStretchEffect(
2732     CalcDimension& left, CalcDimension& right, CalcDimension& top, CalcDimension bottom)
2733 {
2734     bool illegalInput = false;
2735     if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
2736         top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
2737         if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
2738             (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
2739             (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
2740             (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
2741             left.SetUnit(DimensionUnit::PERCENT);
2742             top.SetUnit(DimensionUnit::PERCENT);
2743             right.SetUnit(DimensionUnit::PERCENT);
2744             bottom.SetUnit(DimensionUnit::PERCENT);
2745         } else {
2746             illegalInput = true;
2747         }
2748     }
2749     return illegalInput;
2750 }
2751 
JsLightUpEffect(const JSCallbackInfo & info)2752 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
2753 {
2754     auto radio = 1.0;
2755     if (info[0]->IsNumber()) {
2756         radio = info[0]->ToNumber<double>();
2757     }
2758     ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
2759 }
2760 
JsBackgroundImageSize(const JSCallbackInfo & info)2761 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
2762 {
2763     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2764     BackgroundImageSize bgImgSize;
2765     auto jsVal = info[0];
2766     if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
2767         bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2768         bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2769         ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2770         return;
2771     }
2772     if (jsVal->IsNumber()) {
2773         auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
2774         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2775             (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
2776             sizeType = BackgroundImageSizeType::AUTO;
2777         }
2778         bgImgSize.SetSizeTypeX(sizeType);
2779         bgImgSize.SetSizeTypeY(sizeType);
2780     } else {
2781         CalcDimension width;
2782         CalcDimension height;
2783         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
2784         ParseJsDimensionVp(object->GetProperty("width"), width);
2785         ParseJsDimensionVp(object->GetProperty("height"), height);
2786         double valueWidth = width.ConvertToPx();
2787         double valueHeight = height.ConvertToPx();
2788         BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
2789         BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
2790         if (width.Unit() == DimensionUnit::PERCENT) {
2791             typeWidth = BackgroundImageSizeType::PERCENT;
2792             valueWidth = width.Value() * FULL_DIMENSION;
2793         }
2794         if (height.Unit() == DimensionUnit::PERCENT) {
2795             typeHeight = BackgroundImageSizeType::PERCENT;
2796             valueHeight = height.Value() * FULL_DIMENSION;
2797         }
2798         bgImgSize.SetSizeTypeX(typeWidth);
2799         bgImgSize.SetSizeValueX(valueWidth);
2800         bgImgSize.SetSizeTypeY(typeHeight);
2801         bgImgSize.SetSizeValueY(valueHeight);
2802     }
2803 
2804     ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2805 }
2806 
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)2807 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
2808 {
2809     if (align > 8 || align < 0) { // align ranges from [0, 8].
2810         return;
2811     }
2812     std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
2813         { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
2814         { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
2815     SetBgImgPosition(
2816         DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
2817 }
2818 
JsBackgroundImagePosition(const JSCallbackInfo & info)2819 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
2820 {
2821     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2822     BackgroundImagePosition bgImgPosition;
2823     auto jsVal = info[0];
2824     if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
2825         SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
2826         ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2827         return;
2828     }
2829     if (jsVal->IsNumber()) {
2830         int32_t align = jsVal->ToNumber<int32_t>();
2831         bgImgPosition.SetIsAlign(true);
2832         SetBgImgPositionWithAlign(bgImgPosition, align);
2833     } else {
2834         CalcDimension x;
2835         CalcDimension y;
2836         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
2837         ParseJsDimensionVp(object->GetProperty("x"), x);
2838         ParseJsDimensionVp(object->GetProperty("y"), y);
2839         double valueX = x.Value();
2840         double valueY = y.Value();
2841         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
2842             valueX = x.ConvertToPx();
2843             valueY = y.ConvertToPx();
2844         }
2845         DimensionUnit typeX = DimensionUnit::PX;
2846         DimensionUnit typeY = DimensionUnit::PX;
2847         if (x.Unit() == DimensionUnit::PERCENT) {
2848             valueX = x.Value();
2849             typeX = DimensionUnit::PERCENT;
2850         }
2851         if (y.Unit() == DimensionUnit::PERCENT) {
2852             valueY = y.Value();
2853             typeY = DimensionUnit::PERCENT;
2854         }
2855         SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
2856     }
2857 
2858     ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2859 }
2860 
JsPadding(const JSCallbackInfo & info)2861 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
2862 {
2863     ParseMarginOrPadding(info, EdgeType::PADDING);
2864 }
2865 
JsMargin(const JSCallbackInfo & info)2866 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
2867 {
2868     ParseMarginOrPadding(info, EdgeType::MARGIN);
2869 }
2870 
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)2871 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
2872 {
2873     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
2874         JSCallbackInfoType::NUMBER };
2875     auto jsVal = info[0];
2876     if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
2877         auto resetDimension = CalcDimension(0.0);
2878         if (type == EdgeType::MARGIN) {
2879             ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
2880         } else if (type == EdgeType::PADDING) {
2881             ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
2882         } else if (type == EdgeType::SAFE_AREA_PADDING) {
2883             ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
2884         }
2885         return;
2886     }
2887 
2888     if (jsVal->IsObject()) {
2889         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
2890 
2891         CalcDimension length;
2892         if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
2893             ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
2894             return;
2895         }
2896 
2897         CommonCalcDimension commonCalcDimension;
2898         auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
2899         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
2900             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
2901             if (type == EdgeType::MARGIN) {
2902                 if (useLengthMetrics) {
2903                     ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
2904                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
2905                 } else {
2906                     ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
2907                         commonCalcDimension.left, commonCalcDimension.right);
2908                 }
2909             } else if (type == EdgeType::PADDING) {
2910                 if (useLengthMetrics) {
2911                     ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
2912                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
2913                 } else {
2914                     ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
2915                         commonCalcDimension.left, commonCalcDimension.right);
2916                 }
2917             } else if (type == EdgeType::SAFE_AREA_PADDING) {
2918                 if (useLengthMetrics) {
2919                     ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
2920                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
2921                 } else {
2922                     ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
2923                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
2924                 }
2925             }
2926             return;
2927         }
2928     }
2929 
2930     CalcDimension length;
2931     if (!ParseJsDimensionVp(jsVal, length)) {
2932         // use default value.
2933         length.Reset();
2934     }
2935     if (type == EdgeType::MARGIN) {
2936         ViewAbstractModel::GetInstance()->SetMargin(length);
2937     } else if (type == EdgeType::PADDING) {
2938         ViewAbstractModel::GetInstance()->SetPadding(length);
2939     }
2940 }
2941 
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)2942 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
2943     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
2944     const std::optional<CalcDimension>& end)
2945 {
2946     NG::PaddingProperty paddings;
2947     if (start.has_value()) {
2948         if (start.value().Unit() == DimensionUnit::CALC) {
2949             paddings.start = NG::CalcLength(start.value().CalcValue());
2950         } else {
2951             paddings.start = NG::CalcLength(start.value());
2952         }
2953     }
2954     if (bottom.has_value()) {
2955         if (bottom.value().Unit() == DimensionUnit::CALC) {
2956             paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
2957         } else {
2958             paddings.bottom = NG::CalcLength(bottom.value());
2959         }
2960     }
2961     if (end.has_value()) {
2962         if (end.value().Unit() == DimensionUnit::CALC) {
2963             paddings.end = NG::CalcLength(end.value().CalcValue());
2964         } else {
2965             paddings.end = NG::CalcLength(end.value());
2966         }
2967     }
2968     if (top.has_value()) {
2969         if (top.value().Unit() == DimensionUnit::CALC) {
2970             paddings.top = NG::CalcLength(top.value().CalcValue());
2971         } else {
2972             paddings.top = NG::CalcLength(top.value());
2973         }
2974     }
2975     return paddings;
2976 }
2977 
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)2978 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
2979     std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
2980 {
2981     CalcDimension leftDimen;
2982     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
2983         left = leftDimen;
2984     }
2985     CalcDimension rightDimen;
2986     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
2987         right = rightDimen;
2988     }
2989     CalcDimension topDimen;
2990     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
2991         top = topDimen;
2992     }
2993     CalcDimension bottomDimen;
2994     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
2995         bottom = bottomDimen;
2996     }
2997 }
2998 
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)2999 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3000     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3001 {
3002     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3003     if (jsStart->IsObject()) {
3004         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3005         CalcDimension calcDimension;
3006         if (ParseJsLengthMetrics(startObj, calcDimension)) {
3007             localizedCalcDimension.start = calcDimension;
3008         }
3009     }
3010     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3011     if (jsEnd->IsObject()) {
3012         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3013         CalcDimension calcDimension;
3014         if (ParseJsLengthMetrics(endObj, calcDimension)) {
3015             localizedCalcDimension.end = calcDimension;
3016         }
3017     }
3018     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3019     if (jsTop->IsObject()) {
3020         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3021         CalcDimension calcDimension;
3022         if (ParseJsLengthMetrics(topObj, calcDimension)) {
3023             localizedCalcDimension.top = calcDimension;
3024         }
3025     }
3026     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3027     if (jsBottom->IsObject()) {
3028         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3029         CalcDimension calcDimension;
3030         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3031             localizedCalcDimension.bottom = calcDimension;
3032         }
3033     }
3034 }
3035 
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3036 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3037     const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3038 {
3039     if (CheckLengthMetrics(object)) {
3040         LocalizedCalcDimension localizedCalcDimension;
3041         ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3042         commonCalcDimension.top = localizedCalcDimension.top;
3043         commonCalcDimension.bottom = localizedCalcDimension.bottom;
3044         commonCalcDimension.left = localizedCalcDimension.start;
3045         commonCalcDimension.right = localizedCalcDimension.end;
3046         return true;
3047     }
3048     ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3049         commonCalcDimension.right);
3050         return false;
3051 }
3052 
JsOutline(const JSCallbackInfo & info)3053 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3054 {
3055     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3056     auto jsVal = info[0];
3057     if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3058         CalcDimension borderWidth;
3059         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3060         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3061         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3062         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3063         return;
3064     }
3065     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3066     auto valueOuterWidth = object->GetProperty("width");
3067     if (!valueOuterWidth->IsUndefined()) {
3068         ParseOuterBorderWidth(valueOuterWidth);
3069     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3070         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3071     }
3072 
3073     // use default value when undefined.
3074     ParseOuterBorderColor(object->GetProperty("color"));
3075 
3076     auto valueOuterRadius = object->GetProperty("radius");
3077     if (!valueOuterRadius->IsUndefined()) {
3078         ParseOuterBorderRadius(valueOuterRadius);
3079     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3080         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3081     }
3082     // use default value when undefined.
3083     ParseOuterBorderStyle(object->GetProperty("style"));
3084     info.ReturnSelf();
3085 }
3086 
JsOutlineWidth(const JSCallbackInfo & info)3087 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
3088 {
3089     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3090         JSCallbackInfoType::OBJECT };
3091     auto jsVal = info[0];
3092     if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
3093         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3094         return;
3095     }
3096     ParseOuterBorderWidth(jsVal);
3097 }
3098 
JsOutlineColor(const JSCallbackInfo & info)3099 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
3100 {
3101     ParseOuterBorderColor(info[0]);
3102 }
3103 
JsOutlineRadius(const JSCallbackInfo & info)3104 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
3105 {
3106     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3107         JSCallbackInfoType::OBJECT };
3108     auto jsVal = info[0];
3109     if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
3110         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3111         return;
3112     }
3113     ParseOuterBorderRadius(jsVal);
3114 }
3115 
JsOutlineStyle(const JSCallbackInfo & info)3116 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
3117 {
3118     ParseOuterBorderStyle(info[0]);
3119 }
3120 
JsBorder(const JSCallbackInfo & info)3121 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
3122 {
3123     if (!info[0]->IsObject()) {
3124         CalcDimension borderWidth;
3125         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3126         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3127         ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
3128         ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3129         ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
3130         ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
3131         return;
3132     }
3133     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3134 
3135     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3136     if (!valueWidth->IsUndefined()) {
3137         ParseBorderWidth(valueWidth);
3138     }
3139 
3140     // use default value when undefined.
3141     ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
3142 
3143     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
3144     if (!valueRadius->IsUndefined()) {
3145         ParseBorderRadius(valueRadius);
3146     }
3147     // use default value when undefined.
3148     ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
3149 
3150     auto dashGap = object->GetProperty("dashGap");
3151     if (!dashGap->IsUndefined()) {
3152         ParseDashGap(dashGap);
3153     }
3154     auto dashWidth = object->GetProperty("dashWidth");
3155     if (!dashWidth->IsUndefined()) {
3156         ParseDashWidth(dashWidth);
3157     }
3158 
3159     info.ReturnSelf();
3160 }
3161 
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)3162 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
3163 {
3164     if (!args->IsObject()) {
3165         return false;
3166     }
3167     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3168     if (obj->IsUndefined()) {
3169         return true;
3170     }
3171     // filter dynamic $r raw input
3172     if (obj->HasProperty("id")) {
3173         return false;
3174     }
3175     if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
3176         (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
3177         (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
3178         (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
3179         (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
3180         (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
3181         return true;
3182     }
3183 
3184     return false;
3185 }
3186 
JsBorderWidth(const JSCallbackInfo & info)3187 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
3188 {
3189     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3190         JSCallbackInfoType::OBJECT };
3191     auto jsVal = info[0];
3192     if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
3193         ViewAbstractModel::GetInstance()->SetBorderWidth({});
3194         return;
3195     }
3196 
3197     ParseBorderWidth(jsVal);
3198 }
3199 
ParseBorderWidth(const JSRef<JSVal> & args)3200 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
3201 {
3202     CalcDimension borderWidth;
3203     if (ParseJsDimensionVp(args, borderWidth)) {
3204         if (borderWidth.IsNegative()) {
3205             borderWidth.Reset();
3206         }
3207         if (borderWidth.Unit() == DimensionUnit::PERCENT) {
3208             borderWidth.Reset();
3209         }
3210         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3211     } else if (args->IsObject()) {
3212         if (IsBorderWidthObjUndefined(args)) {
3213             ViewAbstractModel::GetInstance()->SetBorderWidth({});
3214             return;
3215         }
3216         CommonCalcDimension commonCalcDimension;
3217         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3218         if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
3219             ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
3220                 commonCalcDimension.top, commonCalcDimension.bottom, true);
3221             return;
3222         }
3223         ViewAbstractModel::GetInstance()->SetBorderWidth(
3224             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3225     } else {
3226         return;
3227     }
3228 }
3229 
ParseDashGap(const JSRef<JSVal> & args)3230 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
3231 {
3232     CalcDimension dashGap;
3233     if (ParseLengthMetricsToDimension(args, dashGap)) {
3234         if (dashGap.Unit() == DimensionUnit::PERCENT) {
3235             dashGap.Reset();
3236         }
3237         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
3238     } else if (args->IsObject()) {
3239         CommonCalcDimension commonCalcDimension;
3240         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3241         ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
3242         ViewAbstractModel::GetInstance()->SetDashGap(
3243             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3244     } else {
3245         dashGap.Reset();
3246         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
3247     }
3248 }
3249 
ParseDashWidth(const JSRef<JSVal> & args)3250 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
3251 {
3252     CalcDimension dashWidth;
3253     if (ParseLengthMetricsToDimension(args, dashWidth)) {
3254         if (dashWidth.Unit() == DimensionUnit::PERCENT) {
3255             dashWidth.Reset();
3256         }
3257         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
3258     } else if (args->IsObject()) {
3259         CommonCalcDimension commonCalcDimension;
3260         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3261         ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
3262         ViewAbstractModel::GetInstance()->SetDashWidth(
3263             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3264     } else {
3265         dashWidth.Reset();
3266         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
3267     }
3268 }
3269 
ParseOuterBorderWidth(const JSRef<JSVal> & args)3270 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
3271 {
3272     CalcDimension borderWidth;
3273     if (ParseJsDimensionVp(args, borderWidth)) {
3274         if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
3275             borderWidth.Reset();
3276         }
3277         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3278     } else if (args->IsObject()) {
3279         std::optional<CalcDimension> leftDimen;
3280         std::optional<CalcDimension> rightDimen;
3281         std::optional<CalcDimension> topDimen;
3282         std::optional<CalcDimension> bottomDimen;
3283         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3284         CalcDimension left;
3285         if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
3286             if (left.Unit() == DimensionUnit::PERCENT) {
3287                 left.Reset();
3288             }
3289             leftDimen = left;
3290         }
3291         CalcDimension right;
3292         if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
3293             if (right.Unit() == DimensionUnit::PERCENT) {
3294                 right.Reset();
3295             }
3296             rightDimen = right;
3297         }
3298         CalcDimension top;
3299         if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
3300             if (top.Unit() == DimensionUnit::PERCENT) {
3301                 top.Reset();
3302             }
3303             topDimen = top;
3304         }
3305         CalcDimension bottom;
3306         if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
3307             if (bottom.Unit() == DimensionUnit::PERCENT) {
3308                 bottom.Reset();
3309             }
3310             bottomDimen = bottom;
3311         }
3312         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
3313     } else {
3314         return;
3315     }
3316 }
3317 
JsBorderImage(const JSCallbackInfo & info)3318 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
3319 {
3320     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3321     auto jsVal = info[0];
3322     if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
3323         RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
3324         uint8_t imageBorderBitsets = 0;
3325         ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
3326         return;
3327     }
3328     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3329     CHECK_NULL_VOID(!object->IsEmpty());
3330 
3331     RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
3332     uint8_t imageBorderBitsets = 0;
3333 
3334     auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
3335     CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
3336     std::string srcResult;
3337     std::string bundleName;
3338     std::string moduleName;
3339     GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
3340     borderImage->SetBundleName(bundleName);
3341     borderImage->SetModuleName(moduleName);
3342     if (valueSource->IsString() && !valueSource->ToString().empty()) {
3343         borderImage->SetSrc(valueSource->ToString());
3344         imageBorderBitsets |= BorderImage::SOURCE_BIT;
3345     } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
3346         borderImage->SetSrc(srcResult);
3347         imageBorderBitsets |= BorderImage::SOURCE_BIT;
3348     } else if (valueSource->IsObject()) {
3349         ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
3350     }
3351     auto valueOutset = object->GetProperty("outset");
3352     if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
3353         imageBorderBitsets |= BorderImage::OUTSET_BIT;
3354         ParseBorderImageOutset(valueOutset, borderImage);
3355     }
3356     auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
3357     if (!valueRepeat->IsNull()) {
3358         imageBorderBitsets |= BorderImage::REPEAT_BIT;
3359         ParseBorderImageRepeat(valueRepeat, borderImage);
3360     }
3361     auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
3362     if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
3363         imageBorderBitsets |= BorderImage::SLICE_BIT;
3364         ParseBorderImageSlice(valueSlice, borderImage);
3365     }
3366     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3367     if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
3368         imageBorderBitsets |= BorderImage::WIDTH_BIT;
3369         ParseBorderImageWidth(valueWidth, borderImage);
3370     }
3371     auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
3372     if (needFill->IsBoolean()) {
3373         borderImage->SetNeedFillCenter(needFill->ToBoolean());
3374     }
3375     ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
3376     info.ReturnSelf();
3377 }
3378 
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)3379 bool JSViewAbstract::ParseBorderImageDimension(
3380     const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
3381 {
3382     if (!args->IsObject()) {
3383         return false;
3384     }
3385     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3386     if (CheckLengthMetrics(object)) {
3387         LocalizedCalcDimension localizedCalcDimension;
3388         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
3389         borderImageDimension.topDimension = localizedCalcDimension.top;
3390         borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
3391         borderImageDimension.startDimension = localizedCalcDimension.start;
3392         borderImageDimension.endDimension = localizedCalcDimension.end;
3393         return true;
3394     }
3395     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
3396         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
3397         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
3398     for (uint32_t i = 0; i < keys.size(); i++) {
3399         CalcDimension currentDimension;
3400         auto dimensionValue = object->GetProperty(keys.at(i));
3401         if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
3402             auto direction = static_cast<BorderImageDirection>(i);
3403             switch (direction) {
3404                 case BorderImageDirection::LEFT:
3405                     borderImageDimension.leftDimension = currentDimension;
3406                     break;
3407                 case BorderImageDirection::RIGHT:
3408                     borderImageDimension.rightDimension = currentDimension;
3409                     break;
3410                 case BorderImageDirection::TOP:
3411                     borderImageDimension.topDimension = currentDimension;
3412                     break;
3413                 case BorderImageDirection::BOTTOM:
3414                     borderImageDimension.bottomDimension = currentDimension;
3415                     break;
3416                 default:
3417                     break;
3418             }
3419         }
3420     }
3421     return false;
3422 }
3423 
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3424 void JSViewAbstract::ParseBorderImageLengthMetrics(
3425     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3426 {
3427     for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
3428         auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
3429         if (!jsVal->IsObject()) {
3430             continue;
3431         }
3432         JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
3433         CalcDimension calcDimension;
3434         if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
3435             auto direction = static_cast<BorderImageDirection>(i);
3436             switch (direction) {
3437                 case BorderImageDirection::LEFT:
3438                     localizedCalcDimension.start = calcDimension;
3439                     break;
3440                 case BorderImageDirection::RIGHT:
3441                     localizedCalcDimension.end = calcDimension;
3442                     break;
3443                 case BorderImageDirection::TOP:
3444                     localizedCalcDimension.top = calcDimension;
3445                     break;
3446                 case BorderImageDirection::BOTTOM:
3447                     localizedCalcDimension.bottom = calcDimension;
3448                     break;
3449                 default:
3450                     break;
3451             }
3452         }
3453     }
3454 }
3455 
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)3456 bool JSViewAbstract::CheckJSCallbackInfo(
3457     const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
3458 {
3459     bool typeVerified = false;
3460     std::string unrecognizedType;
3461     for (const auto& infoType : infoTypes) {
3462         switch (infoType) {
3463             case JSCallbackInfoType::STRING:
3464                 if (tmpInfo->IsString()) {
3465                     typeVerified = true;
3466                 } else {
3467                     unrecognizedType += "string|";
3468                 }
3469                 break;
3470             case JSCallbackInfoType::NUMBER:
3471                 if (tmpInfo->IsNumber()) {
3472                     typeVerified = true;
3473                 } else {
3474                     unrecognizedType += "number|";
3475                 }
3476                 break;
3477             case JSCallbackInfoType::OBJECT:
3478                 if (tmpInfo->IsObject()) {
3479                     typeVerified = true;
3480                 } else {
3481                     unrecognizedType += "object|";
3482                 }
3483                 break;
3484             case JSCallbackInfoType::FUNCTION:
3485                 if (tmpInfo->IsFunction()) {
3486                     typeVerified = true;
3487                 } else {
3488                     unrecognizedType += "Function|";
3489                 }
3490                 break;
3491             default:
3492                 break;
3493         }
3494     }
3495     if (!typeVerified) {
3496         LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
3497             unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
3498     }
3499     return typeVerified || infoTypes.size() == 0;
3500 }
3501 
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)3502 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
3503 {
3504     switch (direction) {
3505         case NG::GradientDirection::LEFT:
3506             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3507             break;
3508         case NG::GradientDirection::RIGHT:
3509             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3510             break;
3511         case NG::GradientDirection::TOP:
3512             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3513             break;
3514         case NG::GradientDirection::BOTTOM:
3515             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3516             break;
3517         case NG::GradientDirection::LEFT_TOP:
3518             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3519             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3520             break;
3521         case NG::GradientDirection::LEFT_BOTTOM:
3522             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3523             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3524             break;
3525         case NG::GradientDirection::RIGHT_TOP:
3526             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3527             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3528             break;
3529         case NG::GradientDirection::RIGHT_BOTTOM:
3530             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3531             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3532             break;
3533         case NG::GradientDirection::NONE:
3534         case NG::GradientDirection::START_TO_END:
3535         case NG::GradientDirection::END_TO_START:
3536         default:
3537             break;
3538     }
3539 }
3540 
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)3541 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
3542 {
3543     if (!args->IsObject()) {
3544         return;
3545     }
3546     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
3547     NG::Gradient lineGradient;
3548     lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
3549     // angle
3550     std::optional<float> degree;
3551     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3552         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
3553     } else {
3554         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
3555     }
3556     if (degree) {
3557         lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
3558         degree.reset();
3559     }
3560     // direction
3561     auto direction = static_cast<NG::GradientDirection>(
3562         jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
3563         static_cast<int32_t>(NG::GradientDirection::NONE)));
3564     UpdateGradientWithDirection(lineGradient, direction);
3565     auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
3566     lineGradient.SetRepeat(repeating);
3567     NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
3568     ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
3569     bitset |= BorderImage::GRADIENT_BIT;
3570 }
3571 
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3572 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3573 {
3574     auto repeatString = args->ToString();
3575     if (repeatString == "Repeat") {
3576         borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
3577     } else if (repeatString == "Round") {
3578         borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
3579     } else if (repeatString == "Space") {
3580         borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
3581     } else {
3582         borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
3583     }
3584 }
3585 
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3586 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3587 {
3588     CalcDimension outsetDimension;
3589     if (ParseJsDimensionVp(args, outsetDimension)) {
3590         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
3591         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
3592         borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
3593         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
3594         return;
3595     }
3596     BorderImage::BorderImageOption option;
3597     ParseBorderImageDimension(args, option);
3598     if (option.startDimension.has_value()) {
3599         borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
3600     }
3601     if (option.endDimension.has_value()) {
3602         borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
3603     }
3604     if (option.leftDimension.has_value()) {
3605         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
3606     }
3607     if (option.rightDimension.has_value()) {
3608         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
3609     }
3610     if (option.topDimension.has_value()) {
3611         borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
3612     }
3613     if (option.bottomDimension.has_value()) {
3614         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
3615     }
3616 }
3617 
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3618 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3619 {
3620     CalcDimension sliceDimension;
3621     if (ParseJsDimensionVp(args, sliceDimension)) {
3622         borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
3623         borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
3624         borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
3625         borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
3626         return;
3627     }
3628     if (!args->IsObject()) {
3629         return;
3630     }
3631     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3632     if (CheckLengthMetrics(object)) {
3633         LocalizedCalcDimension localizedCalcDimension;
3634         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
3635         if (localizedCalcDimension.top.has_value()) {
3636             borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
3637         }
3638         if (localizedCalcDimension.bottom.has_value()) {
3639             borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
3640         }
3641         if (localizedCalcDimension.start.has_value()) {
3642             borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
3643         }
3644         if (localizedCalcDimension.end.has_value()) {
3645             borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
3646         }
3647         return;
3648     }
3649     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
3650         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
3651         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
3652     for (uint32_t i = 0; i < keys.size(); i++) {
3653         auto dimensionValue = object->GetProperty(keys.at(i));
3654         if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
3655             borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
3656         }
3657     }
3658 }
3659 
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3660 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3661 {
3662     CalcDimension widthDimension;
3663     if (ParseJsDimensionVp(args, widthDimension)) {
3664         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
3665         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
3666         borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
3667         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
3668         return;
3669     }
3670 
3671     BorderImage::BorderImageOption option;
3672     ParseBorderImageDimension(args, option);
3673     if (option.startDimension.has_value()) {
3674         borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
3675     }
3676     if (option.endDimension.has_value()) {
3677         borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
3678     }
3679     if (option.leftDimension.has_value()) {
3680         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
3681     }
3682     if (option.rightDimension.has_value()) {
3683         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
3684     }
3685     if (option.topDimension.has_value()) {
3686         borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
3687     }
3688     if (option.bottomDimension.has_value()) {
3689         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
3690     }
3691 }
3692 
JsBorderColor(const JSCallbackInfo & info)3693 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
3694 {
3695     ParseBorderColor(info[0]);
3696 }
3697 
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)3698 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
3699     const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
3700     const std::optional<Color>& colorBottom)
3701 {
3702     NG::BorderColorProperty borderColors;
3703     borderColors.startColor = colorStart;
3704     borderColors.endColor = colorEnd;
3705     borderColors.topColor = colorTop;
3706     borderColors.bottomColor = colorBottom;
3707     borderColors.multiValued = true;
3708     return borderColors;
3709 }
3710 
ParseBorderColor(const JSRef<JSVal> & args)3711 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
3712 {
3713     Color borderColor;
3714     if (ParseJsColor(args, borderColor)) {
3715         ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
3716     } else if (args->IsObject()) {
3717         CommonColor commonColor;
3718         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3719         if (ParseCommonEdgeColors(object, commonColor)) {
3720             ViewAbstractModel::GetInstance()->SetBorderColor(
3721                 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
3722             return;
3723         }
3724         ViewAbstractModel::GetInstance()->SetBorderColor(
3725             commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
3726     } else {
3727         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3728     }
3729 }
3730 
ParseOuterBorderColor(const JSRef<JSVal> & args)3731 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
3732 {
3733     Color borderColor;
3734     if (ParseJsColor(args, borderColor)) {
3735         ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
3736     } else if (args->IsObject()) {
3737         CommonColor commonColor;
3738         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3739         if (ParseCommonEdgeColors(object, commonColor)) {
3740             ViewAbstractModel::GetInstance()->SetOuterBorderColor(
3741                 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
3742             return;
3743         }
3744         ViewAbstractModel::GetInstance()->SetOuterBorderColor(
3745             commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
3746     } else {
3747         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3748     }
3749 }
3750 
JsBorderRadius(const JSCallbackInfo & info)3751 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
3752 {
3753     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3754         JSCallbackInfoType::OBJECT };
3755     auto jsVal = info[0];
3756     if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
3757         ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
3758         return;
3759     }
3760     ParseBorderRadius(jsVal);
3761 }
3762 
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)3763 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
3764     const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
3765     const std::optional<Dimension>& radiusBottomEnd)
3766 {
3767     NG::BorderRadiusProperty borderRadius;
3768     borderRadius.radiusTopStart = radiusTopStart;
3769     borderRadius.radiusTopEnd = radiusTopEnd;
3770     borderRadius.radiusBottomStart = radiusBottomStart;
3771     borderRadius.radiusBottomEnd = radiusBottomEnd;
3772     borderRadius.multiValued = true;
3773     return borderRadius;
3774 }
3775 
ParseBorderRadius(const JSRef<JSVal> & args)3776 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
3777 {
3778     CalcDimension borderRadius;
3779     if (ParseJsDimensionVp(args, borderRadius)) {
3780         ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
3781     } else if (args->IsObject()) {
3782         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3783         CalcDimension topLeft;
3784         CalcDimension topRight;
3785         CalcDimension bottomLeft;
3786         CalcDimension bottomRight;
3787         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
3788             ViewAbstractModel::GetInstance()->SetBorderRadius(
3789                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
3790                 return;
3791         }
3792         ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3793     }
3794 }
3795 
ParseOuterBorderRadius(const JSRef<JSVal> & args)3796 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
3797 {
3798     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
3799         return;
3800     }
3801     CalcDimension borderRadius;
3802     if (ParseJsDimensionVp(args, borderRadius)) {
3803         if (borderRadius.Unit() == DimensionUnit::PERCENT) {
3804             borderRadius.Reset();
3805         }
3806         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
3807     } else if (args->IsObject()) {
3808         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3809         CalcDimension topLeft;
3810         CalcDimension topRight;
3811         CalcDimension bottomLeft;
3812         CalcDimension bottomRight;
3813         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
3814             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
3815                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
3816         }
3817         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3818     }
3819 }
3820 
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)3821 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
3822 {
3823     ParseJsDimensionVp(object->GetProperty(key), radius);
3824 }
3825 
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)3826 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
3827 {
3828     if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
3829         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
3830         ParseJsLengthMetrics(startObj, radius);
3831     }
3832 }
3833 
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)3834 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
3835     CalcDimension& bottomLeft, CalcDimension& bottomRight)
3836 {
3837     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
3838         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
3839         CalcDimension topStart;
3840         CalcDimension topEnd;
3841         CalcDimension bottomStart;
3842         CalcDimension bottomEnd;
3843         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
3844         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
3845         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
3846         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
3847         topLeft = topStart;
3848         topRight = topEnd;
3849         bottomLeft = bottomStart;
3850         bottomRight = bottomEnd;
3851         return true;
3852     }
3853     GetBorderRadius("topLeft", object, topLeft);
3854     GetBorderRadius("topRight", object, topRight);
3855     GetBorderRadius("bottomLeft", object, bottomLeft);
3856     GetBorderRadius("bottomRight", object, bottomRight);
3857     return false;
3858 }
3859 
JsBorderStyle(const JSCallbackInfo & info)3860 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
3861 {
3862     ParseBorderStyle(info[0]);
3863 }
3864 namespace {
ConvertBorderStyle(int32_t value)3865 BorderStyle ConvertBorderStyle(int32_t value)
3866 {
3867     auto style = static_cast<BorderStyle>(value);
3868     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
3869         style = BorderStyle::SOLID;
3870     }
3871     return style;
3872 }
3873 
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)3874 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
3875 {
3876     style = static_cast<BorderStyle>(value);
3877     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
3878         return false;
3879     }
3880     return true;
3881 }
3882 } // namespace
3883 
ParseBorderStyle(const JSRef<JSVal> & args)3884 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
3885 {
3886     if (args->IsObject()) {
3887         std::optional<BorderStyle> styleLeft;
3888         std::optional<BorderStyle> styleRight;
3889         std::optional<BorderStyle> styleTop;
3890         std::optional<BorderStyle> styleBottom;
3891         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3892         auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
3893         if (leftValue->IsNumber()) {
3894             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3895         }
3896         auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
3897         if (rightValue->IsNumber()) {
3898             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3899         }
3900         auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3901         if (topValue->IsNumber()) {
3902             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3903         }
3904         auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3905         if (bottomValue->IsNumber()) {
3906             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3907         }
3908         ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3909         return;
3910     }
3911     if (args->IsNumber()) {
3912         auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3913         ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
3914         return;
3915     }
3916     ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3917 }
3918 
ParseOuterBorderStyle(const JSRef<JSVal> & args)3919 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
3920 {
3921     if (!args->IsObject() && !args->IsNumber()) {
3922         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3923         return;
3924     }
3925     if (args->IsObject()) {
3926         std::optional<BorderStyle> styleLeft;
3927         std::optional<BorderStyle> styleRight;
3928         std::optional<BorderStyle> styleTop;
3929         std::optional<BorderStyle> styleBottom;
3930         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3931         auto leftValue = object->GetProperty("left");
3932         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
3933             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3934         }
3935         auto rightValue = object->GetProperty("right");
3936         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
3937             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3938         }
3939         auto topValue = object->GetProperty("top");
3940         if (!topValue->IsUndefined() && topValue->IsNumber()) {
3941             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3942         }
3943         auto bottomValue = object->GetProperty("bottom");
3944         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
3945             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3946         }
3947         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3948         return;
3949     }
3950     auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3951     ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
3952 }
3953 
JsBlur(const JSCallbackInfo & info)3954 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
3955 {
3956     if (info.Length() == 0) {
3957         return;
3958     }
3959     double blur = 0.0;
3960     if (!ParseJsDouble(info[0], blur)) {
3961         return;
3962     }
3963 
3964     BlurOption blurOption;
3965     if (info.Length() > 1 && info[1]->IsObject()) {
3966         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
3967         ParseBlurOption(jsBlurOption, blurOption);
3968     }
3969     SysOptions sysOptions;
3970     sysOptions.disableSystemAdaptation = false;
3971     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
3972         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
3973         ParseSysOptions(jsSysOptions, sysOptions);
3974     }
3975     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
3976     ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption, sysOptions);
3977     info.SetReturnValue(info.This());
3978 }
3979 
JsMotionBlur(const JSCallbackInfo & info)3980 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
3981 {
3982     if (!info[0]->IsObject()) {
3983         return;
3984     }
3985     MotionBlurOption option;
3986     double x = 0.0;
3987     double y = 0.0;
3988     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
3989     JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
3990     if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
3991         JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
3992         ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
3993         ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
3994     }
3995     double radius = 0.0;
3996     if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
3997         radius = 0.0;
3998     }
3999     if (LessNotEqual(x, 0.0)) {
4000         x = 0.0;
4001     }
4002     if (LessNotEqual(y, 0.0)) {
4003         y = 0.0;
4004     }
4005     option.radius = radius;
4006     option.anchor.x = std::clamp(x, 0.0, 1.0);
4007     option.anchor.y = std::clamp(y, 0.0, 1.0);
4008     ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4009 }
4010 
JsColorBlend(const JSCallbackInfo & info)4011 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4012 {
4013     Color colorBlend;
4014     if (info[0]->IsUndefined()) {
4015         colorBlend = Color::TRANSPARENT;
4016         SetColorBlend(colorBlend);
4017         return;
4018     }
4019     if (!ParseJsColor(info[0], colorBlend)) {
4020         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4021             colorBlend = Color::TRANSPARENT;
4022             SetColorBlend(colorBlend);
4023         }
4024         return;
4025     }
4026     SetColorBlend(colorBlend);
4027     info.SetReturnValue(info.This());
4028 }
4029 
JsUseEffect(const JSCallbackInfo & info)4030 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4031 {
4032     if (info[0]->IsBoolean()) {
4033         auto effectType = EffectType::DEFAULT;
4034         if (info.Length() == 2 && info[1]->IsNumber()) {
4035             effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
4036             if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
4037                 effectType = EffectType::DEFAULT;
4038             }
4039         }
4040         ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
4041     }
4042 }
4043 
JsUseShadowBatching(const JSCallbackInfo & info)4044 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4045 {
4046     if (info[0]->IsBoolean()) {
4047         ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4048     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4049         ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4050     }
4051 }
4052 
JsBackdropBlur(const JSCallbackInfo & info)4053 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4054 {
4055     if (info.Length() == 0) {
4056         return;
4057     }
4058     double blur = 0.0;
4059     BlurOption blurOption;
4060     if (!ParseJsDouble(info[0], blur)) {
4061         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4062             return;
4063         }
4064     }
4065     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4066     if (info.Length() > 1 && info[1]->IsObject()) {
4067         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4068         ParseBlurOption(jsBlurOption, blurOption);
4069     }
4070     SysOptions sysOptions;
4071     sysOptions.disableSystemAdaptation = false;
4072     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
4073         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
4074         ParseSysOptions(jsSysOptions, sysOptions);
4075     }
4076     ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption, sysOptions);
4077     info.SetReturnValue(info.This());
4078 }
4079 
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4080 void JSViewAbstract::GetFractionStops(
4081     std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4082 {
4083     if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4084         return;
4085     }
4086     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4087     float tmpPos = -1.0f;
4088     size_t length = jsArray->Length();
4089     for (size_t i = 0; i < length; i++) {
4090         std::pair<float, float> fractionStop;
4091         JSRef<JSVal> item = jsArray->GetValueAt(i);
4092         if (!item->IsArray()) {
4093             continue;
4094         }
4095         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4096         if (subArray->Length() < 2) {
4097             continue;
4098         }
4099 
4100         double value = 0.0;
4101         if (ParseJsDouble(subArray->GetValueAt(0), value)) {
4102             value = std::clamp(value, 0.0, 1.0);
4103             fractionStop.first = static_cast<float>(value);
4104         }
4105         value = 0.0;
4106         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
4107             value = std::clamp(value, 0.0, 1.0);
4108             fractionStop.second = static_cast<float>(value);
4109         }
4110 
4111         if (fractionStop.second <= tmpPos) {
4112             fractionStops.clear();
4113             return;
4114         }
4115         tmpPos = fractionStop.second;
4116         fractionStops.push_back(fractionStop);
4117     }
4118 }
JsLinearGradientBlur(const JSCallbackInfo & info)4119 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
4120 {
4121     if (info.Length() < 2) { // 2 represents the least para num;
4122         return;
4123     }
4124     double blurRadius = 0.0;
4125     ParseJsDouble(info[0], blurRadius);
4126 
4127     std::vector<std::pair<float, float>> fractionStops;
4128     auto direction = GradientDirection::BOTTOM;
4129     if (info[1]->IsObject()) {
4130         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
4131         GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
4132         auto directionValue =
4133             jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
4134         if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
4135             directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
4136             directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
4137         }
4138         direction = static_cast<GradientDirection>(directionValue);
4139     }
4140     if (static_cast<int32_t>(fractionStops.size()) <= 1) {
4141         fractionStops.clear();
4142         fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
4143         fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
4144     }
4145     // Parse direction
4146     CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
4147     NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
4148     SetLinearGradientBlur(blurPara);
4149 }
4150 
JsBackgroundBrightness(const JSCallbackInfo & info)4151 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
4152 {
4153     double rate = 0.0;
4154     double lightUpDegree = 0.0;
4155     if (info[0]->IsObject()) {
4156         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4157         ParseJsDouble(jsObj->GetProperty("rate"), rate);
4158         ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
4159     }
4160     SetDynamicLightUp(rate, lightUpDegree);
4161 }
4162 
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)4163 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
4164 {
4165     if (info.Length() == 0) {
4166         return;
4167     }
4168     BrightnessOption option;
4169     if (info[0]->IsObject()) {
4170         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
4171         ParseBrightnessOption(jsOption, option);
4172     }
4173     SetBgDynamicBrightness(option);
4174 }
4175 
JsForegroundBrightness(const JSCallbackInfo & info)4176 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
4177 {
4178     if (info.Length() == 0) {
4179         return;
4180     }
4181     BrightnessOption option;
4182     if (info[0]->IsObject()) {
4183         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
4184         ParseBrightnessOption(jsOption, option);
4185     }
4186     SetFgDynamicBrightness(option);
4187 }
4188 
JsWindowBlur(const JSCallbackInfo & info)4189 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
4190 {
4191     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4192     auto jsVal = info[0];
4193     if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
4194         return;
4195     }
4196 
4197     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
4198     double progress = 0.0;
4199     ParseJsDouble(jsObj->GetProperty("percent"), progress);
4200     auto style = jsObj->GetPropertyValue<int32_t>("style",
4201         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
4202 
4203     progress = std::clamp(progress, 0.0, 1.0);
4204     style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
4205         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
4206 
4207     SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
4208     info.SetReturnValue(info.This());
4209 }
4210 
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)4211 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
4212     std::string& resName, bool isParseType)
4213 {
4214     if (!jsValue->IsString()) {
4215         return false;
4216     }
4217     std::string resPath = jsValue->ToString();
4218     std::smatch results;
4219     std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
4220     if (!std::regex_match(resPath, results, tokenRegex)) {
4221         return false;
4222     }
4223     targetModule = results[1];
4224     if (isParseType && !ConvertResourceType(results[2], resType)) {
4225         return false;
4226     }
4227     resName = resPath;
4228     return true;
4229 }
4230 
ConvertResourceType(const std::string & typeName,ResourceType & resType)4231 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
4232 {
4233     static const std::unordered_map<std::string, ResourceType> resTypeMap {
4234         { "color", ResourceType::COLOR },
4235         { "media", ResourceType::MEDIA },
4236         { "float", ResourceType::FLOAT },
4237         { "string", ResourceType::STRING },
4238         { "plural", ResourceType::PLURAL },
4239         { "pattern", ResourceType::PATTERN },
4240         { "boolean", ResourceType::BOOLEAN },
4241         { "integer", ResourceType::INTEGER },
4242         { "strarray", ResourceType::STRARRAY },
4243         { "intarray", ResourceType::INTARRAY },
4244     };
4245     auto it = resTypeMap.find(typeName);
4246     if (it == resTypeMap.end()) {
4247         return false;
4248     }
4249     resType = it->second;
4250     return true;
4251 }
4252 
CompleteResourceObject(JSRef<JSObject> & jsObj)4253 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
4254 {
4255     std::string bundleName;
4256     std::string moduleName;
4257     int32_t resId = -1;
4258     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
4259 }
4260 
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)4261 void JSViewAbstract::CompleteResourceObjectWithBundleName(
4262     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
4263 {
4264     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
4265 }
4266 
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)4267 void JSViewAbstract::CompleteResourceObjectInner(
4268     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
4269 {
4270     // dynamic $r raw input format is
4271     // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
4272     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
4273     ResourceType resType;
4274 
4275     std::string targetModule;
4276     std::string resName;
4277     if (resId->IsString()) {
4278         JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
4279         int32_t typeNum = -1;
4280         if (type->IsNumber()) {
4281             typeNum = type->ToNumber<int32_t>();
4282         }
4283         if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
4284             return;
4285         }
4286         CompleteResourceObjectFromId(type, jsObj, resType, resName);
4287     } else if (resId->IsNumber()) {
4288         resIdValue = resId->ToNumber<int32_t>();
4289         if (resIdValue == -1) {
4290             CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
4291         }
4292     }
4293 
4294     JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
4295     if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
4296         bundleName = GetBundleNameFromContainer();
4297         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
4298     }
4299     if (moduleName == DEFAULT_HAR_MODULE_NAME) {
4300         moduleName = GetModuleNameFromContainer();
4301         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
4302     }
4303 }
4304 
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)4305 bool JSViewAbstract::ParseJsDimensionNG(
4306     const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
4307 {
4308     if (jsValue->IsNumber()) {
4309         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
4310         return true;
4311     }
4312     if (jsValue->IsString()) {
4313         auto value = jsValue->ToString();
4314         if (!isSupportPercent && value.back() == '%') {
4315             return false;
4316         }
4317         return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
4318     }
4319     if (jsValue->IsObject()) {
4320         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4321         CompleteResourceObject(jsObj);
4322         JSRef<JSVal> resId = jsObj->GetProperty("id");
4323         if (!resId->IsNumber()) {
4324             return false;
4325         }
4326         auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4327         if (resType == UNKNOWN_RESOURCE_TYPE) {
4328             return false;
4329         }
4330         auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4331         auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4332         if (!resourceWrapper) {
4333             return false;
4334         }
4335         auto resIdNum = resId->ToNumber<int32_t>();
4336         if (resIdNum == -1) {
4337             if (!IsGetResourceByName(jsObj)) {
4338                 return false;
4339             }
4340             JSRef<JSVal> args = jsObj->GetProperty("params");
4341             if (!args->IsArray()) {
4342                 return false;
4343             }
4344             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4345             auto param = params->GetValueAt(0);
4346             if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4347                 auto value = resourceWrapper->GetStringByName(param->ToString());
4348                 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
4349             }
4350             if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4351                 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
4352                 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
4353                 return true;
4354             }
4355             result = resourceWrapper->GetDimensionByName(param->ToString());
4356             return true;
4357         }
4358         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4359             auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4360             return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
4361         }
4362         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4363             auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
4364             StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
4365             return true;
4366         }
4367         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4368             result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
4369             return true;
4370         }
4371     }
4372     return false;
4373 }
4374 
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)4375 bool JSViewAbstract::ParseJsLengthNG(
4376     const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
4377 {
4378     if (jsValue->IsNumber()) {
4379         if (std::isnan(jsValue->ToNumber<double>())) {
4380             return false;
4381         }
4382         result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
4383         return true;
4384     } else if (jsValue->IsObject()) {
4385         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4386         JSRef<JSVal> value = jsObj->GetProperty("value");
4387         if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
4388             return false;
4389         }
4390         DimensionUnit unit = defaultUnit;
4391         JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
4392         if (jsUnit->IsNumber()) {
4393             if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
4394                 return false;
4395             }
4396             unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
4397         }
4398         result = NG::CalcLength(value->ToNumber<double>(), unit);
4399         return true;
4400     }
4401 
4402     return false;
4403 }
4404 
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)4405 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
4406 {
4407     // 'vp' -> the value varies with pixel density of device.
4408     return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
4409 }
4410 
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)4411 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
4412 {
4413     if (jsValue->IsNumber()) {
4414         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
4415         return true;
4416     }
4417     if (jsValue->IsString()) {
4418         result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
4419         return true;
4420     }
4421     if (!jsValue->IsObject()) {
4422         return false;
4423     }
4424     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4425     CompleteResourceObject(jsObj);
4426     JSRef<JSVal> resId = jsObj->GetProperty("id");
4427     if (!resId->IsNumber()) {
4428         return false;
4429     }
4430     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4431     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4432     if (!resourceWrapper) {
4433         return false;
4434     }
4435     auto resIdNum = resId->ToNumber<int32_t>();
4436     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4437     if (resType == UNKNOWN_RESOURCE_TYPE) {
4438         return false;
4439     }
4440     if (resIdNum == -1) {
4441         if (!IsGetResourceByName(jsObj)) {
4442             return false;
4443         }
4444         JSRef<JSVal> args = jsObj->GetProperty("params");
4445         if (!args->IsArray()) {
4446             return false;
4447         }
4448         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4449         auto param = params->GetValueAt(0);
4450         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4451             auto value = resourceWrapper->GetStringByName(param->ToString());
4452             result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
4453             return true;
4454         }
4455         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4456             auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
4457             result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
4458             return true;
4459         }
4460         result = resourceWrapper->GetDimensionByName(param->ToString());
4461         return true;
4462     }
4463     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4464         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4465         result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
4466         return true;
4467     }
4468     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4469         auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
4470         result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
4471         return true;
4472     }
4473     result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
4474     return true;
4475 }
4476 
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)4477 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
4478 {
4479     // 'vp' -> the value varies with pixel density of device.
4480     return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
4481 }
4482 
ParseJsLengthMetricsVp(const JSRef<JSObject> & jsObj,CalcDimension & result)4483 bool JSViewAbstract::ParseJsLengthMetricsVp(const JSRef<JSObject>& jsObj, CalcDimension& result)
4484 {
4485     auto value = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
4486     if (!value->IsNumber()) {
4487         return false;
4488     }
4489     auto unit = DimensionUnit::VP;
4490     auto jsUnit = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
4491     if (jsUnit->IsNumber()) {
4492         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
4493     }
4494     CalcDimension dimension(value->ToNumber<double>(), unit);
4495     result = dimension;
4496     return true;
4497 }
4498 
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)4499 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
4500 {
4501     // 'vp' -> the value varies with pixel density of device.
4502     return ParseJsDimension(jsValue, result, DimensionUnit::VP);
4503 }
4504 
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)4505 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
4506 {
4507     // the 'fp' unit is used for text scenes.
4508     return ParseJsDimension(jsValue, result, DimensionUnit::FP);
4509 }
4510 
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)4511 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
4512 {
4513     // the 'fp' unit is used for text scenes.
4514     return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
4515 }
4516 
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)4517 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
4518 {
4519     return ParseJsDimension(jsValue, result, DimensionUnit::PX);
4520 }
4521 
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)4522 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
4523 {
4524     if (!jsValue->IsObject()) {
4525         return false;
4526     }
4527     auto colorObj = JSRef<JSObject>::Cast(jsValue);
4528     auto toNumericProp = colorObj->GetProperty("toNumeric");
4529     if (toNumericProp->IsFunction()) {
4530         auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
4531         result.SetValue(colorVal->ToNumber<uint32_t>());
4532 
4533         auto resourceIdProp = colorObj->GetProperty("getResourceId");
4534         if (resourceIdProp->IsFunction()) {
4535             auto resourceIdVal = JSRef<JSFunc>::Cast(resourceIdProp)->Call(colorObj, 0, nullptr);
4536             result.SetResourceId(resourceIdVal->ToNumber<uint32_t>());
4537         }
4538 
4539         return true;
4540     }
4541     return false;
4542 }
4543 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)4544 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
4545 {
4546     if (jsValue->IsNumber()) {
4547         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
4548         return true;
4549     }
4550     if (jsValue->IsString()) {
4551         auto value = jsValue->ToString();
4552         return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
4553     }
4554     if (jsValue->IsObject()) {
4555         auto jsObj = JSRef<JSObject>::Cast(jsValue);
4556         auto valObj = jsObj->GetProperty("value");
4557         if (valObj->IsUndefined() || valObj->IsNull()) {
4558             return false;
4559         }
4560         double value = valObj->ToNumber<double>();
4561         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
4562         result = CalcDimension(value, unit);
4563         return true;
4564     }
4565     return false;
4566 }
4567 
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)4568 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
4569 {
4570     return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
4571 }
4572 
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)4573 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
4574 {
4575     if (!jsValue->IsObject()) {
4576         return false;
4577     }
4578     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4579     CompleteResourceObject(jsObj);
4580     if (jsObj->IsEmpty()) {
4581         return false;
4582     }
4583     JSRef<JSVal> id = jsObj->GetProperty("id");
4584     if (!id->IsNumber()) {
4585         return false;
4586     }
4587 
4588     auto resId = id->ToNumber<int32_t>();
4589     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4590     if (resType == UNKNOWN_RESOURCE_TYPE) {
4591         return false;
4592     }
4593 
4594     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4595     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4596     if (!resourceWrapper) {
4597         return false;
4598     }
4599 
4600     if (resId == -1) {
4601         return ParseResourceToDoubleByName(jsObj, resType, resourceWrapper, result);
4602     }
4603     return ParseResourceToDoubleById(resId, resType, resourceWrapper, result);
4604 }
4605 
ParseResourceToDoubleByName(const JSRef<JSObject> & jsObj,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)4606 bool JSViewAbstract::ParseResourceToDoubleByName(
4607     const JSRef<JSObject>& jsObj, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
4608 {
4609     if (!IsGetResourceByName(jsObj)) {
4610         return false;
4611     }
4612     JSRef<JSVal> args = jsObj->GetProperty("params");
4613     if (!args->IsArray()) {
4614         return false;
4615     }
4616     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4617     auto param = params->GetValueAt(0);
4618     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4619         auto numberString = resourceWrapper->GetStringByName(param->ToString());
4620         return StringUtils::StringToDouble(numberString, result);
4621     }
4622     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4623         result = resourceWrapper->GetIntByName(param->ToString());
4624         return true;
4625     }
4626     if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4627         result = resourceWrapper->GetDoubleByName(param->ToString());
4628         return true;
4629     }
4630     return false;
4631 }
4632 
ParseResourceToDoubleById(int32_t resId,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)4633 bool JSViewAbstract::ParseResourceToDoubleById(
4634     int32_t resId, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
4635 {
4636     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4637         auto numberString = resourceWrapper->GetString(resId);
4638         return StringUtils::StringToDouble(numberString, result);
4639     }
4640     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4641         result = resourceWrapper->GetInt(resId);
4642         return true;
4643     }
4644     if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4645         result = resourceWrapper->GetDouble(resId);
4646         return true;
4647     }
4648     return false;
4649 }
4650 
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)4651 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
4652 {
4653     if (jsValue->IsNumber()) {
4654         result = jsValue->ToNumber<double>();
4655         return true;
4656     }
4657     if (jsValue->IsString()) {
4658         return StringUtils::StringToDouble(jsValue->ToString(), result);
4659     }
4660     if (jsValue->IsObject()) {
4661         return ParseResourceToDouble(jsValue, result);
4662     }
4663     return false;
4664 }
4665 
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)4666 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
4667 {
4668     if (jsValue->IsNumber()) {
4669         result = jsValue->ToNumber<int32_t>();
4670         return true;
4671     }
4672     if (jsValue->IsString()) {
4673         result = StringUtils::StringToInt(jsValue->ToString());
4674         return true;
4675     }
4676     if (!jsValue->IsObject()) {
4677         return false;
4678     }
4679     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4680     CompleteResourceObject(jsObj);
4681     JSRef<JSVal> resId = jsObj->GetProperty("id");
4682     if (!resId->IsNumber()) {
4683         return false;
4684     }
4685 
4686     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4687     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4688     if (!resourceWrapper) {
4689         return false;
4690     }
4691 
4692     auto resIdNum = resId->ToNumber<int32_t>();
4693     if (resIdNum == -1) {
4694         if (!IsGetResourceByName(jsObj)) {
4695             return false;
4696         }
4697         JSRef<JSVal> args = jsObj->GetProperty("params");
4698         if (!args->IsArray()) {
4699             return false;
4700         }
4701         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4702         auto param = params->GetValueAt(0);
4703         result = resourceWrapper->GetIntByName(param->ToString());
4704         return true;
4705     }
4706     result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
4707     return true;
4708 }
4709 
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)4710 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
4711 {
4712     if (!jsValue->IsObject()) {
4713         return false;
4714     }
4715     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4716     CompleteResourceObject(jsObj);
4717 
4718     auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
4719     if (ok) {
4720         JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
4721         if (jsOpacityRatio->IsNumber()) {
4722             double opacityRatio = jsOpacityRatio->ToNumber<double>();
4723             result = result.BlendOpacity(opacityRatio);
4724         }
4725     }
4726     return ok;
4727 }
4728 
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)4729 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
4730 {
4731     JSRef<JSVal> resId = jsObj->GetProperty("id");
4732     if (!resId->IsNumber()) {
4733         return false;
4734     }
4735 
4736     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4737     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4738     if (!resourceWrapper) {
4739         return false;
4740     }
4741 
4742     auto resIdNum = resId->ToNumber<int32_t>();
4743     if (resIdNum == -1) {
4744         if (!IsGetResourceByName(jsObj)) {
4745             return false;
4746         }
4747         JSRef<JSVal> args = jsObj->GetProperty("params");
4748         if (!args->IsArray()) {
4749             return false;
4750         }
4751         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4752         auto param = params->GetValueAt(0);
4753         result = resourceWrapper->GetColorByName(param->ToString());
4754         return true;
4755     }
4756 
4757     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4758     if (type == static_cast<int32_t>(ResourceType::STRING)) {
4759         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4760         return Color::ParseColorString(value, result);
4761     }
4762     if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
4763         auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
4764         result = Color(ColorAlphaAdapt(value));
4765         return true;
4766     }
4767     if (type == static_cast<int32_t>(ResourceType::COLOR)) {
4768         result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
4769         result.SetResourceId(resId->ToNumber<uint32_t>());
4770         return true;
4771     }
4772     return false;
4773 }
4774 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)4775 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
4776 {
4777     if (jsValue->IsNumber()) {
4778         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
4779         return true;
4780     }
4781     if (jsValue->IsString()) {
4782         return Color::ParseColorString(jsValue->ToString(), result);
4783     }
4784     if (jsValue->IsObject()) {
4785         return ParseJsColorFromResource(jsValue, result);
4786     }
4787     return false;
4788 }
4789 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)4790 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
4791 {
4792     if (jsValue->IsNumber()) {
4793         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
4794         return true;
4795     }
4796     if (jsValue->IsString()) {
4797         return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
4798     }
4799     if (!jsValue->IsObject()) {
4800         return false;
4801     }
4802     return ParseJsColorFromResource(jsValue, result);
4803 }
4804 
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)4805 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
4806 {
4807     if (jsValue->IsString()) {
4808         std::string colorStr = jsValue->ToString();
4809         if (colorStr.compare("invert") == 0) {
4810             strategy = ForegroundColorStrategy::INVERT;
4811             return true;
4812         }
4813     }
4814     return false;
4815 }
4816 
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)4817 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
4818 {
4819     if (jsValue->IsString()) {
4820         std::string colorStr = jsValue->ToString();
4821         if (colorStr.compare("average") == 0) {
4822             strategy = ShadowColorStrategy::AVERAGE;
4823             return true;
4824         } else if (colorStr.compare("primary") == 0) {
4825             strategy = ShadowColorStrategy::PRIMARY;
4826             return true;
4827         }
4828     }
4829     return false;
4830 }
4831 
ParseJsSymbolCustomFamilyNames(std::vector<std::string> & customFamilyNames,const JSRef<JSVal> & jsValue)4832 void JSViewAbstract::ParseJsSymbolCustomFamilyNames(std::vector<std::string>& customFamilyNames,
4833     const JSRef<JSVal>& jsValue)
4834 {
4835     if (jsValue->IsNull() || jsValue->IsUndefined()) {
4836         return;
4837     }
4838     if (!jsValue->IsObject()) {
4839         return;
4840     }
4841     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4842     CompleteResourceObject(jsObj);
4843     JSRef<JSVal> resId = jsObj->GetProperty("id");
4844     if (resId->IsNull() || !resId->IsNumber()) {
4845         return;
4846     }
4847     auto resourceObject = GetResourceObject(jsObj);
4848     std::string bundleName = resourceObject->GetBundleName();
4849     std::string moduleName = resourceObject->GetModuleName();
4850     auto customSymbolFamilyName = bundleName + "_" + moduleName + CUSTOM_SYMBOL_SUFFIX;
4851     std::replace(customSymbolFamilyName.begin(), customSymbolFamilyName.end(), '.', '_');
4852     customFamilyNames.push_back(customSymbolFamilyName);
4853 }
4854 
CheckResource(RefPtr<ResourceObject> resourceObject,RefPtr<ResourceWrapper> resourceWrapper)4855 bool JSViewAbstract::CheckResource(RefPtr<ResourceObject> resourceObject, RefPtr<ResourceWrapper> resourceWrapper)
4856 {
4857     if (!resourceWrapper) {
4858         return false;
4859     }
4860     if (!resourceObject) {
4861         return false;
4862     }
4863     return true;
4864 }
4865 
CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper,JSRef<JSVal> & resId,std::uint32_t & symbolId)4866 bool JSViewAbstract::CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper, JSRef<JSVal>& resId,
4867     std::uint32_t& symbolId)
4868 {
4869     auto strValue = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4870     if (!strValue.empty()) {
4871         auto customSymbolId = static_cast<uint32_t>(strtol(strValue.c_str(), nullptr, 16));
4872         symbolId = customSymbolId;
4873         return true;
4874     }
4875     return false;
4876 }
4877 
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)4878 bool JSViewAbstract::ParseJsSymbolId(
4879     const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
4880 {
4881     if (jsValue->IsNull() || jsValue->IsUndefined()) {
4882         symbolId = 0;
4883         return false;
4884     }
4885     if (!jsValue->IsObject()) {
4886         return false;
4887     }
4888     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4889     CompleteResourceObject(jsObj);
4890     JSRef<JSVal> resId = jsObj->GetProperty("id");
4891     if (resId->IsNull() || !resId->IsNumber()) {
4892         return false;
4893     }
4894     auto resourceObject = GetResourceObject(jsObj);
4895     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4896     symbolResourceObject = resourceObject;
4897     if (CheckCustomSymbolId(resourceWrapper, resId, symbolId)) {
4898         return true;
4899     }
4900     if (!CheckResource(resourceObject, resourceWrapper)) {
4901         return false;
4902     }
4903     auto resIdNum = resId->ToNumber<int32_t>();
4904     if (resIdNum == -1) {
4905         if (!IsGetResourceByName(jsObj)) {
4906             return false;
4907         }
4908         JSRef<JSVal> args = jsObj->GetProperty("params");
4909         if (!args->IsArray()) {
4910             return false;
4911         }
4912         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4913         auto param = params->GetValueAt(0);
4914         auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
4915         if (!symbol) {
4916             return false;
4917         }
4918         symbolId = symbol;
4919         return true;
4920     }
4921 
4922     auto symbol = resourceWrapper->GetSymbolById(resIdNum);
4923     if (!symbol) {
4924         return false;
4925     }
4926     symbolId = symbol;
4927     return true;
4928 }
4929 
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)4930 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
4931 {
4932     if (!jsValue->IsArray()) {
4933         return false;
4934     }
4935     if (jsValue->IsArray()) {
4936         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
4937         for (size_t i = 0; i < array->Length(); i++) {
4938             JSRef<JSVal> value = array->GetValueAt(i);
4939             if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
4940                 return false;
4941             }
4942             if (value->IsNumber()) {
4943                 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
4944                 continue;
4945             } else if (value->IsString()) {
4946                 Color color;
4947                 Color::ParseColorString(value->ToString(), color);
4948                 result.emplace_back(color);
4949                 continue;
4950             } else {
4951                 Color color;
4952                 ParseJsColorFromResource(value, color);
4953                 result.emplace_back(color);
4954             }
4955         }
4956         return true;
4957     }
4958     return false;
4959 }
4960 
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)4961 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
4962 {
4963     result.clear();
4964     if (!jsValue->IsString() && !jsValue->IsObject()) {
4965         return false;
4966     }
4967     if (jsValue->IsString()) {
4968         result = ConvertStrToFontFamilies(jsValue->ToString());
4969         return true;
4970     }
4971     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4972     CompleteResourceObject(jsObj);
4973     JSRef<JSVal> resId = jsObj->GetProperty("id");
4974     if (!resId->IsNumber()) {
4975         return false;
4976     }
4977 
4978     auto resourceObject = GetResourceObject(jsObj);
4979     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4980     if (!resourceWrapper) {
4981         return false;
4982     }
4983 
4984     auto resIdNum = resId->ToNumber<int32_t>();
4985     if (resIdNum == -1) {
4986         if (!IsGetResourceByName(jsObj)) {
4987             return false;
4988         }
4989         JSRef<JSVal> args = jsObj->GetProperty("params");
4990         if (!args->IsArray()) {
4991             return false;
4992         }
4993         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4994         auto param = params->GetValueAt(0);
4995         result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
4996         return true;
4997     }
4998     result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
4999     return true;
5000 }
5001 
ParseJsStringObj(const JSRef<JSVal> & jsValue,std::string & result)5002 bool JSViewAbstract::ParseJsStringObj(const JSRef<JSVal>& jsValue, std::string& result)
5003 {
5004     if (!jsValue->IsObject()) {
5005         return false;
5006     }
5007     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5008     CompleteResourceObject(jsObj);
5009     JSRef<JSVal> resId = jsObj->GetProperty("id");
5010     if (!resId->IsNumber()) {
5011         return false;
5012     }
5013     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5014     if (type == UNKNOWN_RESOURCE_TYPE) {
5015         return false;
5016     }
5017     JSRef<JSVal> args = jsObj->GetProperty("params");
5018     if (!args->IsArray()) {
5019         return false;
5020     }
5021     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5022     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5023     if (!resourceWrapper) {
5024         return false;
5025     }
5026     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5027     auto resIdNum = resId->ToNumber<int32_t>();
5028     if (resIdNum == -1) {
5029         if (!IsGetResourceByName(jsObj)) {
5030             return false;
5031         }
5032         auto param = params->GetValueAt(0);
5033         if (type == static_cast<int32_t>(ResourceType::STRING)) {
5034             auto originStr = resourceWrapper->GetStringByName(param->ToString());
5035             ReplaceHolder(originStr, params, 1);
5036             result = originStr;
5037         } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5038             auto countJsVal = params->GetValueAt(1);
5039             int count = 0;
5040             if (!countJsVal->IsNumber()) {
5041                 return false;
5042             }
5043             count = countJsVal->ToNumber<int>();
5044             auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5045             ReplaceHolder(pluralStr, params, 2); // params[2] applys pluralStr.
5046             result = pluralStr;
5047         } else {
5048             return false;
5049         }
5050         return true;
5051     }
5052     if (type == static_cast<int32_t>(ResourceType::STRING)) {
5053         auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5054         ReplaceHolder(originStr, params, 0);
5055         result = originStr;
5056     } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5057         auto countJsVal = params->GetValueAt(0);
5058         int count = 0;
5059         if (!countJsVal->IsNumber()) {
5060             return false;
5061         }
5062         count = countJsVal->ToNumber<int>();
5063         auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5064         ReplaceHolder(pluralStr, params, 1);
5065         result = pluralStr;
5066     } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5067         result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5068     } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5069         result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5070     } else {
5071         return false;
5072     }
5073     return true;
5074 }
5075 
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5076 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5077 {
5078     if (jsValue->IsString()) {
5079         result = jsValue->ToString();
5080         return true;
5081     }
5082     return ParseJsStringObj(jsValue, result);
5083 }
5084 
ParseJsString(const JSRef<JSVal> & jsValue,std::u16string & result)5085 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::u16string& result)
5086 {
5087     std::string u8Result;
5088     if (jsValue->IsString()) {
5089         result = jsValue->ToU16String();
5090         return true;
5091     }
5092     bool ret = ParseJsStringObj(jsValue, u8Result);
5093     if (ret) {
5094         result = UtfUtils::Str8DebugToStr16(u8Result);
5095         return true;
5096     }
5097     return false;
5098 }
5099 
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5100 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5101 {
5102     if (!jsValue->IsObject() && !jsValue->IsString()) {
5103         return false;
5104     }
5105     if (jsValue->IsString()) {
5106         result = jsValue->ToString();
5107         return true;
5108     }
5109     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5110     CompleteResourceObject(jsObj);
5111     return ParseJSMediaInternal(jsObj, result);
5112 }
5113 
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5114 bool JSViewAbstract::ParseJsMediaWithBundleName(
5115     const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5116 {
5117     if (!jsValue->IsObject() && !jsValue->IsString()) {
5118         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5119     }
5120     if (jsValue->IsString()) {
5121         result = jsValue->ToString();
5122         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5123     }
5124     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5125     CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5126     return ParseJSMediaInternal(jsObj, result);
5127 }
5128 
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5129 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5130 {
5131     int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5132     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5133     if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5134         auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5135         auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5136         CHECK_NULL_RETURN(resourceWrapper, false);
5137         if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5138             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5139             if (!args->IsArray()) {
5140                 return false;
5141             }
5142             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5143             auto fileName = params->GetValueAt(0);
5144             if (!fileName->IsString()) {
5145                 return false;
5146             }
5147             result = resourceWrapper->GetRawfile(fileName->ToString());
5148             return true;
5149         }
5150         auto resIdNum = resId->ToNumber<int32_t>();
5151         if (resIdNum == -1) {
5152             if (!IsGetResourceByName(jsObj)) {
5153                 return false;
5154             }
5155             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5156             if (!args->IsArray()) {
5157                 return false;
5158             }
5159             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5160             auto param = params->GetValueAt(0);
5161             if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5162                 result = resourceWrapper->GetMediaPathByName(param->ToString());
5163                 return true;
5164             }
5165             if (type == static_cast<int32_t>(ResourceType::STRING)) {
5166                 result = resourceWrapper->GetStringByName(param->ToString());
5167                 return true;
5168             }
5169             return false;
5170         } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5171             result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5172             return true;
5173         } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5174             result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5175             return true;
5176         }
5177     }
5178     return false;
5179 }
5180 
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5181 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
5182     const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
5183 {
5184     auto vm = info.GetVm();
5185     auto globalObj = JSNApi::GetGlobalObject(vm);
5186     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
5187     JsiValue jsiValue(globalFunc);
5188     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
5189     if (!globalFuncRef->IsFunction()) {
5190         return;
5191     }
5192     if (modifierNormalObj->IsUndefined()) {
5193         symbolApply.onApply = nullptr;
5194     } else {
5195         RefPtr<JsFunction> jsFunc =
5196             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
5197         auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
5198                            modifierNormal = std::move(modifierNormalObj),
5199                            modifierSelected = std::move(modifierSelectedObj)](
5200                            WeakPtr<NG::FrameNode> frameNode, std::string type) {
5201             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5202             auto node = frameNode.Upgrade();
5203             CHECK_NULL_VOID(node);
5204             JSRef<JSVal> params[SECOND_INDEX];
5205             if (type == "normal") {
5206                 params[0] = modifierNormal;
5207             } else if (!modifierSelected->IsUndefined()) {
5208                 params[0] = modifierSelected;
5209             }
5210             params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
5211             PipelineContext::SetCallBackNode(node);
5212             func->ExecuteJS(SECOND_INDEX, params);
5213         };
5214         symbolApply.onApply = onApply;
5215     }
5216 }
5217 
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)5218 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
5219 {
5220     if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
5221         return false;
5222     }
5223 
5224     if (jsValue->IsBoolean()) {
5225         result = jsValue->ToBoolean();
5226         return true;
5227     }
5228 
5229     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5230     CompleteResourceObject(jsObj);
5231     int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5232     if (resType == UNKNOWN_RESOURCE_TYPE) {
5233         return false;
5234     }
5235 
5236     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5237     if (!resId->IsNumber()) {
5238         return false;
5239     }
5240 
5241     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5242     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5243     if (!resourceWrapper) {
5244         return false;
5245     }
5246 
5247     auto resIdNum = resId->ToNumber<int32_t>();
5248     if (resIdNum == -1) {
5249         if (!IsGetResourceByName(jsObj)) {
5250             return false;
5251         }
5252         JSRef<JSVal> args = jsObj->GetProperty("params");
5253         if (!args->IsArray()) {
5254             return false;
5255         }
5256         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5257         auto param = params->GetValueAt(0);
5258         if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
5259             result = resourceWrapper->GetBooleanByName(param->ToString());
5260             return true;
5261         }
5262         return false;
5263     }
5264 
5265     if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
5266         result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
5267         return true;
5268     }
5269     return false;
5270 }
5271 
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)5272 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
5273 {
5274     return ParseJsInteger<uint32_t>(jsValue, result);
5275 }
5276 
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)5277 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
5278 {
5279     return ParseJsInteger<int32_t>(jsValue, result);
5280 }
5281 
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)5282 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
5283 {
5284     if (!jsValue->IsArray() && !jsValue->IsObject()) {
5285         return false;
5286     }
5287     if (jsValue->IsArray()) {
5288         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5289         for (size_t i = 0; i < array->Length(); i++) {
5290             JSRef<JSVal> value = array->GetValueAt(i);
5291             if (value->IsNumber()) {
5292                 result.emplace_back(value->ToNumber<uint32_t>());
5293             } else if (value->IsObject()) {
5294                 uint32_t singleResInt;
5295                 if (ParseJsInteger(value, singleResInt)) {
5296                     result.emplace_back(singleResInt);
5297                 } else {
5298                     return false;
5299                 }
5300             } else {
5301                 return false;
5302             }
5303         }
5304         return true;
5305     }
5306     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5307     CompleteResourceObject(jsObj);
5308     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5309     if (resType == UNKNOWN_RESOURCE_TYPE) {
5310         return false;
5311     }
5312     JSRef<JSVal> resId = jsObj->GetProperty("id");
5313     if (!resId->IsNumber()) {
5314         return false;
5315     }
5316     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5317     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5318     if (!resourceWrapper) {
5319         return false;
5320     }
5321     auto resIdNum = resId->ToNumber<int32_t>();
5322     if (resIdNum == -1) {
5323         if (!IsGetResourceByName(jsObj)) {
5324             return false;
5325         }
5326         JSRef<JSVal> args = jsObj->GetProperty("params");
5327         if (!args->IsArray()) {
5328             return false;
5329         }
5330         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5331         auto param = params->GetValueAt(0);
5332         if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
5333             result = resourceWrapper->GetIntArrayByName(param->ToString());
5334             return true;
5335         }
5336         return false;
5337     }
5338     if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
5339         result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
5340         return true;
5341     }
5342     return false;
5343 }
5344 
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5345 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5346 {
5347     if (!jsValue->IsArray() && !jsValue->IsObject()) {
5348         return false;
5349     }
5350     if (jsValue->IsArray()) {
5351         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5352         for (size_t i = 0; i < array->Length(); i++) {
5353             JSRef<JSVal> value = array->GetValueAt(i);
5354             if (value->IsString()) {
5355                 result.emplace_back(value->ToString());
5356             } else if (value->IsObject()) {
5357                 std::string singleResStr;
5358                 if (ParseJsString(value, singleResStr)) {
5359                     result.emplace_back(singleResStr);
5360                 } else {
5361                     return false;
5362                 }
5363             } else {
5364                 return false;
5365             }
5366         }
5367         return true;
5368     }
5369     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5370     CompleteResourceObject(jsObj);
5371     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5372     if (resType == UNKNOWN_RESOURCE_TYPE) {
5373         return false;
5374     }
5375     JSRef<JSVal> resId = jsObj->GetProperty("id");
5376     if (!resId->IsNumber()) {
5377         return false;
5378     }
5379     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5380     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5381     if (!resourceWrapper) {
5382         return false;
5383     }
5384     auto resIdNum = resId->ToNumber<int32_t>();
5385     if (resIdNum == -1) {
5386         if (!IsGetResourceByName(jsObj)) {
5387             return false;
5388         }
5389         JSRef<JSVal> args = jsObj->GetProperty("params");
5390         if (!args->IsArray()) {
5391             return false;
5392         }
5393         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5394         auto param = params->GetValueAt(0);
5395         if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
5396             result = resourceWrapper->GetStringArrayByName(param->ToString());
5397             return true;
5398         }
5399         return false;
5400     }
5401     if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
5402         result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
5403         return true;
5404     }
5405     return false;
5406 }
5407 
ParseJsLengthMetricsArray(const JSRef<JSVal> & jsValue,std::vector<Dimension> & result)5408 bool JSViewAbstract::ParseJsLengthMetricsArray(const JSRef<JSVal>& jsValue, std::vector<Dimension>& result)
5409 {
5410     if (jsValue->IsArray()) {
5411         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5412         for (size_t i = 0; i < array->Length(); i++) {
5413             JSRef<JSVal> value = array->GetValueAt(i);
5414             Dimension calc;
5415             ParseJsLengthMetricsToDimension(value, calc);
5416             result.emplace_back(calc);
5417         }
5418         return true;
5419     }
5420 
5421     return false;
5422 }
5423 
IsGetResourceByName(const JSRef<JSObject> & jsObj)5424 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
5425 {
5426     JSRef<JSVal> resId = jsObj->GetProperty("id");
5427     if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
5428         return false;
5429     }
5430     JSRef<JSVal> args = jsObj->GetProperty("params");
5431     if (!args->IsArray()) {
5432         return false;
5433     }
5434     JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
5435     JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
5436     if (!bundleName->IsString() || !moduleName->IsString()) {
5437         return false;
5438     }
5439     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5440     if (params->IsEmpty()) {
5441         return false;
5442     }
5443     return true;
5444 }
5445 
ParseSize(const JSCallbackInfo & info)5446 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
5447 {
5448     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5449     auto jsVal = info[0];
5450     if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
5451         return std::pair<CalcDimension, CalcDimension>();
5452     }
5453     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
5454     CalcDimension width;
5455     CalcDimension height;
5456     if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
5457         !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
5458         return std::pair<CalcDimension, CalcDimension>();
5459     }
5460     return std::pair<CalcDimension, CalcDimension>(width, height);
5461 }
5462 
JsUseAlign(const JSCallbackInfo & info)5463 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
5464 {
5465     if (info.Length() < 2) {
5466         return;
5467     }
5468 
5469     if (!info[0]->IsObject() && !info[1]->IsObject()) {
5470         return;
5471     }
5472 
5473     AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
5474     if (declaration == nullptr) {
5475         return;
5476     }
5477 
5478     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5479     JSRef<JSVal> side = obj->GetProperty("side");
5480     JSRef<JSVal> offset = obj->GetProperty("offset");
5481 
5482     if (!side->IsNumber()) {
5483         return;
5484     }
5485 
5486     auto sideValue = side->ToNumber<int32_t>();
5487 
5488     if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
5489         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
5490             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
5491             return;
5492         }
5493     } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
5494         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
5495             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
5496             return;
5497         }
5498     }
5499 
5500     std::optional<CalcDimension> optOffset;
5501     CalcDimension offsetDimension;
5502     if (ParseJsDimensionVp(offset, offsetDimension)) {
5503         optOffset = offsetDimension;
5504     }
5505     ViewAbstractModel::GetInstance()->SetUseAlign(
5506         declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
5507 }
5508 
JsGridSpan(const JSCallbackInfo & info)5509 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
5510 {
5511     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
5512     auto jsVal = info[0];
5513     if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
5514         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5515             ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
5516         }
5517         return;
5518     }
5519     auto span = jsVal->ToNumber<int32_t>();
5520     ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
5521 }
5522 
JsGridOffset(const JSCallbackInfo & info)5523 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
5524 {
5525     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
5526     auto jsVal = info[0];
5527     if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
5528         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5529             ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
5530         }
5531         return;
5532     }
5533     auto offset = jsVal->ToNumber<int32_t>();
5534     ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
5535 }
5536 
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)5537 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
5538 {
5539     // {lg: 4}
5540     if (val->IsNumber()) {
5541         span = val->ToNumber<uint32_t>();
5542         return true;
5543     }
5544 
5545     if (!val->IsObject()) {
5546         return false;
5547     }
5548 
5549     // {lg: {span: 1, offset: 2}}
5550     JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
5551     span = obj->GetProperty("span")->ToNumber<uint32_t>();
5552     offset = obj->GetProperty("offset")->ToNumber<int32_t>();
5553     return true;
5554 }
5555 
JsUseSizeType(const JSCallbackInfo & info)5556 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
5557 {
5558     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5559     auto jsVal = info[0];
5560     if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
5561         return;
5562     }
5563     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
5564     for (auto values : SCREEN_SIZE_VALUES) {
5565         JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
5566         if (val->IsNull() || val->IsEmpty()) {
5567             continue;
5568         }
5569         uint32_t span = 0;
5570         int32_t offset = 0;
5571         if (ParseSpanAndOffset(val, span, offset)) {
5572             ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
5573         }
5574     }
5575 }
5576 
JsZIndex(const JSCallbackInfo & info)5577 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
5578 {
5579     int zIndex = 0;
5580     if (info[0]->IsNumber()) {
5581         zIndex = info[0]->ToNumber<int>();
5582     }
5583 
5584     ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
5585 }
5586 
Pop()5587 void JSViewAbstract::Pop()
5588 {
5589     if (ViewStackModel::GetInstance()->IsPrebuilding()) {
5590         return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSViewAbstract][pop]", &JSViewAbstract::Pop);
5591     }
5592     ViewStackModel::GetInstance()->Pop();
5593 }
5594 
JsSetDraggable(bool draggable)5595 void JSViewAbstract::JsSetDraggable(bool draggable)
5596 {
5597     ViewAbstractModel::GetInstance()->SetDraggable(draggable);
5598 }
5599 
ParseDragInteractionOptions(const JSCallbackInfo & info,NG::DragPreviewOption & previewOption)5600 void JSViewAbstract::ParseDragInteractionOptions(const JSCallbackInfo& info,
5601     NG::DragPreviewOption& previewOption)
5602 {
5603     if (info.Length() > 1 && info[1]->IsObject()) {
5604         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
5605         auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
5606         if (multiSelection->IsBoolean()) {
5607             previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
5608         }
5609         auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
5610         if (defaultAnimation->IsBoolean()) {
5611             previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
5612         }
5613         auto hapicFeedback = interObj->GetProperty("enableHapticFeedback");
5614         if (hapicFeedback->IsBoolean()) {
5615             previewOption.enableHapticFeedback = hapicFeedback->ToBoolean();
5616         }
5617         auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
5618         if (dragPreview->IsBoolean()) {
5619             previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
5620         }
5621         auto enableEdgeAutoScroll = interObj->GetProperty("enableEdgeAutoScroll");
5622         if (enableEdgeAutoScroll->IsBoolean()) {
5623             previewOption.enableEdgeAutoScroll = enableEdgeAutoScroll->ToBoolean();
5624         }
5625         auto isLiftingDisabled = interObj->GetProperty("isLiftingDisabled");
5626         if (isLiftingDisabled->IsBoolean()) {
5627             previewOption.isLiftingDisabled = isLiftingDisabled->ToBoolean();
5628         }
5629     }
5630 }
5631 
ParseDragPreviewOptions(const JSCallbackInfo & info)5632 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
5633 {
5634     NG::DragPreviewOption previewOption;
5635     if (!info[0]->IsObject()) {
5636         return previewOption;
5637     }
5638     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
5639     auto mode = obj->GetProperty("mode");
5640     bool isAuto = true;
5641     if (mode->IsNumber()) {
5642         ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
5643     } else if (mode->IsArray()) {
5644         JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
5645         for (size_t i = 0; i < array->Length(); i++) {
5646             JSRef<JSVal> value = array->GetValueAt(i);
5647             if (value->IsNumber()) {
5648                 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
5649             }
5650             if (isAuto) {
5651                 break;
5652             }
5653         }
5654     }
5655 
5656     auto sizeChangeEffect = obj->GetProperty("sizeChangeEffect");
5657     if (sizeChangeEffect->IsNumber()) {
5658         previewOption.sizeChangeEffect = static_cast<NG::DraggingSizeChangeEffect>(sizeChangeEffect->ToNumber<int>());
5659     }
5660 
5661     JSViewAbstract::SetDragNumberBadge(info, previewOption);
5662 
5663     ParseDragInteractionOptions(info, previewOption);
5664 
5665     JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
5666 
5667     return previewOption;
5668 }
5669 
JsSetDragPreviewOptions(const JSCallbackInfo & info)5670 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
5671 {
5672     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5673     auto jsVal = info[0];
5674     if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
5675         return;
5676     }
5677     NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
5678     ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
5679 }
5680 
JsOnDragStart(const JSCallbackInfo & info)5681 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
5682 {
5683     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5684     auto jsVal = info[0];
5685     if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
5686         return;
5687     }
5688 
5689     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5690 
5691     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5692     auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
5693                            const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
5694         NG::DragDropBaseInfo dragDropInfo;
5695         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
5696         PipelineContext::SetCallBackNode(node);
5697         auto ret = func->Execute(info, extraParams);
5698         if (!ret->IsObject()) {
5699             return dragDropInfo;
5700         }
5701 
5702         dragDropInfo.node = ParseDragNode(ret);
5703         auto builderObj = JSRef<JSObject>::Cast(ret);
5704 #if defined(PIXEL_MAP_SUPPORTED)
5705         auto pixmap = builderObj->GetProperty("pixelMap");
5706         dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
5707 #endif
5708         auto extraInfo = builderObj->GetProperty("extraInfo");
5709         ParseJsString(extraInfo, dragDropInfo.extraInfo);
5710         return dragDropInfo;
5711     };
5712     ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
5713 }
5714 
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)5715 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
5716 {
5717     auto node = ParseDragNode(info);
5718     if (!node) {
5719         return false;
5720     }
5721     dragInfo.node = node;
5722     return true;
5723 }
5724 
ParseDragNode(const JSRef<JSVal> & info)5725 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
5726 {
5727     auto builderFunc = ParseDragStartBuilderFunc(info);
5728     if (!builderFunc) {
5729         return nullptr;
5730     }
5731     // use another VSP instance while executing the builder function
5732     ViewStackModel::GetInstance()->NewScope();
5733     {
5734         ACE_SCORING_EVENT("onDragStart.builder");
5735         builderFunc->Execute();
5736     }
5737 
5738     return ViewStackModel::GetInstance()->Finish();
5739 }
5740 
JsOnDragEnter(const JSCallbackInfo & info)5741 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
5742 {
5743     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5744     auto jsVal = info[0];
5745     if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
5746         return;
5747     }
5748     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5749     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5750     auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
5751                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5752         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5753         ACE_SCORING_EVENT("onDragEnter");
5754         PipelineContext::SetCallBackNode(node);
5755         func->Execute(info, extraParams);
5756     };
5757 
5758     ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
5759 }
5760 
JsOnDragEnd(const JSCallbackInfo & info)5761 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
5762 {
5763     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5764     auto jsVal = info[0];
5765     if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
5766         return;
5767     }
5768     RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5769     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5770     auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
5771                          const RefPtr<OHOS::Ace::DragEvent>& info) {
5772         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5773         ACE_SCORING_EVENT("onDragEnd");
5774         auto extraParams = JsonUtil::Create(true);
5775         PipelineContext::SetCallBackNode(node);
5776         func->Execute(info, extraParams->ToString());
5777     };
5778 
5779     ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
5780 }
5781 
JsOnDragMove(const JSCallbackInfo & info)5782 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
5783 {
5784     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5785     auto jsVal = info[0];
5786     if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
5787         return;
5788     }
5789     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5790     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5791     auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
5792                           const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5793         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5794         ACE_SCORING_EVENT("onDragMove");
5795         PipelineContext::SetCallBackNode(node);
5796         func->Execute(info, extraParams);
5797     };
5798 
5799     ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
5800 }
5801 
JsOnDragLeave(const JSCallbackInfo & info)5802 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
5803 {
5804     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5805     auto jsVal = info[0];
5806     if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
5807         return;
5808     }
5809     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5810     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5811     auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
5812                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5813         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5814         ACE_SCORING_EVENT("onDragLeave");
5815         PipelineContext::SetCallBackNode(node);
5816         func->Execute(info, extraParams);
5817     };
5818 
5819     ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
5820 }
5821 
JsOnDrop(const JSCallbackInfo & info)5822 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
5823 {
5824     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5825     auto jsVal = info[0];
5826     if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
5827         return;
5828     }
5829     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5830     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5831     auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
5832                       const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5833         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5834         ACE_SCORING_EVENT("onDrop");
5835         PipelineContext::SetCallBackNode(node);
5836         func->Execute(info, extraParams);
5837     };
5838 
5839     ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
5840 
5841     bool disableDataPrefetch = false;
5842     if (info.Length() > 1 && info[1]->IsObject()) {
5843         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
5844         auto jsDisableDataPrefetch = interObj->GetProperty("disableDataPrefetch");
5845         if (jsDisableDataPrefetch->IsBoolean()) {
5846             disableDataPrefetch = jsDisableDataPrefetch->ToBoolean();
5847         }
5848     }
5849     ViewAbstractModel::GetInstance()->SetDisableDataPrefetch(disableDataPrefetch);
5850 }
5851 
JsOnAreaChange(const JSCallbackInfo & info)5852 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
5853 {
5854     auto jsVal = info[0];
5855     if (jsVal->IsUndefined() && IsDisableEventVersion()) {
5856         ViewAbstractModel::GetInstance()->DisableOnAreaChange();
5857         return;
5858     }
5859     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5860     if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
5861         return;
5862     }
5863     auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
5864 
5865     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5866     auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
5867                              node = frameNode](
5868                              const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
5869         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5870         ACE_SCORING_EVENT("onAreaChange");
5871         PipelineContext::SetCallBackNode(node);
5872         func->Execute(oldRect, oldOrigin, rect, origin);
5873     };
5874     ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
5875 }
5876 
JsOnSizeChange(const JSCallbackInfo & info)5877 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
5878 {
5879     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5880     auto jsVal = info[0];
5881     if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
5882         return;
5883     }
5884     auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
5885 
5886     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5887     auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
5888                              node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
5889         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5890         ACE_SCORING_EVENT("onSizeChange");
5891         PipelineContext::SetCallBackNode(node);
5892         func->Execute(oldRect, rect);
5893     };
5894     ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
5895 }
5896 
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5897 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5898 {
5899     if (!info[0]->IsObject()) {
5900         return;
5901     }
5902     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5903     newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
5904     // angle
5905     std::optional<float> degree;
5906     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5907         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
5908     } else {
5909         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
5910     }
5911     if (degree) {
5912         newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
5913         degree.reset();
5914     }
5915     // direction
5916     auto direction = static_cast<GradientDirection>(
5917         jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
5918     SetGradientDirection(newGradient, direction);
5919     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
5920     newGradient.SetRepeat(repeating);
5921     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
5922 }
5923 
SetGradientDirection(NG::Gradient & newGradient,const GradientDirection & direction)5924 void JSViewAbstract::SetGradientDirection(NG::Gradient& newGradient, const GradientDirection& direction)
5925 {
5926     switch (direction) {
5927         case GradientDirection::LEFT:
5928             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5929             break;
5930         case GradientDirection::RIGHT:
5931             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5932             break;
5933         case GradientDirection::TOP:
5934             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5935             break;
5936         case GradientDirection::BOTTOM:
5937             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5938             break;
5939         case GradientDirection::LEFT_TOP:
5940             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5941             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5942             break;
5943         case GradientDirection::LEFT_BOTTOM:
5944             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5945             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5946             break;
5947         case GradientDirection::RIGHT_TOP:
5948             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5949             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5950             break;
5951         case GradientDirection::RIGHT_BOTTOM:
5952             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5953             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5954             break;
5955         default:
5956             break;
5957     }
5958 }
5959 
JsRadialGradient(const JSCallbackInfo & info)5960 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
5961 {
5962     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5963     auto jsVal = info[0];
5964     if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
5965         NG::Gradient newGradient;
5966         newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
5967         ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
5968         return;
5969     }
5970     NG::Gradient newGradient;
5971     NewJsRadialGradient(info, newGradient);
5972     ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
5973 }
5974 
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5975 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5976 {
5977     JSRef<JSVal> arg = info[0];
5978     if (!arg->IsObject()) {
5979         return;
5980     }
5981     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
5982     newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
5983     // center
5984     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
5985     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
5986         CalcDimension value;
5987         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
5988         if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
5989             newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
5990             if (value.Unit() == DimensionUnit::PERCENT) {
5991                 // [0,1] -> [0, 100]
5992                 newGradient.GetRadialGradient()->radialCenterX =
5993                     CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
5994             }
5995         }
5996         if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
5997             newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
5998             if (value.Unit() == DimensionUnit::PERCENT) {
5999                 // [0,1] -> [0, 100]
6000                 newGradient.GetRadialGradient()->radialCenterY =
6001                     CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6002             }
6003         }
6004     }
6005     // radius
6006     CalcDimension radius;
6007     if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6008         newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6009         newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6010     }
6011     // repeating
6012     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6013     newGradient.SetRepeat(repeating);
6014     // color stops
6015     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6016 }
6017 
JsSweepGradient(const JSCallbackInfo & info)6018 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6019 {
6020     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6021     auto jsVal = info[0];
6022     if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6023         NG::Gradient newGradient;
6024         newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6025         ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6026         return;
6027     }
6028 
6029     NG::Gradient newGradient;
6030     NewJsSweepGradient(info, newGradient);
6031     ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6032 }
6033 
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6034 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6035 {
6036     JSRef<JSVal> arg = info[0];
6037     if (!arg->IsObject()) {
6038         return;
6039     }
6040     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6041     newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6042     // center
6043     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6044     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6045         CalcDimension value;
6046         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6047         if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6048             newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6049             if (value.Unit() == DimensionUnit::PERCENT) {
6050                 // [0,1] -> [0, 100]
6051                 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6052             }
6053         }
6054         if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6055             newGradient.GetSweepGradient()->centerY = CalcDimension(value);
6056             if (value.Unit() == DimensionUnit::PERCENT) {
6057                 // [0,1] -> [0, 100]
6058                 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6059             }
6060         }
6061     }
6062     // start, end and rotation
6063     ParseSweepGradientPartly(jsObj, newGradient);
6064     // repeating
6065     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6066     newGradient.SetRepeat(repeating);
6067     // color stops
6068     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6069 }
6070 
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)6071 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
6072 {
6073     std::optional<float> degreeStart;
6074     std::optional<float> degreeEnd;
6075     std::optional<float> degreeRotation;
6076     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6077         GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
6078         GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
6079         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
6080     } else {
6081         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
6082         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
6083         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
6084     }
6085     if (degreeStart) {
6086         CheckAngle(degreeStart);
6087         newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
6088     }
6089     if (degreeEnd) {
6090         CheckAngle(degreeEnd);
6091         newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
6092     }
6093     if (degreeRotation) {
6094         CheckAngle(degreeRotation);
6095         newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
6096     }
6097 }
6098 
JsMotionPath(const JSCallbackInfo & info)6099 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
6100 {
6101     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6102     auto jsVal = info[0];
6103     if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
6104         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6105         return;
6106     }
6107     MotionPathOption motionPathOption;
6108     if (ParseMotionPath(jsVal, motionPathOption)) {
6109         ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
6110     } else {
6111         TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
6112         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6113     }
6114 }
6115 
JsShadow(const JSCallbackInfo & info)6116 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
6117 {
6118     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6119     auto jsVal = info[0];
6120     if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
6121         Shadow shadow;
6122         std::vector<Shadow> shadows { shadow };
6123         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6124         return;
6125     }
6126     Shadow shadow;
6127     if (!ParseShadowProps(jsVal, shadow)) {
6128         info.ReturnSelf();
6129         return;
6130     }
6131     std::vector<Shadow> shadows { shadow };
6132     ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6133 }
6134 
JsBlendMode(const JSCallbackInfo & info)6135 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
6136 {
6137     if (info.Length() == 0) {
6138         return;
6139     }
6140     BlendMode blendMode = BlendMode::NONE;
6141     BlendApplyType blendApplyType = BlendApplyType::FAST;
6142     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
6143     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
6144     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
6145     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
6146     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
6147     if (info[0]->IsNumber()) {
6148         auto blendModeNum = info[0]->ToNumber<int32_t>();
6149         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
6150             blendMode = static_cast<BlendMode>(blendModeNum);
6151         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
6152             // backward compatibility code, will remove soon
6153             blendMode = BlendMode::SRC_OVER;
6154             blendApplyType = BlendApplyType::OFFSCREEN;
6155         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
6156             // backward compatibility code, will remove soon
6157             blendMode = BlendMode::SRC_IN;
6158             blendApplyType = BlendApplyType::OFFSCREEN;
6159         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
6160             // backward compatibility code, will remove soon
6161             blendMode = BlendMode::DST_IN;
6162             blendApplyType = BlendApplyType::OFFSCREEN;
6163         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
6164             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
6165         }
6166     }
6167     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
6168         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
6169         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
6170             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
6171         }
6172     }
6173     ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
6174     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
6175 }
6176 
JsAdvancedBlendMode(const JSCallbackInfo & info)6177 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
6178 {
6179     if (info.Length() == 0) {
6180         return;
6181     }
6182     BlendMode blendMode = BlendMode::NONE;
6183     BlendApplyType blendApplyType = BlendApplyType::FAST;
6184     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
6185     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
6186     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
6187     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
6188     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
6189     if (info[0]->IsNumber()) {
6190         auto blendModeNum = info[0]->ToNumber<int32_t>();
6191         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
6192             blendMode = static_cast<BlendMode>(blendModeNum);
6193         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
6194             // backward compatibility code, will remove soon
6195             blendMode = BlendMode::SRC_OVER;
6196             blendApplyType = BlendApplyType::OFFSCREEN;
6197         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
6198             // backward compatibility code, will remove soon
6199             blendMode = BlendMode::SRC_IN;
6200             blendApplyType = BlendApplyType::OFFSCREEN;
6201         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
6202             // backward compatibility code, will remove soon
6203             blendMode = BlendMode::DST_IN;
6204             blendApplyType = BlendApplyType::OFFSCREEN;
6205         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
6206             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
6207         }
6208     } else if (info[0]->IsObject()) {
6209         auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
6210         ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
6211     }
6212     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
6213         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
6214         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
6215             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
6216         }
6217     }
6218     if (!info[0]->IsObject()) {
6219         ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
6220     }
6221     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
6222 }
6223 
JsGrayScale(const JSCallbackInfo & info)6224 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
6225 {
6226     CalcDimension value;
6227     if (!ParseJsDimensionVp(info[0], value)) {
6228         value.SetValue(0.0);
6229         ViewAbstractModel::GetInstance()->SetGrayScale(value);
6230         return;
6231     }
6232 
6233     if (LessNotEqual(value.Value(), 0.0)) {
6234         value.SetValue(0.0);
6235     }
6236 
6237     if (GreatNotEqual(value.Value(), 1.0)) {
6238         value.SetValue(1.0);
6239     }
6240 
6241     ViewAbstractModel::GetInstance()->SetGrayScale(value);
6242 }
6243 
JsBrightness(const JSCallbackInfo & info)6244 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
6245 {
6246     CalcDimension value;
6247     if (!ParseJsDimensionVp(info[0], value)) {
6248         value.SetValue(1.0);
6249         ViewAbstractModel::GetInstance()->SetBrightness(value);
6250         return;
6251     }
6252 
6253     ViewAbstractModel::GetInstance()->SetBrightness(value);
6254 }
6255 
JsContrast(const JSCallbackInfo & info)6256 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
6257 {
6258     CalcDimension value;
6259     if (!ParseJsDimensionVp(info[0], value)) {
6260         value.SetValue(1.0);
6261         ViewAbstractModel::GetInstance()->SetContrast(value);
6262         return;
6263     }
6264 
6265     if (LessNotEqual(value.Value(), 0.0)) {
6266         value.SetValue(0.0);
6267     }
6268 
6269     ViewAbstractModel::GetInstance()->SetContrast(value);
6270 }
6271 
JsSaturate(const JSCallbackInfo & info)6272 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
6273 {
6274     CalcDimension value;
6275     if (!ParseJsDimensionVp(info[0], value)) {
6276         value.SetValue(1.0);
6277         ViewAbstractModel::GetInstance()->SetSaturate(value);
6278         return;
6279     }
6280 
6281     if (LessNotEqual(value.Value(), 0.0)) {
6282         value.SetValue(0.0);
6283     }
6284 
6285     ViewAbstractModel::GetInstance()->SetSaturate(value);
6286 }
6287 
JsSepia(const JSCallbackInfo & info)6288 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
6289 {
6290     CalcDimension value;
6291     if (!ParseJsDimensionVp(info[0], value)) {
6292         value.SetValue(0.0);
6293         ViewAbstractModel::GetInstance()->SetSepia(value);
6294         return;
6295     }
6296 
6297     if (LessNotEqual(value.Value(), 0.0)) {
6298         value.SetValue(0.0);
6299     }
6300 
6301     ViewAbstractModel::GetInstance()->SetSepia(value);
6302 }
6303 
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)6304 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
6305 {
6306     double invertValue = 0.0;
6307     if (ParseJsDouble(jsValue, invertValue)) {
6308         invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
6309         return true;
6310     }
6311     auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
6312     if (!argsPtrItem || argsPtrItem->IsNull()) {
6313         return false;
6314     }
6315     InvertOption option;
6316     double low = 0.0;
6317     if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
6318         option.low_ = std::clamp(low, 0.0, 1.0);
6319     }
6320     double high = 0.0;
6321     if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
6322         option.high_ = std::clamp(high, 0.0, 1.0);
6323     }
6324     double threshold = 0.0;
6325     if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
6326         option.threshold_ = std::clamp(threshold, 0.0, 1.0);
6327     }
6328     double thresholdRange = 0.0;
6329     if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
6330         option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
6331     }
6332     invert = option;
6333     return true;
6334 }
6335 
JsInvert(const JSCallbackInfo & info)6336 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
6337 {
6338     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6339     InvertVariant invert = 0.0f;
6340     auto jsVal = info[0];
6341     if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
6342         ViewAbstractModel::GetInstance()->SetInvert(invert);
6343         return;
6344     }
6345     if (ParseInvertProps(jsVal, invert)) {
6346         ViewAbstractModel::GetInstance()->SetInvert(invert);
6347     }
6348     ViewAbstractModel::GetInstance()->SetInvert(invert);
6349 }
6350 
JsSystemBarEffect(const JSCallbackInfo & info)6351 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
6352 {
6353     ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
6354 }
6355 
JsHueRotate(const JSCallbackInfo & info)6356 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
6357 {
6358     std::optional<float> degree;
6359     JSRef<JSVal> arg = info[0];
6360     if (arg->IsString()) {
6361         degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
6362     } else if (arg->IsNumber()) {
6363         degree = static_cast<float>(arg->ToNumber<int32_t>());
6364     } else {
6365         ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
6366         return;
6367     }
6368     float deg = 0.0f;
6369     if (degree) {
6370         deg = degree.value();
6371         degree.reset();
6372     }
6373     deg = std::fmod(deg, ROUND_UNIT);
6374     if (deg < 0.0f) {
6375         deg += ROUND_UNIT;
6376     }
6377     ViewAbstractModel::GetInstance()->SetHueRotate(deg);
6378 }
6379 
JsClip(const JSCallbackInfo & info)6380 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
6381 {
6382     JSRef<JSVal> arg = info[0];
6383     if (arg->IsUndefined()) {
6384         ViewAbstractModel::GetInstance()->SetClipEdge(false);
6385         return;
6386     }
6387     if (arg->IsObject()) {
6388         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
6389         if (clipShape == nullptr) {
6390             return;
6391         }
6392         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
6393     } else if (arg->IsBoolean()) {
6394         ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
6395     }
6396 }
6397 
JsClipShape(const JSCallbackInfo & info)6398 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
6399 {
6400     if (info[0]->IsObject()) {
6401         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
6402         if (clipShape == nullptr) {
6403             return;
6404         }
6405         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
6406     }
6407 }
6408 
JsMask(const JSCallbackInfo & info)6409 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
6410 {
6411     JSRef<JSVal> arg = info[0];
6412     if (!arg->IsObject()) {
6413         ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
6414         return;
6415     }
6416     auto paramObject = JSRef<JSObject>::Cast(arg);
6417     JSRef<JSVal> typeParam = paramObject->GetProperty("type");
6418     if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
6419         typeParam->ToString() == "ProgressMask") {
6420         auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
6421         JSRef<JSVal> jValue = paramObject->GetProperty("value");
6422         auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
6423         if (value < 0.0f) {
6424             value = 0.0f;
6425         }
6426         progressMask->SetValue(value);
6427         JSRef<JSVal> jTotal = paramObject->GetProperty("total");
6428         auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
6429         if (total < 0.0f) {
6430             total = DEFAULT_PROGRESS_TOTAL;
6431         }
6432         progressMask->SetMaxValue(total);
6433         JSRef<JSVal> jColor = paramObject->GetProperty("color");
6434         Color colorVal;
6435         if (ParseJsColor(jColor, colorVal)) {
6436             progressMask->SetColor(colorVal);
6437         } else {
6438             RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
6439             progressMask->SetColor(theme->GetMaskColor());
6440         }
6441         JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
6442         if (jEnableBreathe->IsBoolean()) {
6443             progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
6444         }
6445         ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
6446     } else {
6447         JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
6448         if (maskShape == nullptr) {
6449             return;
6450         };
6451         ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
6452     }
6453 }
6454 
JsMaskShape(const JSCallbackInfo & info)6455 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
6456 {
6457     if (!info[0]->IsObject()) {
6458         return;
6459     }
6460 
6461     JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
6462     if (maskShape == nullptr) {
6463         return;
6464     };
6465     ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
6466 }
6467 
JsFocusable(const JSCallbackInfo & info)6468 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
6469 {
6470     if (!info[0]->IsBoolean()) {
6471         return;
6472     }
6473     ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
6474 }
6475 
JsTabStop(const JSCallbackInfo & info)6476 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
6477 {
6478     if (!info[0]->IsBoolean()) {
6479         ViewAbstractModel::GetInstance()->SetTabStop(false);
6480         return;
6481     }
6482     ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
6483 }
6484 
JsNextFocus(const JSCallbackInfo & info)6485 void JSViewAbstract::JsNextFocus(const JSCallbackInfo& info)
6486 {
6487     ViewAbstractModel::GetInstance()->ResetNextFocus();
6488     if (info.Length() == 1 && info[0]->IsObject()) {
6489         auto obj = JSRef<JSObject>::Cast(info[0]);
6490         auto forward = obj->GetPropertyValue<std::string>("forward", "");
6491         if (!forward.empty()) {
6492             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::TAB, forward);
6493         }
6494         auto backward = obj->GetPropertyValue<std::string>("backward", "");
6495         if (!backward.empty()) {
6496             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::SHIFT_TAB, backward);
6497         }
6498         auto up = obj->GetPropertyValue<std::string>("up", "");
6499         if (!up.empty()) {
6500             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::UP, up);
6501         }
6502         auto down = obj->GetPropertyValue<std::string>("down", "");
6503         if (!down.empty()) {
6504             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::DOWN, down);
6505         }
6506         auto left = obj->GetPropertyValue<std::string>("left", "");
6507         if (!left.empty()) {
6508             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::LEFT, left);
6509         }
6510         auto right = obj->GetPropertyValue<std::string>("right", "");
6511         if (!right.empty()) {
6512             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::RIGHT, right);
6513         }
6514     }
6515 }
6516 
JsFocusBox(const JSCallbackInfo & info)6517 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
6518 {
6519     if (!info[0]->IsObject() || info.Length() != 1) {
6520         return;
6521     }
6522     auto obj = JSRef<JSObject>::Cast(info[0]);
6523     NG::FocusBoxStyle style;
6524 
6525     CalcDimension margin;
6526     if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
6527         style.margin = margin;
6528     }
6529     CalcDimension strokeWidth;
6530     if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
6531         style.strokeWidth = strokeWidth;
6532     }
6533     Color strokeColor;
6534     if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
6535         style.strokeColor = strokeColor;
6536     }
6537 
6538     ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
6539 }
6540 
JsOnFocusMove(const JSCallbackInfo & args)6541 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
6542 {
6543     JSRef<JSVal> arg = args[0];
6544     if (arg->IsFunction()) {
6545         RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
6546         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6547         auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
6548                                int info) {
6549             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6550             ACE_SCORING_EVENT("onFocusMove");
6551             PipelineContext::SetCallBackNode(node);
6552             func->Execute(info);
6553         };
6554         ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
6555     }
6556 }
6557 
JsOnKeyEvent(const JSCallbackInfo & args)6558 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
6559 {
6560     JSRef<JSVal> arg = args[0];
6561     if (arg->IsUndefined() && IsDisableEventVersion()) {
6562         ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
6563         return;
6564     }
6565     if (!arg->IsFunction()) {
6566         return;
6567     }
6568     RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
6569     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6570     auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
6571                           KeyEventInfo& info) -> bool {
6572         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
6573         ACE_SCORING_EVENT("onKey");
6574         PipelineContext::SetCallBackNode(node);
6575         auto ret = func->ExecuteWithValue(info);
6576         return ret->IsBoolean() ? ret->ToBoolean() : false;
6577     };
6578     ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
6579 }
6580 
JsDispatchKeyEvent(const JSCallbackInfo & args)6581 void JSViewAbstract::JsDispatchKeyEvent(const JSCallbackInfo& args)
6582 {
6583     JSRef<JSVal> arg = args[0];
6584     if (!(arg->IsNumber() || arg->IsString())) {
6585         return;
6586     }
6587     RefPtr<NG::FrameNode> frameNode = nullptr;
6588     if (arg->IsString()) {
6589         std::string id = arg->ToString();
6590         frameNode = NG::Inspector::GetFrameNodeByKey(id);
6591     }
6592 
6593     if (arg->IsNumber()) {
6594         auto id = arg->ToNumber<int32_t>();
6595         auto node = ElementRegister::GetInstance()->GetNodeById(id);
6596         frameNode = AceType::DynamicCast<NG::FrameNode>(node);
6597     }
6598     CHECK_NULL_VOID(frameNode);
6599     auto focusHub = frameNode->GetOrCreateFocusHub();
6600     CHECK_NULL_VOID(focusHub);
6601 
6602     if (!(args[1]->IsObject())) {
6603         return;
6604     }
6605     JSRef<JSObject> jsObject = JSRef<JSObject>::Cast(args[1]);
6606     auto eventInfoPtr = jsObject->Unwrap<KeyEventInfo>();
6607     CHECK_NULL_VOID(eventInfoPtr);
6608     KeyEvent keyEvent;
6609     eventInfoPtr->ParseKeyEvent(keyEvent);
6610     auto result = focusHub->HandleEvent(keyEvent);
6611     args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
6612 }
6613 
JsOnCrownEvent(const JSCallbackInfo & args)6614 void JSViewAbstract::JsOnCrownEvent(const JSCallbackInfo& args)
6615 {
6616 #ifdef SUPPORT_DIGITAL_CROWN
6617     if (args.Length() <= 0) {
6618         return;
6619     }
6620     if (args[0]->IsFunction()) {
6621         RefPtr<JsCrownFunction> JsOnCrownEventfunc = AceType::MakeRefPtr<JsCrownFunction>(JSRef<JSFunc>::Cast(args[0]));
6622         WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->
6623             GetMainFrameNode());
6624         auto onCrownEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnCrownEventfunc),
6625             node = frameNode](CrownEventInfo& info) {
6626                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6627                 ACE_SCORING_EVENT("onCrown");
6628                 PipelineContext::SetCallBackNode(node);
6629                 func->Execute(info);
6630             };
6631         ViewAbstractModel::GetInstance()->SetOnCrownEvent(std::move(onCrownEvent));
6632     } else {
6633         ViewAbstractModel::GetInstance()->DisableOnCrownEvent();
6634     }
6635 #endif
6636 }
6637 
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle)6638 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args, NG::SheetStyle& sheetStyle)
6639 {
6640     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
6641         TAG_LOGE(AceLogTag::ACE_SHEET, "radius is not correct type");
6642         return;
6643     }
6644     CalcDimension radius;
6645     NG::BorderRadiusProperty borderRadius;
6646     if (ParseJsLengthMetrics(args, radius)) {
6647         borderRadius.SetRadius(radius);
6648         sheetStyle.radius = borderRadius;
6649     } else if (ParseBindSheetBorderRadiusProps(args, borderRadius)) {
6650         sheetStyle.radius = borderRadius;
6651     } else {
6652         TAG_LOGW(AceLogTag::ACE_SHEET, "radius is not correct.");
6653         return;
6654     }
6655 }
6656 
ParseBindSheetBorderRadiusProps(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)6657 bool JSViewAbstract::ParseBindSheetBorderRadiusProps(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
6658 {
6659     if (args->IsObject()) {
6660         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
6661         if (CheckLengthMetrics(object)) {
6662             std::optional<CalcDimension> radiusTopStart = ParseBindSheetBorderRadiusProp(object, TOP_START_PROPERTY);
6663             std::optional<CalcDimension> radiusTopEnd = ParseBindSheetBorderRadiusProp(object, TOP_END_PROPERTY);
6664             std::optional<CalcDimension> radiusBottomStart =
6665                 ParseBindSheetBorderRadiusProp(object, BOTTOM_START_PROPERTY);
6666             std::optional<CalcDimension> radiusBottomEnd = ParseBindSheetBorderRadiusProp(object, BOTTOM_END_PROPERTY);
6667             auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
6668             radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
6669             radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
6670             radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
6671             radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
6672             radius.multiValued = true;
6673         } else {
6674             ParseBorderRadiusProps(object, radius);
6675         }
6676         return true;
6677     }
6678     return false;
6679 }
6680 
ParseBindSheetBorderRadiusProp(const JSRef<JSObject> & object,const char * prop)6681 std::optional<CalcDimension> JSViewAbstract::ParseBindSheetBorderRadiusProp(
6682     const JSRef<JSObject>& object, const char* prop)
6683 {
6684     if (object->IsEmpty()) {
6685         return std::nullopt;
6686     }
6687     if (object->HasProperty(prop) && object->GetProperty(prop)->IsObject()) {
6688         JSRef<JSObject> propObj = JSRef<JSObject>::Cast(object->GetProperty(prop));
6689         CalcDimension calcDimension;
6690         if (ParseJsLengthMetrics(propObj, calcDimension)) {
6691             return calcDimension;
6692         }
6693     }
6694     return std::nullopt;
6695 }
6696 
JSCreateAnimatableProperty(const JSCallbackInfo & info)6697 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
6698 {
6699     if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
6700         return;
6701     }
6702 
6703     JSRef<JSVal> callback = info[2]; /* 2:args index */
6704     if (!callback->IsFunction()) {
6705         return;
6706     }
6707     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6708     std::string propertyName = info[0]->ToString();
6709     if (info[1]->IsNumber()) {
6710         float numValue = info[1]->ToNumber<float>();
6711         std::function<void(float)> onCallbackEvent;
6712         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
6713         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
6714                               node = frameNode](const float val) {
6715             ContainerScope scope(id);
6716             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6717             auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
6718             PipelineContext::SetCallBackNode(node);
6719             func->ExecuteJS(1, &newJSVal);
6720         };
6721         ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
6722     } else if (info[1]->IsObject()) {
6723         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6724         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
6725             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
6726         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
6727             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
6728         std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
6729         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
6730         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
6731                               node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
6732             ContainerScope scope(id);
6733             RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
6734             if (!impl) {
6735                 return;
6736             }
6737             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6738             auto newJSVal = JSRef<JSVal>(impl->GetObject());
6739             PipelineContext::SetCallBackNode(node);
6740             func->ExecuteJS(1, &newJSVal);
6741         };
6742         ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
6743             propertyName, animatableArithmetic, onCallbackEvent);
6744     }
6745 }
6746 
JSUpdateAnimatableProperty(const JSCallbackInfo & info)6747 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
6748 {
6749     if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
6750         return;
6751     }
6752 
6753     std::string propertyName = info[0]->ToString();
6754     float numValue = 0.0;
6755     if (info[1]->IsNumber()) {
6756         numValue = info[1]->ToNumber<float>();
6757         ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
6758     } else if (info[1]->IsObject()) {
6759         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6760         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
6761             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
6762         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
6763             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
6764         ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
6765     }
6766 }
6767 
JsExpandSafeArea(const JSCallbackInfo & info)6768 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
6769 {
6770     NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
6771     if (info.Length() >= PARAMETER_LENGTH_FIRST && info[0]->IsArray()) {
6772         auto paramArray = JSRef<JSArray>::Cast(info[0]);
6773         uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
6774         for (size_t i = 0; i < paramArray->Length(); ++i) {
6775             if (!paramArray->GetValueAt(i)->IsNumber() ||
6776                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
6777                 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
6778                 break;
6779             }
6780             safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
6781         }
6782         opts.type = safeAreaType;
6783     }
6784     if (info.Length() >= 2 && info[1]->IsArray()) {
6785         auto paramArray = JSRef<JSArray>::Cast(info[1]);
6786         uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
6787         for (size_t i = 0; i < paramArray->Length(); ++i) {
6788             if (!paramArray->GetValueAt(i)->IsNumber() ||
6789                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
6790                 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
6791                 break;
6792             }
6793             safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
6794         }
6795         opts.edges = safeAreaEdge;
6796     }
6797 
6798     ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
6799 }
6800 
ParseJSLightSource(JSRef<JSObject> & lightSource)6801 void ParseJSLightSource(JSRef<JSObject>& lightSource)
6802 {
6803     if (lightSource->IsUndefined()) {
6804         return;
6805     }
6806     JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
6807     JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
6808     JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
6809     JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
6810     JSRef<JSVal> color = lightSource->GetProperty("color");
6811 
6812     CalcDimension dimPositionX;
6813     CalcDimension dimPositionY;
6814     CalcDimension dimPositionZ;
6815     if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
6816         JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
6817         JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
6818         ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
6819     }
6820 
6821     if (intensity->IsNumber()) {
6822         float intensityValue = intensity->ToNumber<float>();
6823         ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
6824     }
6825 
6826     Color lightColor;
6827     if (JSViewAbstract::ParseJsColor(color, lightColor)) {
6828         ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
6829     }
6830 }
6831 
JsPointLight(const JSCallbackInfo & info)6832 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
6833 {
6834 #ifdef POINT_LIGHT_ENABLE
6835     if (!info[0]->IsObject()) {
6836         return;
6837     }
6838 
6839     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
6840     JSRef<JSObject> lightSource = object->GetProperty("lightSource");
6841     ParseJSLightSource(lightSource);
6842 
6843     auto resourceWrapper = CreateResourceWrapper();
6844     if (!resourceWrapper) {
6845         return;
6846     }
6847     double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
6848     Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
6849     Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
6850 
6851     JSRef<JSVal> illuminated = object->GetProperty("illuminated");
6852     if (illuminated->IsNumber()) {
6853         uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
6854         ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
6855         ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
6856     }
6857 
6858     JSRef<JSVal> bloom = object->GetProperty("bloom");
6859     if (bloom->IsNumber()) {
6860         float bloomValue = bloom->ToNumber<float>();
6861         ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
6862 
6863         Shadow shadow;
6864         shadow.SetBlurRadius(bloomValue * bloomRadius);
6865         shadow.SetColor(bloomColor);
6866         std::vector<Shadow> shadows { shadow };
6867         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6868     }
6869 #endif
6870 }
6871 
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)6872 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
6873 {
6874     if (info[0]->IsBoolean()) {
6875         ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
6876     }
6877 }
6878 
JsNotifyDragStartRequest(const JSCallbackInfo & info)6879 void JSViewAbstract::JsNotifyDragStartRequest(const JSCallbackInfo& info)
6880 {
6881     if (info[0]->IsNumber()) {
6882         int32_t dragStatus = info[0]->ToNumber<int32_t>();
6883         ViewAbstractModel::GetInstance()->NotifyDragStartRequest(
6884             static_cast<DragStartRequestStatus>(dragStatus));
6885     }
6886 }
6887 
JsCancelDataLoading(const std::string & key)6888 void JSViewAbstract::JsCancelDataLoading(const std::string& key)
6889 {
6890     auto ret = ViewAbstractModel::GetInstance()->CancelDataLoading(key);
6891     if (ret != 0) {
6892         JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid input parameter.");
6893     }
6894 }
6895 
JSBind(BindingTarget globalObj)6896 void JSViewAbstract::JSBind(BindingTarget globalObj)
6897 {
6898     JSClass<JSViewAbstract>::Declare("JSViewAbstract");
6899 
6900     // static methods
6901     MethodOptions opt = MethodOptions::NONE;
6902     JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
6903 
6904     JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
6905     JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
6906     JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
6907     JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
6908     JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
6909     JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
6910     JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
6911     JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSLayoutableView::JsPixelRound);
6912     JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
6913     JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSLayoutableView::JsChainWeight);
6914 
6915     JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
6916     JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
6917     JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
6918     JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
6919     JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
6920 
6921     JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
6922     JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
6923     JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
6924     JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
6925     JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
6926     JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
6927 
6928     JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
6929     JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
6930     JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
6931     JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
6932     JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
6933     JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
6934     JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
6935     JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
6936     JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
6937     JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
6938     JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
6939     JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
6940     JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
6941     JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
6942     JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
6943     JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
6944     JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
6945     JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
6946     JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
6947     JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
6948     JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
6949     JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
6950     JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
6951     JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
6952 
6953     JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
6954     JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
6955     JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
6956     JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
6957     JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
6958     JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
6959     JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
6960     JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
6961     JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
6962     JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
6963     JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
6964     JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
6965 
6966     JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
6967     JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
6968     JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
6969     JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
6970     JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
6971     JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
6972     JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
6973 
6974     JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
6975     JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
6976     JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
6977     JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
6978     JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
6979     JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
6980     JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
6981     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
6982     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal", &JSViewAbstract::JsBackgroundBrightnessInternal);
6983     JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
6984     JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
6985     JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
6986     JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
6987     JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
6988     JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
6989     JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
6990     JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
6991     JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
6992     JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
6993     JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
6994     JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
6995 #ifndef WEARABLE_PRODUCT
6996     JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
6997     JSClass<JSViewAbstract>::StaticMethod("bindTips", &JSViewAbstract::JsBindTips);
6998 #endif
6999 
7000     JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
7001     JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
7002     JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
7003     JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
7004     JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
7005     JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
7006     JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
7007     JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
7008     JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
7009     JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
7010     JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
7011     JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
7012     JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
7013     JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
7014 
7015     JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
7016     JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
7017     JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
7018     JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
7019     JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
7020     JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
7021     JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
7022     JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
7023     JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
7024     JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
7025     JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
7026     JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
7027     JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
7028     JSClass<JSViewAbstract>::StaticMethod("nextFocus", &JSViewAbstract::JsNextFocus);
7029     JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
7030     JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
7031     JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
7032     JSClass<JSViewAbstract>::StaticMethod("onKeyEventDispatch", &JSInteractableView::JsOnKeyEventDispatch);
7033     JSClass<JSViewAbstract>::StaticMethod("dispatchKeyEvent", &JSViewAbstract::JsDispatchKeyEvent);
7034     JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
7035     JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
7036     JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
7037     JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
7038     JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
7039     JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
7040     JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
7041     JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
7042     JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
7043     JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
7044     JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
7045     JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
7046     JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
7047     JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
7048     JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
7049     JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
7050     JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
7051     JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
7052     JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
7053     JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
7054     JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
7055     JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
7056     JSClass<JSViewAbstract>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
7057     JSClass<JSViewAbstract>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
7058     JSClass<JSViewAbstract>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
7059     JSClass<JSViewAbstract>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
7060     JSClass<JSViewAbstract>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
7061     JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
7062     JSClass<JSViewAbstract>::StaticMethod("onAxisEvent", &JSViewAbstract::JsOnAxisEvent);
7063     JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
7064     JSClass<JSViewAbstract>::StaticMethod("onHoverMove", &JSViewAbstract::JsOnHoverMove);
7065     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
7066     JSClass<JSViewAbstract>::StaticMethod("onDigitalCrown", &JSViewAbstract::JsOnCrownEvent);
7067     JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
7068     JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
7069     JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
7070     JSClass<JSViewAbstract>::StaticMethod(
7071         "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
7072     JSClass<JSViewAbstract>::StaticMethod(
7073         "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
7074     JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
7075     JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
7076     JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
7077     JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
7078     JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
7079     JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
7080     JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
7081     JSClass<JSViewAbstract>::StaticMethod("onFocusAxisEvent", &JSViewAbstract::JsOnFocusAxisEvent);
7082 
7083     JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
7084     JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
7085     JSClass<JSViewAbstract>::StaticMethod("accessibilityNextFocusId", &JSViewAbstract::JsAccessibilityNextFocusId);
7086     JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
7087     JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
7088     JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
7089     JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
7090     JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
7091     JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
7092     JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
7093     JSClass<JSViewAbstract>::StaticMethod("accessibilityRole", &JSViewAbstract::JsAccessibilityRole);
7094     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityFocus", &JSViewAbstract::JsOnAccessibilityFocus);
7095     JSClass<JSViewAbstract>::StaticMethod("accessibilityDefaultFocus", &JSViewAbstract::JsAccessibilityDefaultFocus);
7096     JSClass<JSViewAbstract>::StaticMethod("accessibilityUseSamePage", &JSViewAbstract::JsAccessibilityUseSamePage);
7097     JSClass<JSViewAbstract>::StaticMethod("accessibilityScrollTriggerable",
7098                                           &JSViewAbstract::JsAccessibilityScrollTriggerable);
7099     JSClass<JSViewAbstract>::StaticMethod("accessibilityFocusDrawLevel",
7100                                           &JSViewAbstract::JsAccessibilityFocusDrawLevel);
7101 
7102     JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
7103     JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
7104     JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
7105     JSClass<JSViewAbstract>::StaticMethod(
7106         "onVisibleAreaApproximateChange", &JSViewAbstract::JsOnVisibleAreaApproximateChange);
7107     JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
7108     JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
7109     JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
7110     JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
7111     JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
7112     JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
7113     JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
7114     JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
7115 
7116     JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
7117     JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
7118     JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
7119     JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
7120 
7121     JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
7122 
7123     JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
7124 
7125     JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
7126     JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
7127     JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
7128     JSClass<JSViewAbstract>::StaticMethod("notifyDragStartRequest", &JSViewAbstract::JsNotifyDragStartRequest);
7129     JSClass<JSViewAbstract>::StaticMethod(
7130         "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
7131     JSClass<JSViewAbstract>::StaticMethod("cancelDataLoading", &JSViewAbstract::JsCancelDataLoading);
7132 
7133     JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
7134     JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
7135 
7136     JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
7137     JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
7138     JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
7139     JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
7140 
7141     JSClass<JSViewAbstract>::StaticMethod("setPixelRoundMode", &JSViewAbstract::SetPixelRoundMode);
7142     JSClass<JSViewAbstract>::StaticMethod("getPixelRoundMode", &JSViewAbstract::GetPixelRoundMode);
7143 
7144     JSClass<JSViewAbstract>::Bind(globalObj);
7145 }
7146 
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)7147 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
7148 {
7149     auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
7150         auto vm = info->GetVM();
7151         CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
7152         Local<JSValueRef> thisObj = info->GetFunctionRef();
7153         auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
7154         if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
7155             return panda::JSValueRef::Undefined(vm);
7156         }
7157 
7158         auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
7159         if (weak->Invalid()) {
7160             return panda::JSValueRef::Undefined(vm);
7161         }
7162 
7163         auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
7164         if (frameNode) {
7165             const auto& extensionHandler = frameNode->GetExtensionHandler();
7166             if (extensionHandler) {
7167                 extensionHandler->InvalidateRender();
7168             } else {
7169                 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
7170             }
7171         }
7172 
7173         return panda::JSValueRef::Undefined(vm);
7174     };
7175     auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
7176     if (frameNode) {
7177         const auto& extensionHandler = frameNode->GetExtensionHandler();
7178         if (extensionHandler) {
7179             extensionHandler->InvalidateRender();
7180         } else {
7181             frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
7182         }
7183     }
7184     auto vm = jsInvalidate->GetEcmaVM();
7185     auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
7186     jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
7187     jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
7188     jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
7189 }
7190 
JsDrawModifier(const JSCallbackInfo & info)7191 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
7192 {
7193     if (!info[0]->IsObject()) {
7194         return;
7195     }
7196 
7197     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
7198     bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
7199     if (!IsSupportDrawModifier) {
7200         return;
7201     }
7202     auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
7203     RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
7204     auto execCtx = info.GetExecutionContext();
7205     auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
7206         JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
7207         if (!drawMethod->IsFunction()) {
7208             return nullptr;
7209         }
7210 
7211         auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
7212             JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
7213 
7214         return GetDrawCallback(jsDrawFunc, execCtx, jsDrawModifier);
7215     };
7216 
7217     drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
7218     drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
7219     drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
7220 
7221     ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
7222     AddInvalidateFunc(jsDrawModifier, frameNode);
7223 }
7224 
JsAllowDrop(const JSCallbackInfo & info)7225 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
7226 {
7227     std::set<std::string> allowDropSet;
7228     allowDropSet.clear();
7229     if (!info[0]->IsUndefined() && info[0]->IsArray()) {
7230         auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
7231         std::string allowDrop;
7232         for (size_t i = 0; i < allowDropArray->Length(); i++) {
7233             allowDrop = allowDropArray->GetValueAt(i)->ToString();
7234             allowDropSet.insert(allowDrop);
7235         }
7236         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
7237     } else if (info[0]->IsNull()) {
7238         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
7239     } else {
7240         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
7241     }
7242     ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
7243 }
7244 
JsOnPreDrag(const JSCallbackInfo & info)7245 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
7246 {
7247     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
7248     auto jsVal = info[0];
7249     if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
7250         return;
7251     }
7252 
7253     RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
7254     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7255     auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
7256                          const PreDragStatus preDragStatus) {
7257         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7258         ACE_SCORING_EVENT("onPreDrag");
7259         PipelineContext::SetCallBackNode(node);
7260         func->PreDragExecute(preDragStatus);
7261     };
7262     ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
7263 }
7264 
ParseDragPreviewConfig(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)7265 void JSViewAbstract::ParseDragPreviewConfig(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
7266 {
7267     if (info.Length() <= 1) {
7268         return;
7269     }
7270     auto jsVal = info[1];
7271     if (!jsVal->IsObject()) {
7272         return;
7273     }
7274     auto config = JSRef<JSObject>::Cast(jsVal);
7275     ParseJsBool(config->GetProperty("onlyForLifting"), dragPreviewInfo.onlyForLifting);
7276     ParseJsBool(config->GetProperty("delayCreating"), dragPreviewInfo.delayCreating);
7277 }
7278 
ParseDragPreviewValue(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)7279 void JSViewAbstract::ParseDragPreviewValue(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
7280 {
7281     auto jsVal = info[0];
7282     JSRef<JSVal> builder;
7283     JSRef<JSVal> pixelMap;
7284     JSRef<JSVal> extraInfo;
7285     if (jsVal->IsFunction()) {
7286         builder = jsVal;
7287     } else if (jsVal->IsObject()) {
7288         auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
7289         builder = dragItemInfo->GetProperty("builder");
7290 #if defined(PIXEL_MAP_SUPPORTED)
7291         pixelMap = dragItemInfo->GetProperty("pixelMap");
7292         dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
7293 #endif
7294         extraInfo = dragItemInfo->GetProperty("extraInfo");
7295         ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
7296     } else if (jsVal->IsString()) {
7297         auto inspectorId = jsVal;
7298         ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
7299     } else {
7300         return;
7301     }
7302     ParseDragPreviewBuilderNode(info, dragPreviewInfo, builder);
7303 }
7304 
ParseDragPreviewBuilderNode(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo,const JSRef<JSVal> & builder)7305 void JSViewAbstract::ParseDragPreviewBuilderNode(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo,
7306     const JSRef<JSVal>& builder)
7307 {
7308     if (!builder->IsFunction()) {
7309         return;
7310     }
7311     RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7312     CHECK_NULL_VOID(builderFunc);
7313     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7314     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7315                          node = frameNode]() -> RefPtr<NG::UINode> {
7316         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
7317         ACE_SCORING_EVENT("dragPreview.builder");
7318         PipelineContext::SetCallBackNode(node);
7319         func->Execute();
7320         auto customNode = ViewStackModel::GetInstance()->Finish();
7321         return AceType::DynamicCast<NG::UINode>(customNode);
7322     };
7323     if (!dragPreviewInfo.delayCreating) {
7324         ViewStackModel::GetInstance()->NewScope();
7325         {
7326             dragPreviewInfo.customNode = buildFunc();
7327         }
7328     } else {
7329         dragPreviewInfo.buildFunc = buildFunc;
7330     }
7331 }
7332 
JsDragPreview(const JSCallbackInfo & info)7333 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
7334 {
7335     auto jsVal = info[0];
7336     if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
7337         return;
7338     }
7339     NG::DragDropInfo dragPreviewInfo;
7340     ParseDragPreviewConfig(info, dragPreviewInfo);
7341     ParseDragPreviewValue(info, dragPreviewInfo);
7342     ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
7343 }
7344 
JsAlignRules(const JSCallbackInfo & info)7345 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
7346 {
7347     if (!info[0]->IsObject()) {
7348         return;
7349     }
7350 
7351     JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
7352     if (valueObj->IsEmpty()) {
7353         return;
7354     }
7355     const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
7356     std::map<AlignDirection, AlignRule> alignRules;
7357     BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
7358     for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
7359         auto rule = valueObj->GetProperty(keys[i]);
7360         if (rule->IsObject()) {
7361             JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
7362             JSRef<JSVal> align = val->GetProperty("align");
7363             AlignRule alignRule;
7364             alignRule.anchor = val->GetProperty("anchor")->ToString();
7365             if (i < HORIZONTAL_DIRECTION_RANGE) {
7366                 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
7367             } else {
7368                 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
7369             }
7370             if (i < VERTICAL_DIRECTION_RANGE) {
7371                 alignRules[static_cast<AlignDirection>(i)] = alignRule;
7372             } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
7373                 alignRules[AlignDirection::LEFT] = alignRule;
7374             } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
7375                 alignRules[AlignDirection::RIGHT] = alignRule;
7376             }
7377             auto biasX = val->GetProperty("horizontal");
7378             if (biasX->IsNumber()) {
7379                 biasPair.first = biasX->ToNumber<float>();
7380             }
7381             auto biasY = val->GetProperty("vertical");
7382             if (biasY->IsNumber()) {
7383                 biasPair.second = biasY->ToNumber<float>();
7384             }
7385         }
7386     }
7387 
7388     ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
7389     ViewAbstractModel::GetInstance()->SetBias(biasPair);
7390 }
7391 
JsChainMode(const JSCallbackInfo & info)7392 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
7393 {
7394     ChainInfo chainInfo;
7395     if (info.Length() >= 1) {
7396         auto tmpDirection = info[0];
7397         if (tmpDirection->IsUndefined()) {
7398             chainInfo.direction = std::nullopt;
7399         } else if (tmpDirection->IsNumber()) {
7400             auto direction = tmpDirection->ToNumber<int32_t>();
7401             chainInfo.direction = static_cast<LineDirection>(direction);
7402         }
7403     }
7404 
7405     if (info.Length() >= 2) { // 2 : two args
7406         auto tmpStyle = info[1];
7407         if (tmpStyle->IsUndefined()) {
7408             chainInfo.style = std::nullopt;
7409         } else if (tmpStyle->IsNumber()) {
7410             auto style = tmpStyle->ToNumber<int32_t>();
7411             chainInfo.style = static_cast<ChainStyle>(style);
7412         }
7413     }
7414     ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
7415 }
7416 
SetMarginTop(const JSCallbackInfo & info)7417 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
7418 {
7419     CalcDimension value;
7420     if (!ParseJsDimensionVp(info[0], value)) {
7421         return;
7422     }
7423     ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
7424 }
7425 
SetMarginBottom(const JSCallbackInfo & info)7426 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
7427 {
7428     CalcDimension value;
7429     if (!ParseJsDimensionVp(info[0], value)) {
7430         return;
7431     }
7432     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
7433 }
7434 
SetMarginLeft(const JSCallbackInfo & info)7435 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
7436 {
7437     CalcDimension value;
7438     if (!ParseJsDimensionVp(info[0], value)) {
7439         return;
7440     }
7441     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
7442 }
7443 
SetMarginRight(const JSCallbackInfo & info)7444 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
7445 {
7446     CalcDimension value;
7447     if (!ParseJsDimensionVp(info[0], value)) {
7448         return;
7449     }
7450     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
7451 }
7452 
SetPaddingTop(const JSCallbackInfo & info)7453 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
7454 {
7455     CalcDimension value;
7456     if (!ParseJsDimensionVp(info[0], value)) {
7457         return;
7458     }
7459     ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
7460 }
7461 
SetPaddingBottom(const JSCallbackInfo & info)7462 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
7463 {
7464     CalcDimension value;
7465     if (!ParseJsDimensionVp(info[0], value)) {
7466         return;
7467     }
7468     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
7469 }
7470 
SetPaddingLeft(const JSCallbackInfo & info)7471 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
7472 {
7473     CalcDimension value;
7474     if (!ParseJsDimensionVp(info[0], value)) {
7475         return;
7476     }
7477     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
7478 }
7479 
SetPaddingRight(const JSCallbackInfo & info)7480 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
7481 {
7482     CalcDimension value;
7483     if (!ParseJsDimensionVp(info[0], value)) {
7484         return;
7485     }
7486     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
7487 }
7488 
SetSafeAreaPadding(const JSCallbackInfo & info)7489 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
7490 {
7491     ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
7492 }
7493 
SetColorBlend(Color color)7494 void JSViewAbstract::SetColorBlend(Color color)
7495 {
7496     ViewAbstractModel::GetInstance()->SetColorBlend(color);
7497 }
7498 
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)7499 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
7500 {
7501     ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
7502 }
7503 
SetDynamicLightUp(float rate,float lightUpDegree)7504 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
7505 {
7506     ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
7507 }
7508 
SetBgDynamicBrightness(BrightnessOption brightnessOption)7509 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
7510 {
7511     ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
7512 }
7513 
SetFgDynamicBrightness(BrightnessOption brightnessOption)7514 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
7515 {
7516     ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
7517 }
7518 
SetWindowBlur(float progress,WindowBlurStyle blurStyle)7519 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
7520 {
7521     ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
7522 }
7523 
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)7524 bool JSViewAbstract::ParseJsonDimension(
7525     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
7526 {
7527     if (!jsonValue || jsonValue->IsNull()) {
7528         return false;
7529     }
7530     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
7531         return false;
7532     }
7533     if (jsonValue->IsNumber()) {
7534         result = Dimension(jsonValue->GetDouble(), defaultUnit);
7535         return true;
7536     }
7537     if (jsonValue->IsString()) {
7538         if (checkIllegal) {
7539             return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
7540         }
7541         result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
7542         return true;
7543     }
7544     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7545     auto resId = resVal->GetValue("id");
7546     if (!resId || !resId->IsNumber()) {
7547         return false;
7548     }
7549 
7550     auto resourceWrapper = CreateResourceWrapper();
7551     if (!resourceWrapper) {
7552         return false;
7553     }
7554     result = resourceWrapper->GetDimension(resId->GetUInt());
7555     return true;
7556 }
7557 
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)7558 bool JSViewAbstract::ParseJsonDimensionVp(
7559     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
7560 {
7561     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
7562         return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
7563     }
7564     return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
7565 }
7566 
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)7567 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
7568 {
7569     if (!jsonValue || jsonValue->IsNull()) {
7570         return false;
7571     }
7572     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
7573         return false;
7574     }
7575     if (jsonValue->IsNumber()) {
7576         result = jsonValue->GetDouble();
7577         return true;
7578     }
7579     if (jsonValue->IsString()) {
7580         result = StringUtils::StringToDouble(jsonValue->GetString());
7581         return true;
7582     }
7583     // parse json Resource
7584     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7585     auto resId = resVal->GetValue("id");
7586     CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
7587     auto id = resId->GetUInt();
7588     auto resType = resVal->GetValue("type");
7589     CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
7590     auto type = resType->GetUInt();
7591 
7592     auto resourceWrapper = CreateResourceWrapper();
7593     if (!resourceWrapper) {
7594         return false;
7595     }
7596     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
7597         auto numberString = resourceWrapper->GetString(id);
7598         return StringUtils::StringToDouble(numberString, result);
7599     }
7600     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
7601         result = resourceWrapper->GetInt(id);
7602         return true;
7603     }
7604     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
7605         result = resourceWrapper->GetDouble(id);
7606         return true;
7607     }
7608     return false;
7609 }
7610 
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)7611 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
7612 {
7613     if (!jsonValue || jsonValue->IsNull()) {
7614         return false;
7615     }
7616     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
7617         return false;
7618     }
7619     if (jsonValue->IsNumber()) {
7620         result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
7621         return true;
7622     }
7623 
7624     bool isSetColor = false;
7625     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
7626         isSetColor = jsonValue->IsString();
7627     } else {
7628         isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
7629     }
7630     if (isSetColor) {
7631         result = Color::FromString(jsonValue->GetString());
7632         return true;
7633     }
7634     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7635     auto resId = resVal->GetValue("id");
7636     if (!resId || !resId->IsNumber()) {
7637         return false;
7638     }
7639     auto resourceWrapper = CreateResourceWrapper();
7640     if (!resourceWrapper) {
7641         return false;
7642     }
7643     result = resourceWrapper->GetColor(resId->GetUInt());
7644     return true;
7645 }
7646 
ParseShadowOffsetXY(const JSRef<JSObject> & jsObj,Shadow & shadow)7647 void JSViewAbstract::ParseShadowOffsetXY(const JSRef<JSObject>& jsObj, Shadow& shadow)
7648 {
7649     CalcDimension offsetX;
7650     if (ParseJsResource(jsObj->GetProperty("offsetX"), offsetX)) {
7651         shadow.SetOffsetX(offsetX.Value());
7652     } else {
7653         if (ParseJsDimensionVp(jsObj->GetProperty("offsetX"), offsetX)) {
7654             shadow.SetOffsetX(offsetX.Value());
7655         }
7656     }
7657     CalcDimension offsetY;
7658     auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
7659     if (ParseJsResource(jsOffsetY, offsetY)) {
7660         shadow.SetOffsetY(offsetY.Value());
7661     } else {
7662         if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
7663             shadow.SetOffsetY(offsetY.Value());
7664         }
7665     }
7666 }
7667 
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)7668 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
7669 {
7670     int32_t shadowStyle = 0;
7671     if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
7672         auto style = static_cast<ShadowStyle>(shadowStyle);
7673         return GetShadowFromTheme(style, shadow);
7674     }
7675     if (!jsValue->IsObject()) {
7676         return false;
7677     }
7678     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7679     double radius = 0.0;
7680     ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
7681     if (LessNotEqual(radius, 0.0)) {
7682         radius = 0.0;
7683     }
7684     shadow.SetBlurRadius(radius);
7685     ParseShadowOffsetXY(jsObj, shadow);
7686 
7687     Color color;
7688     ShadowColorStrategy shadowColorStrategy;
7689     auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
7690     if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
7691         shadow.SetShadowColorStrategy(shadowColorStrategy);
7692     } else if (ParseJsColor(jsColor, color)) {
7693         shadow.SetColor(color);
7694     }
7695     int32_t type = static_cast<int32_t>(ShadowType::COLOR);
7696     JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
7697     if (type != static_cast<int32_t>(ShadowType::BLUR)) {
7698         type = static_cast<int32_t>(ShadowType::COLOR);
7699     }
7700     shadow.SetShadowType(static_cast<ShadowType>(type));
7701     bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
7702     shadow.SetIsFilled(isFilled);
7703     return true;
7704 }
7705 
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)7706 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
7707 {
7708     auto colorMode = Container::CurrentColorMode();
7709     if (shadowStyle == ShadowStyle::None) {
7710         return true;
7711     }
7712 
7713     auto container = Container::Current();
7714     CHECK_NULL_RETURN(container, false);
7715     auto pipelineContext = container->GetPipelineContext();
7716     CHECK_NULL_RETURN(pipelineContext, false);
7717 
7718     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
7719     if (!shadowTheme) {
7720         return false;
7721     }
7722 
7723     shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
7724     return true;
7725 }
7726 
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)7727 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
7728 {
7729     if (!jsValue->IsObject()) {
7730         return false;
7731     }
7732     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7733     uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
7734     if (type == 0) {
7735         return false;
7736     }
7737     auto resourceWrapper = CreateResourceWrapper();
7738     CHECK_NULL_RETURN(resourceWrapper, false);
7739     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
7740         auto value = resourceWrapper->GetString(
7741             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
7742         return StringUtils::StringToCalcDimensionNG(value, result, false);
7743     }
7744     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
7745         auto value = std::to_string(
7746             resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
7747         StringUtils::StringToDimensionWithUnitNG(value, result);
7748         return true;
7749     }
7750 
7751     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
7752         result = resourceWrapper->GetDimension(
7753             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
7754         return true;
7755     }
7756     return false;
7757 }
7758 
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)7759 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
7760 {
7761     JSRef<JSVal> arg = info[0];
7762     if (!arg->IsObject()) {
7763         return false;
7764     }
7765     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
7766     JSRef<JSVal> typeValue = obj->GetProperty("types");
7767     if (!typeValue->IsArray()) {
7768         return false;
7769     }
7770     JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
7771     for (size_t i = 0; i < array->Length(); i++) {
7772         JSRef<JSVal> value = array->GetValueAt(i);
7773         auto index = value->ToNumber<int32_t>();
7774         if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
7775             return false;
7776         }
7777         if (i != 0) {
7778             textDetectConfig.types.append(",");
7779         }
7780         textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
7781     }
7782     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7783     JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
7784     if (resultCallback->IsFunction()) {
7785         auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
7786         textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
7787                        const std::string& result) {
7788             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7789             PipelineContext::SetCallBackNode(node);
7790             func->Execute(result);
7791         };
7792     }
7793 
7794     return ParseAIEntityColor(obj, textDetectConfig);
7795 }
7796 
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)7797 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
7798 {
7799     JSRef<JSVal> entityColorValue = obj->GetProperty("color");
7800     ParseJsColor(entityColorValue, textDetectConfig.entityColor);
7801 
7802     JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
7803     if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
7804         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
7805         return true;
7806     }
7807     JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
7808     JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
7809     JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
7810     JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
7811 
7812     if (typeValue->IsNumber()) {
7813         textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
7814     } else {
7815         textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
7816     }
7817     if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
7818         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
7819     }
7820     if (styleValue->IsNumber()) {
7821          textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
7822     } else {
7823         textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
7824     }
7825 
7826     return true;
7827 }
7828 
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)7829 void JSViewAbstract::GetAngle(
7830     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
7831 {
7832     auto value = jsonValue->GetValue(key);
7833     if (value && value->IsString()) {
7834         angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
7835     } else if (value && value->IsNumber()) {
7836         angle = static_cast<float>(value->GetDouble());
7837     }
7838 }
7839 
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)7840 void JSViewAbstract::GetJsAngle(
7841     int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
7842 {
7843     if (!jsValue->IsObject()) {
7844         return;
7845     }
7846     JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
7847     if (value->IsString()) {
7848         angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
7849     } else if (value->IsNumber()) {
7850         angle = value->ToNumber<float>();
7851     }
7852 }
7853 
7854 // 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)7855 void JSViewAbstract::GetJsAngleWithDefault(
7856     int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
7857 {
7858     JSRef<JSVal> value = jsObj->GetProperty(key);
7859     if (value->IsString()) {
7860         double temp = 0.0;
7861         if (StringUtils::StringToDegree(value->ToString(), temp)) {
7862             angle = static_cast<float>(temp);
7863         } else {
7864             angle = defaultValue;
7865         }
7866     } else if (value->IsNumber()) {
7867         angle = value->ToNumber<float>();
7868     }
7869 }
7870 
CheckAngle(std::optional<float> & angle)7871 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
7872 {
7873     angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
7874 }
7875 
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)7876 void JSViewAbstract::GetPerspective(
7877     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
7878 {
7879     auto value = jsonValue->GetValue(key);
7880     if (value && value->IsNumber()) {
7881         perspective = static_cast<float>(value->GetDouble());
7882     }
7883 }
7884 
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)7885 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
7886 {
7887     auto value = jsValue->GetProperty(key);
7888     if (value->IsNumber()) {
7889         perspective = value->ToNumber<float>();
7890     }
7891 }
7892 
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)7893 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
7894 {
7895     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
7896         return;
7897     }
7898 
7899     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
7900         GradientColor gradientColor;
7901         auto item = colorStops->GetArrayItem(i);
7902         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
7903             auto colorParams = item->GetArrayItem(0);
7904             // color
7905             Color color;
7906             if (!ParseJsonColor(colorParams, color)) {
7907                 continue;
7908             }
7909             gradientColor.SetColor(color);
7910             gradientColor.SetHasValue(false);
7911             // stop value
7912             if (item->GetArraySize() <= 1) {
7913                 continue;
7914             }
7915             auto stopValue = item->GetArrayItem(1);
7916             double value = 0.0;
7917             if (ParseJsonDouble(stopValue, value)) {
7918                 value = std::clamp(value, 0.0, 1.0);
7919                 gradientColor.SetHasValue(true);
7920                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7921             }
7922             gradient.AddColor(gradientColor);
7923         }
7924     }
7925 }
7926 
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)7927 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
7928 {
7929     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
7930         return;
7931     }
7932 
7933     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
7934         NG::GradientColor gradientColor;
7935         auto item = colorStops->GetArrayItem(i);
7936         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
7937             auto colorParams = item->GetArrayItem(0);
7938             // color
7939             Color color;
7940             if (!ParseJsonColor(colorParams, color)) {
7941                 continue;
7942             }
7943             gradientColor.SetColor(color);
7944             gradientColor.SetHasValue(false);
7945             // stop value
7946             if (item->GetArraySize() <= 1) {
7947                 continue;
7948             }
7949             auto stopValue = item->GetArrayItem(1);
7950             double value = 0.0;
7951             if (ParseJsonDouble(stopValue, value)) {
7952                 value = std::clamp(value, 0.0, 1.0);
7953                 gradientColor.SetHasValue(true);
7954                 //  [0, 1] -> [0, 100.0];
7955                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7956             }
7957             gradient.AddColor(gradientColor);
7958         }
7959     }
7960 }
7961 
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)7962 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
7963 {
7964     if (!colorStops->IsArray()) {
7965         return;
7966     }
7967 
7968     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
7969     size_t length = jsArray->Length();
7970     for (size_t i = 0; i < length; i++) {
7971         NG::GradientColor gradientColor;
7972         JSRef<JSVal> item = jsArray->GetValueAt(i);
7973         if (!item->IsArray()) {
7974             continue;
7975         }
7976         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
7977         if (subArray->Length() < 2) {
7978             continue;
7979         }
7980         // color
7981         Color color;
7982         if (!ParseJsColor(subArray->GetValueAt(0), color)) {
7983             continue;
7984         }
7985         gradientColor.SetColor(color);
7986         gradientColor.SetHasValue(false);
7987         // stop value
7988         double value = 0.0;
7989         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
7990             value = std::clamp(value, 0.0, 1.0);
7991             gradientColor.SetHasValue(true);
7992         }
7993         //  [0, 1] -> [0, 100.0];
7994         gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7995         gradient.AddColor(gradientColor);
7996     }
7997 }
7998 
SetDirection(const std::string & dir)7999 void JSViewAbstract::SetDirection(const std::string& dir)
8000 {
8001     TextDirection direction = TextDirection::AUTO;
8002     if (dir == "Ltr") {
8003         direction = TextDirection::LTR;
8004     } else if (dir == "Rtl") {
8005         direction = TextDirection::RTL;
8006     } else if (dir == "Auto") {
8007         direction = TextDirection::AUTO;
8008     } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
8009         direction = TextDirection::AUTO;
8010     }
8011     ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
8012 }
8013 
GetThemeConstants(const JSRef<JSObject> & jsObj)8014 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
8015 {
8016     std::string bundleName;
8017     std::string moduleName;
8018     if (!jsObj->IsUndefined()) {
8019         JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
8020         JSRef<JSVal> module = jsObj->GetProperty("moduleName");
8021         if (bundle->IsString() && module->IsString()) {
8022             bundleName = bundle->ToString();
8023             moduleName = module->ToString();
8024         }
8025     }
8026 
8027     auto cardId = CardScope::CurrentId();
8028     if (cardId != INVALID_CARD_ID) {
8029         auto container = Container::Current();
8030         auto weak = container->GetCardPipeline(cardId);
8031         auto cardPipelineContext = weak.Upgrade();
8032         CHECK_NULL_RETURN(cardPipelineContext, nullptr);
8033         auto cardThemeManager = cardPipelineContext->GetThemeManager();
8034         CHECK_NULL_RETURN(cardThemeManager, nullptr);
8035         return cardThemeManager->GetThemeConstants(bundleName, moduleName);
8036     }
8037 
8038 #ifdef PLUGIN_COMPONENT_SUPPORTED
8039     if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
8040         auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
8041         if (!pluginContainer) {
8042             return nullptr;
8043         }
8044         auto pluginPipelineContext = pluginContainer->GetPipelineContext();
8045         if (!pluginPipelineContext) {
8046             return nullptr;
8047         }
8048         auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
8049         if (!pluginThemeManager) {
8050             return nullptr;
8051         }
8052         return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
8053     }
8054 #endif
8055     auto container = Container::Current();
8056     CHECK_NULL_RETURN(container, nullptr);
8057     auto pipelineContext = container->GetPipelineContext();
8058     CHECK_NULL_RETURN(pipelineContext, nullptr);
8059     auto themeManager = pipelineContext->GetThemeManager();
8060     CHECK_NULL_RETURN(themeManager, nullptr);
8061     return themeManager->GetThemeConstants(bundleName, moduleName);
8062 }
8063 
JsHoverEffect(const JSCallbackInfo & info)8064 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
8065 {
8066     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
8067     auto jsVal = info[0];
8068     if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
8069         ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
8070         return;
8071     }
8072     if (!jsVal->IsNumber()) {
8073         return;
8074     }
8075     ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
8076 }
8077 
JsOnMouse(const JSCallbackInfo & info)8078 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
8079 {
8080     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
8081         ViewAbstractModel::GetInstance()->DisableOnMouse();
8082         return;
8083     }
8084     if (!info[0]->IsFunction()) {
8085         return;
8086     }
8087 
8088     RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
8089     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8090     auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
8091                        MouseInfo& mouseInfo) {
8092         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8093         ACE_SCORING_EVENT("onMouse");
8094         PipelineContext::SetCallBackNode(node);
8095         func->Execute(mouseInfo);
8096     };
8097     ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
8098 }
8099 
JsOnAxisEvent(const JSCallbackInfo & args)8100 void JSViewAbstract::JsOnAxisEvent(const JSCallbackInfo& args)
8101 {
8102     JSRef<JSVal> arg = args[0];
8103     if (arg->IsUndefined() && IsDisableEventVersion()) {
8104         ViewAbstractModel::GetInstance()->DisableOnAxisEvent();
8105         return;
8106     }
8107     if (!arg->IsFunction()) {
8108         return;
8109     }
8110     EcmaVM* vm = args.GetVm();
8111     CHECK_NULL_VOID(vm);
8112     auto jsOnAxisEventFunc = JSRef<JSFunc>::Cast(args[0]);
8113     if (jsOnAxisEventFunc->IsEmpty()) {
8114         return;
8115     }
8116     auto jsOnAxisFuncLocalHandle = jsOnAxisEventFunc->GetLocalHandle();
8117     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8118     auto onAxisEvent = [vm, execCtx = args.GetExecutionContext(),
8119                        func = panda::CopyableGlobal(vm, jsOnAxisFuncLocalHandle),
8120                        node = frameNode](Ace::AxisInfo& info) {
8121         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8122         ACE_SCORING_EVENT("onAxis");
8123         PipelineContext::SetCallBackNode(node);
8124         auto eventObj = NG::CommonBridge::CreateAxisEventInfo(vm, info);
8125         panda::Local<panda::JSValueRef> params[1] = { eventObj };
8126         func->Call(vm, func.ToLocal(), params, 1);
8127     };
8128     ViewAbstractModel::GetInstance()->SetOnAxisEvent(std::move(onAxisEvent));
8129 }
8130 
JsOnHover(const JSCallbackInfo & info)8131 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
8132 {
8133     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
8134         ViewAbstractModel::GetInstance()->DisableOnHover();
8135         return;
8136     }
8137     if (!info[0]->IsFunction()) {
8138         return;
8139     }
8140 
8141     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
8142     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8143     auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
8144                        bool isHover, HoverInfo& hoverInfo) {
8145         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8146         ACE_SCORING_EVENT("onHover");
8147         PipelineContext::SetCallBackNode(node);
8148         func->HoverExecute(isHover, hoverInfo);
8149     };
8150     ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
8151 }
8152 
JsOnHoverMove(const JSCallbackInfo & info)8153 void JSViewAbstract::JsOnHoverMove(const JSCallbackInfo& info)
8154 {
8155     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
8156         ViewAbstractModel::GetInstance()->DisableOnHoverMove();
8157         return;
8158     }
8159     if (!info[0]->IsFunction()) {
8160         return;
8161     }
8162 
8163     RefPtr<JsHoverFunction> jsOnHoverMoveFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
8164     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8165     auto onHoverMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverMoveFunc), node = frameNode](
8166                        HoverInfo& hoverInfo) {
8167         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8168         ACE_SCORING_EVENT("onHoverMove");
8169         PipelineContext::SetCallBackNode(node);
8170         func->HoverMoveExecute(hoverInfo);
8171     };
8172     ViewAbstractModel::GetInstance()->SetOnHoverMove(std::move(onHoverMove));
8173 }
8174 
JsOnAccessibilityHover(const JSCallbackInfo & info)8175 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
8176 {
8177     if (info[0]->IsUndefined()) {
8178         ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
8179         return;
8180     }
8181     if (!info[0]->IsFunction()) {
8182         return;
8183     }
8184 
8185     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
8186     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8187     auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
8188                                     node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
8189         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8190         ACE_SCORING_EVENT("onAccessibilityHover");
8191         PipelineContext::SetCallBackNode(node);
8192         func->AccessibilityHoverExecute(isHover, hoverInfo);
8193     };
8194     ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
8195 }
8196 
JsOnClick(const JSCallbackInfo & info)8197 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
8198 {
8199     auto arg = info[0];
8200     if (arg->IsUndefined() && IsDisableEventVersion()) {
8201         ViewAbstractModel::GetInstance()->DisableOnClick();
8202         return;
8203     }
8204     if (!arg->IsFunction()) {
8205         return;
8206     }
8207 
8208     auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
8209     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8210     auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
8211                      BaseEventInfo* info) {
8212         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8213         auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
8214         ACE_SCORING_EVENT("onClick");
8215         PipelineContext::SetCallBackNode(node);
8216         func->Execute(*tapInfo);
8217 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
8218         JSInteractableView::ReportClickEvent(node);
8219 #endif
8220     };
8221     auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
8222     auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
8223                        const ClickInfo* info) {
8224         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8225         ACE_SCORING_EVENT("onClick");
8226         PipelineContext::SetCallBackNode(node);
8227         func->Execute(*info);
8228 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
8229         JSInteractableView::ReportClickEvent(node);
8230 #endif
8231     };
8232 
8233     double distanceThreshold = std::numeric_limits<double>::infinity();
8234     if (info.Length() > 1 && info[1]->IsNumber()) {
8235         distanceThreshold = info[1]->ToNumber<double>();
8236         if (distanceThreshold < 0) {
8237             distanceThreshold = std::numeric_limits<double>::infinity();
8238         }
8239     }
8240     distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
8241     ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
8242 }
8243 
JsOnGestureJudgeBegin(const JSCallbackInfo & info)8244 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
8245 {
8246     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8247         ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
8248         return;
8249     }
8250 
8251     auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
8252     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8253     auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
8254                                   const RefPtr<NG::GestureInfo>& gestureInfo,
8255                                   const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
8256         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
8257         ACE_SCORING_EVENT("onGestureJudgeBegin");
8258         PipelineContext::SetCallBackNode(node);
8259         return func->Execute(gestureInfo, info);
8260     };
8261     ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
8262 }
8263 
JsOnTouchIntercept(const JSCallbackInfo & info)8264 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
8265 {
8266     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8267         ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
8268         return;
8269     }
8270 
8271     auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
8272     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8273     auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
8274                                     TouchEventInfo& info) -> NG::HitTestMode {
8275         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
8276         ACE_SCORING_EVENT("onTouchIntercept");
8277         PipelineContext::SetCallBackNode(node);
8278         return func->Execute(info);
8279     };
8280     ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
8281 }
8282 
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)8283 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
8284 {
8285     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8286         ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
8287         return;
8288     }
8289 
8290     auto jsParallelInnerGestureToFunc =
8291         AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
8292     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8293     auto shouldBuiltInRecognizerParallelWithFunc =
8294         [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
8295             const RefPtr<NG::NGGestureRecognizer>& current,
8296             const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
8297         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
8298         ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
8299         PipelineContext::SetCallBackNode(node);
8300         return func->Execute(current, others);
8301     };
8302     ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
8303         std::move(shouldBuiltInRecognizerParallelWithFunc));
8304 }
8305 
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)8306 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
8307 {
8308     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8309         ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
8310         return;
8311     }
8312 
8313     auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
8314     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8315     auto onGestureRecognizerJudgefunc =
8316         [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
8317             const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
8318             const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
8319         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
8320         ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
8321         PipelineContext::SetCallBackNode(node);
8322         return func->Execute(info, current, others);
8323     };
8324 
8325     bool exposeInnerGestureFlag = false;
8326     if (info.Length() > 1 && info[1]->IsBoolean()) {
8327         exposeInnerGestureFlag = info[1]->ToBoolean();
8328     }
8329     ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
8330         std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
8331 }
8332 
JsClickEffect(const JSCallbackInfo & info)8333 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
8334 {
8335     JSRef<JSVal> arg = info[0];
8336     if (arg->IsUndefined() || arg->IsNull()) {
8337         ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
8338         return;
8339     }
8340     if (!arg->IsObject()) {
8341         return;
8342     }
8343     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
8344     JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
8345     int32_t clickEffectLevelValue = 0;
8346     if (clickEffectLevel->IsNumber()) {
8347         clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
8348         if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
8349             clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
8350             clickEffectLevelValue = 0;
8351         }
8352     }
8353 
8354     JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
8355     float scaleNumberValue = DEFAULT_SCALE_LIGHT;
8356     if (!scaleNumber->IsNumber()) {
8357         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
8358             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
8359             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
8360         }
8361         ViewAbstractModel::GetInstance()->SetClickEffectLevel(
8362             (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
8363         return;
8364     }
8365 
8366     scaleNumberValue = scaleNumber->ToNumber<float>();
8367     if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
8368         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
8369             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
8370             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
8371         } else {
8372             scaleNumberValue = DEFAULT_SCALE_LIGHT;
8373         }
8374     }
8375 
8376     ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
8377 }
8378 
JsOnVisibleAreaChange(const JSCallbackInfo & info)8379 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
8380 {
8381     if (info.Length() != 2) {
8382         return;
8383     }
8384 
8385     if (!info[0]->IsArray() || !info[1]->IsFunction()) {
8386         return;
8387     }
8388 
8389     auto ratioArray = JSRef<JSArray>::Cast(info[0]);
8390     size_t size = ratioArray->Length();
8391     std::vector<double> ratioVec(size);
8392     ratioVec.clear();
8393     for (size_t i = 0; i < size; i++) {
8394         double ratio = 0.0;
8395         ParseJsDouble(ratioArray->GetValueAt(i), ratio);
8396         if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
8397             ratio = VISIBLE_RATIO_MIN;
8398         }
8399 
8400         if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
8401             ratio = VISIBLE_RATIO_MAX;
8402         }
8403         ratioVec.push_back(ratio);
8404     }
8405 
8406     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
8407     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8408     auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
8409                                bool visible, double ratio) {
8410         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8411         ACE_SCORING_EVENT("onVisibleAreaChange");
8412 
8413         JSRef<JSVal> params[2];
8414         params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
8415         params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
8416         PipelineContext::SetCallBackNode(node);
8417         func->ExecuteJS(2, params);
8418     };
8419     ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
8420 }
8421 
JsOnVisibleAreaApproximateChange(const JSCallbackInfo & info)8422 void JSViewAbstract::JsOnVisibleAreaApproximateChange(const JSCallbackInfo& info)
8423 {
8424     if (info.Length() != PARAMETER_LENGTH_SECOND) {
8425         return;
8426     }
8427 
8428     if (!info[0]->IsObject() || !info[1]->IsFunction()) {
8429         return;
8430     }
8431 
8432     const auto& options = info[0];
8433     JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(options);
8434     JSRef<JSVal> ratios = optionObj->GetProperty("ratios");
8435     if (!ratios->IsArray()) {
8436         return;
8437     }
8438     auto ratioArray = JSRef<JSArray>::Cast(ratios);
8439     size_t size = ratioArray->Length();
8440     std::vector<double> ratioVec(size);
8441     for (size_t i = 0; i < size; i++) {
8442         double ratio = 0.0;
8443         ParseJsDouble(ratioArray->GetValueAt(i), ratio);
8444         ratio = std::clamp(ratio, VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
8445         ratioVec.push_back(ratio);
8446     }
8447     int32_t expectedUpdateInterval = DEFAULT_DURATION;
8448     JSRef<JSVal> expectedUpdateIntervalVal = optionObj->GetProperty("expectedUpdateInterval");
8449     if (expectedUpdateIntervalVal->IsNumber()) {
8450         JSViewAbstract::ParseJsInteger(expectedUpdateIntervalVal, expectedUpdateInterval);
8451     }
8452     if (expectedUpdateInterval < 0) {
8453         expectedUpdateInterval = DEFAULT_DURATION;
8454     }
8455 
8456     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
8457     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8458     auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
8459                                bool visible, double ratio) {
8460         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8461         ACE_SCORING_EVENT("onVisibleAreaApproximateChange");
8462 
8463         JSRef<JSVal> params[2];
8464         params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
8465         params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
8466         PipelineContext::SetCallBackNode(node);
8467         func->ExecuteJS(2, params);
8468     };
8469     ViewAbstractModel::GetInstance()->SetOnVisibleAreaApproximateChange(
8470         std::move(onVisibleChange), ratioVec, expectedUpdateInterval);
8471 }
8472 
JsHitTestBehavior(const JSCallbackInfo & info)8473 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
8474 {
8475     if (info.Length() != 1 || !info[0]->IsNumber()) {
8476         return;
8477     }
8478 
8479     NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
8480     hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
8481     ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
8482 }
8483 
JsOnChildTouchTest(const JSCallbackInfo & info)8484 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
8485 {
8486     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8487     auto jsVal = info[0];
8488     if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
8489         return;
8490     }
8491 
8492     RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
8493         AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
8494 
8495     auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
8496                                const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
8497         NG::TouchResult touchRes;
8498         NG::TouchResult defaultRes;
8499         defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
8500         defaultRes.id = "";
8501         auto ret = func->Execute(touchInfo);
8502         if (!ret->IsObject()) {
8503             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
8504             return defaultRes;
8505         }
8506 
8507         auto retObj = JSRef<JSObject>::Cast(ret);
8508         auto strategy = retObj->GetProperty("strategy");
8509         if (!strategy->IsNumber()) {
8510             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
8511             return defaultRes;
8512         }
8513         touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
8514         auto id = retObj->GetProperty("id");
8515         if (!id->IsString()) {
8516             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
8517             return defaultRes;
8518         }
8519         touchRes.id = id->ToString();
8520         return touchRes;
8521     };
8522     ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
8523 }
8524 
JsForegroundColor(const JSCallbackInfo & info)8525 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
8526 {
8527     Color foregroundColor = Color::TRANSPARENT;
8528     ForegroundColorStrategy strategy;
8529     if (ParseJsColorStrategy(info[0], strategy)) {
8530         ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
8531         return;
8532     }
8533     ParseJsColor(info[0], foregroundColor);
8534     ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
8535 }
8536 
JsKeyboardShortcut(const JSCallbackInfo & info)8537 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
8538 {
8539     // KeyboardShortcut only allows 2 or 3 params.
8540     if (info.Length() < 2 || info.Length() > 3) {
8541         return;
8542     }
8543     if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
8544         // clear shortcut key
8545         ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
8546         return;
8547     }
8548 
8549     std::string value;
8550     if (info[0]->IsString()) {
8551         // common letter/number/symbol
8552         value = info[0]->ToString();
8553         if (value.size() != 1) {
8554             // clear shortcut key
8555             ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
8556             return;
8557         }
8558     } else {
8559         // function keys such as F1-F10/ESC
8560         FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
8561         value = GetFunctionKeyName(functionkey);
8562     }
8563 
8564     auto keysArray = JSRef<JSArray>::Cast(info[1]);
8565     size_t size = keysArray->Length();
8566     std::vector<ModifierKey> keys(size);
8567     keys.clear();
8568     for (size_t i = 0; i < size; i++) {
8569         JSRef<JSVal> key = keysArray->GetValueAt(i);
8570         if (key->IsNumber()) {
8571             keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
8572         }
8573     }
8574 
8575     // KeyboardShortcut allows 3 params, the third param is function callback.
8576     if (info.Length() == 3 && info[2]->IsFunction()) {
8577         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
8578         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8579         auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
8580                                             node = frameNode]() {
8581             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8582             ACE_SCORING_EVENT("onKeyboardShortcutAction");
8583             PipelineContext::SetCallBackNode(node);
8584             func->ExecuteJS();
8585         };
8586         ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
8587         return;
8588     }
8589     ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
8590 }
8591 
JsOnFocusAxisEvent(const JSCallbackInfo & args)8592 void JSViewAbstract::JsOnFocusAxisEvent(const JSCallbackInfo& args)
8593 {
8594     JSRef<JSVal> arg = args[0];
8595     if (arg->IsUndefined() && IsDisableEventVersion()) {
8596         ViewAbstractModel::GetInstance()->DisableOnFocusAxisEvent();
8597         return;
8598     }
8599     if (!arg->IsFunction()) {
8600         return;
8601     }
8602     EcmaVM* vm = args.GetVm();
8603     CHECK_NULL_VOID(vm);
8604     auto jsOnFocusAxisEventFunc = JSRef<JSFunc>::Cast(arg);
8605     if (jsOnFocusAxisEventFunc->IsEmpty()) {
8606         return;
8607     }
8608     auto jsOnFocusAxisFuncLocalHandle = jsOnFocusAxisEventFunc->GetLocalHandle();
8609     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8610     auto onFocusAxisEvent = [vm, execCtx = args.GetExecutionContext(),
8611                        func = panda::CopyableGlobal(vm, jsOnFocusAxisFuncLocalHandle),
8612                        node = frameNode](NG::FocusAxisEventInfo& info) {
8613         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8614         ACE_SCORING_EVENT("onFocusAxis");
8615         PipelineContext::SetCallBackNode(node);
8616         auto eventObj = NG::CommonBridge::CreateFocusAxisEventInfo(vm, info);
8617         panda::Local<panda::JSValueRef> params[1] = { eventObj };
8618         func->Call(vm, func.ToLocal(), params, 1);
8619     };
8620     ViewAbstractModel::GetInstance()->SetOnFocusAxisEvent(std::move(onFocusAxisEvent));
8621 }
8622 
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)8623 bool JSViewAbstract::CheckColor(
8624     const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
8625 {
8626     // Color is undefined or null
8627     if (jsValue->IsUndefined() || jsValue->IsNull()) {
8628         return false;
8629     }
8630     // input type is not in [number, string, Resource]
8631     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
8632         return false;
8633     }
8634     // Correct type, incorrect value parsing
8635     if (!ParseJsColor(jsValue, result)) {
8636         return false;
8637     }
8638     return true;
8639 }
8640 
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)8641 bool JSViewAbstract::CheckLength(
8642     const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
8643 {
8644     // Length is undefined or null
8645     if (jsValue->IsUndefined() || jsValue->IsNull()) {
8646         return false;
8647     }
8648     // input type is not in [number, string, Resource]
8649     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
8650         return false;
8651     }
8652     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
8653         return ParseJsDimensionVpNG(jsValue, result);
8654     }
8655     // Correct type, incorrect value parsing
8656     if (!ParseJsDimensionVp(jsValue, result)) {
8657         return false;
8658     }
8659     return true;
8660 }
8661 
8662 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)8663 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
8664 {
8665     JSRef<JSVal> arg = info[0];
8666     if (arg->IsUndefined() || arg->IsNull()) {
8667         std::vector<ObscuredReasons> reasons(0);
8668         ViewAbstractModel::GetInstance()->SetObscured(reasons);
8669         return;
8670     }
8671     if (!arg->IsArray()) {
8672         return;
8673     }
8674 
8675     auto obscuredArray = JSRef<JSArray>::Cast(arg);
8676     size_t size = obscuredArray->Length();
8677     std::vector<ObscuredReasons> reasons(size);
8678     reasons.clear();
8679     for (size_t i = 0; i < size; i++) {
8680         JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
8681         if (reason->IsNumber()) {
8682             reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
8683         }
8684     }
8685 
8686     ViewAbstractModel::GetInstance()->SetObscured(reasons);
8687 }
8688 
8689 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)8690 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
8691 {
8692     auto sensitiveInfo = info[0];
8693     if (sensitiveInfo->IsUndefined()) {
8694         ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
8695         return;
8696     }
8697     bool sensitive = false;
8698     if (sensitiveInfo->IsBoolean()) {
8699         sensitive = sensitiveInfo->ToBoolean();
8700     }
8701     ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
8702 }
8703 
JSRenderGroup(const JSCallbackInfo & info)8704 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
8705 {
8706     if (info.Length() != 1) {
8707         return;
8708     }
8709     bool isRenderGroup = false;
8710     if (info[0]->IsBoolean()) {
8711         isRenderGroup = info[0]->ToBoolean();
8712     }
8713     ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
8714 }
8715 
JSRenderFit(const JSCallbackInfo & info)8716 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
8717 {
8718     if (info.Length() != 1) {
8719         return;
8720     }
8721     RenderFit renderFit = RenderFit::TOP_LEFT;
8722     if (info[0]->IsNumber()) {
8723         int32_t fitNumber = info[0]->ToNumber<int32_t>();
8724         if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
8725             fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
8726             renderFit = static_cast<RenderFit>(fitNumber);
8727         }
8728     }
8729     // how content fills the node duration implicit animation
8730     ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
8731 }
8732 
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)8733 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
8734 {
8735     if (!jsValue->IsObject() || jsValue->IsString()) {
8736         return false;
8737     }
8738     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
8739     if (!jsObj->IsUndefined()) {
8740         JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
8741         JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
8742         if (bundle->IsString() && module->IsString()) {
8743             bundleName = bundle->ToString();
8744             moduleName = module->ToString();
8745             return true;
8746         }
8747     }
8748     return false;
8749 }
8750 
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)8751 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
8752 {
8753     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8754         return false;
8755     }
8756     Color borderColor;
8757     if (ParseJsColor(args, borderColor)) {
8758         colorProperty.SetColor(borderColor);
8759         return true;
8760     } else if (args->IsObject()) {
8761         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
8762         CommonColor commonColor;
8763         auto isLocalizedEdgeColor = ParseCommonEdgeColors(obj, commonColor);
8764         colorProperty.topColor = commonColor.top;
8765         colorProperty.bottomColor = commonColor.bottom;
8766         if (isLocalizedEdgeColor) {
8767             colorProperty.startColor = commonColor.left;
8768             colorProperty.endColor = commonColor.right;
8769         } else {
8770             colorProperty.leftColor = commonColor.left;
8771             colorProperty.rightColor = commonColor.right;
8772         }
8773         colorProperty.multiValued = true;
8774         return true;
8775     }
8776     return false;
8777 }
8778 
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)8779 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
8780 {
8781     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8782         return false;
8783     }
8784     CalcDimension borderWidth;
8785     if (ParseJsDimensionVpNG(args, borderWidth, true)) {
8786         if (borderWidth.IsNegative()) {
8787             borderWidth.Reset();
8788         }
8789         borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth,
8790             std::nullopt, std::nullopt});
8791         return true;
8792     } else if (args->IsObject()) {
8793         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
8794         CommonCalcDimension commonCalcDimension;
8795         ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
8796         borderWidthProperty.topDimen = commonCalcDimension.top;
8797         borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
8798         borderWidthProperty.leftDimen = commonCalcDimension.left;
8799         borderWidthProperty.rightDimen = commonCalcDimension.right;
8800         borderWidthProperty.multiValued = true;
8801         return true;
8802     }
8803     return false;
8804 }
8805 
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)8806 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
8807 {
8808     if (!args->IsObject() && !args->IsNumber()) {
8809         return false;
8810     }
8811     if (args->IsObject()) {
8812         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
8813         auto leftValue = obj->GetProperty("left");
8814         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
8815             ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
8816         }
8817         auto rightValue = obj->GetProperty("right");
8818         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
8819             ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
8820         }
8821         auto topValue = obj->GetProperty("top");
8822         if (!topValue->IsUndefined() && topValue->IsNumber()) {
8823             ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
8824         }
8825         auto bottomValue = obj->GetProperty("bottom");
8826         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
8827             ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
8828         }
8829         borderStyleProperty.multiValued = true;
8830         return true;
8831     }
8832     std::optional<BorderStyle> borderStyle;
8833     if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
8834         borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
8835         return true;
8836     }
8837     return false;
8838 }
8839 
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)8840 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
8841 {
8842     std::optional<CalcDimension> radiusTopLeft;
8843     std::optional<CalcDimension> radiusTopRight;
8844     std::optional<CalcDimension> radiusBottomLeft;
8845     std::optional<CalcDimension> radiusBottomRight;
8846     CalcDimension topLeft;
8847     if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
8848         radiusTopLeft = topLeft;
8849     }
8850     CalcDimension topRight;
8851     if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
8852         radiusTopRight = topRight;
8853     }
8854     CalcDimension bottomLeft;
8855     if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
8856         radiusBottomLeft = bottomLeft;
8857     }
8858     CalcDimension bottomRight;
8859     if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
8860         radiusBottomRight = bottomRight;
8861     }
8862     CheckLengthMetrics(object);
8863     radius.radiusTopLeft = radiusTopLeft;
8864     radius.radiusTopRight = radiusTopRight;
8865     radius.radiusBottomLeft = radiusBottomLeft;
8866     radius.radiusBottomRight = radiusBottomRight;
8867     radius.multiValued = true;
8868     return;
8869 }
8870 
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)8871 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
8872 {
8873     if (CheckLengthMetrics(object)) {
8874         std::optional<CalcDimension> radiusTopStart;
8875         std::optional<CalcDimension> radiusTopEnd;
8876         std::optional<CalcDimension> radiusBottomStart;
8877         std::optional<CalcDimension> radiusBottomEnd;
8878         if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
8879             JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
8880             CalcDimension calcDimension;
8881             if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
8882                 CheckDimensionUnit(calcDimension, false, true);
8883                 radiusTopStart = calcDimension;
8884             }
8885         }
8886         if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
8887             JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
8888             CalcDimension calcDimension;
8889             if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
8890                 CheckDimensionUnit(calcDimension, false, true);
8891                 radiusTopEnd = calcDimension;
8892             }
8893         }
8894         if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
8895             JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
8896             CalcDimension calcDimension;
8897             if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
8898                 CheckDimensionUnit(calcDimension, false, true);
8899                 radiusBottomStart = calcDimension;
8900             }
8901         }
8902         if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
8903             JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
8904             CalcDimension calcDimension;
8905             if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
8906                 CheckDimensionUnit(calcDimension, false, true);
8907                 radiusBottomEnd = calcDimension;
8908             }
8909         }
8910         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
8911         radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
8912         radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
8913         radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
8914         radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
8915         radius.multiValued = true;
8916         return;
8917     }
8918     ParseBorderRadiusProps(object, radius);
8919 }
8920 
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)8921 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
8922 {
8923     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8924         return false;
8925     }
8926     CalcDimension borderRadius;
8927     if (ParseJsDimensionVpNG(args, borderRadius, true)) {
8928         radius = NG::BorderRadiusProperty(borderRadius);
8929         radius.multiValued = false;
8930     } else if (args->IsObject()) {
8931         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
8932         ParseCommonBorderRadiusProps(object, radius);
8933     } else {
8934         return false;
8935     }
8936     return true;
8937 }
8938 
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)8939 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
8940 {
8941     JSRef<JSVal> arg = info[0];
8942     if (!arg->IsObject()) {
8943         return;
8944     }
8945     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
8946     auto vm = info.GetVm();
8947     auto globalObj = JSNApi::GetGlobalObject(vm);
8948     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
8949     JsiValue jsiValue(globalFunc);
8950     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
8951     if (globalFuncRef->IsFunction()) {
8952         auto modifierObj = obj->GetProperty("modifier");
8953         if (modifierObj->IsUndefined()) {
8954             option.onApply = nullptr;
8955         } else {
8956             RefPtr<JsFunction> jsFunc =
8957                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
8958             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
8959                                modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
8960                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8961                 auto node = frameNode.Upgrade();
8962                 JSRef<JSVal> params[SECOND_INDEX];
8963                 params[0] = modifier;
8964                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
8965                 PipelineContext::SetCallBackNode(node);
8966                 func->ExecuteJS(SECOND_INDEX, params);
8967             };
8968             option.onApply = onApply;
8969         }
8970     }
8971 }
8972 
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)8973 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
8974 {
8975     if (!info[0]->IsObject()) {
8976         return;
8977     }
8978     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
8979     auto numberBadge = obj->GetProperty("numberBadge");
8980     if (!numberBadge->IsEmpty()) {
8981         if (numberBadge->IsNumber()) {
8982             int64_t number = numberBadge->ToNumber<int64_t>();
8983             if (number < 0 || number > INT_MAX) {
8984                 option.isNumber = false;
8985                 option.isShowBadge = true;
8986             } else {
8987                 option.isNumber = true;
8988                 option.badgeNumber = numberBadge->ToNumber<int>();
8989             }
8990         } else if (numberBadge->IsBoolean()) {
8991             option.isNumber = false;
8992             option.isShowBadge = numberBadge->ToBoolean();
8993         }
8994     } else {
8995         option.isNumber = false;
8996         option.isShowBadge = true;
8997     }
8998 }
8999 
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)9000 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
9001 {
9002     // Parse cornerRadius.
9003     auto cornerRadiusValue = obj->GetProperty("cornerRadius");
9004     NG::BorderRadiusProperty radius;
9005     if (ParseBorderRadius(cornerRadiusValue, radius)) {
9006         properties.borderRadius = radius;
9007     }
9008     // Parse border width
9009     auto borderWidthValue = obj->GetProperty("borderWidth");
9010     NG::BorderWidthProperty borderWidth;
9011     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
9012         properties.borderWidth = borderWidth;
9013         auto colorValue = obj->GetProperty("borderColor");
9014         NG::BorderColorProperty borderColor;
9015         if (ParseBorderColorProps(colorValue, borderColor)) {
9016             properties.borderColor = borderColor;
9017         } else {
9018             borderColor.SetColor(Color::BLACK);
9019             properties.borderColor = borderColor;
9020         }
9021         // Parse border style
9022         auto styleValue = obj->GetProperty("borderStyle");
9023         NG::BorderStyleProperty borderStyle;
9024         if (ParseBorderStyleProps(styleValue, borderStyle)) {
9025             properties.borderStyle = borderStyle;
9026         } else {
9027             properties.borderStyle = NG::BorderStyleProperty(
9028                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
9029         }
9030     }
9031     auto shadowValue = obj->GetProperty("shadow");
9032     Shadow shadow;
9033     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
9034         properties.shadow = shadow;
9035     }
9036     auto widthValue = obj->GetProperty("width");
9037     CalcDimension width;
9038     if (ParseJsDimensionVpNG(widthValue, width, true)) {
9039         properties.width = width;
9040     }
9041     auto heightValue = obj->GetProperty("height");
9042     CalcDimension height;
9043     if (ParseJsDimensionVpNG(heightValue, height, true)) {
9044         properties.height = height;
9045     }
9046 }
9047 
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx,JSRef<JSObject> modifier)9048 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
9049     const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx, JSRef<JSObject> modifier)
9050 {
9051     std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx, modifier](
9052                                                                          NG::DrawingContext& context) -> void {
9053         JAVASCRIPT_EXECUTION_SCOPE(execCtx);
9054         if (modifier->IsEmpty()) {
9055             return;
9056         }
9057         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
9058         objectTemplate->SetInternalFieldCount(1);
9059         JSRef<JSObject> contextObj = objectTemplate->NewInstance();
9060         JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
9061         sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
9062         sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
9063         contextObj->SetPropertyObject("size", sizeObj);
9064 
9065         JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
9066         sizeInPxObj->SetProperty<float>("height", context.height);
9067         sizeInPxObj->SetProperty<float>("width", context.width);
9068         contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
9069 
9070         auto engine = EngineHelper::GetCurrentEngine();
9071         CHECK_NULL_VOID(engine);
9072         NativeEngine* nativeEngine = engine->GetNativeEngine();
9073         napi_env env = reinterpret_cast<napi_env>(nativeEngine);
9074         ScopeRAII scope(env);
9075 
9076         auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
9077         OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
9078         napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
9079         if (unwrapCanvas) {
9080             unwrapCanvas->SaveCanvas();
9081             unwrapCanvas->ClipCanvas(context.width, context.height);
9082         }
9083         JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
9084         contextObj->SetPropertyObject("canvas", jsCanvasVal);
9085 
9086         auto jsVal = JSRef<JSVal>::Cast(contextObj);
9087         panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
9088         JSValueWrapper valueWrapper = value;
9089         napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
9090 
9091         napi_wrap(
9092             env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
9093 
9094         JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
9095         if (unwrapCanvas) {
9096             unwrapCanvas->RestoreCanvas();
9097             unwrapCanvas->ResetCanvas();
9098         }
9099     };
9100     return drawCallback;
9101 }
9102 
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)9103 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
9104 {
9105     auto* vm = info.GetVm();
9106     return [vm, nodeId](const std::string& key) -> std::string {
9107         std::string resultString = std::string();
9108         CHECK_NULL_RETURN(vm, resultString);
9109         panda::LocalScope scope(vm);
9110         auto global = JSNApi::GetGlobalObject(vm);
9111         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
9112         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
9113             return resultString;
9114         }
9115         auto obj = getCustomProperty->ToObject(vm);
9116         panda::Local<panda::FunctionRef> func = obj;
9117         panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
9118             panda::StringRef::NewFromUtf8(vm, key.c_str()) };
9119         auto function = panda::CopyableGlobal(vm, func);
9120         auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
9121         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
9122             return resultString;
9123         }
9124         auto value = callValue->ToString(vm)->ToString(vm);
9125         return value;
9126     };
9127 }
9128 
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)9129 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
9130 {
9131     auto* vm = info.GetVm();
9132     panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
9133         info[1]->GetLocalHandle() };
9134     return [vm, params3]() -> bool {
9135         CHECK_NULL_RETURN(vm, false);
9136         panda::LocalScope scope(vm);
9137         auto global = JSNApi::GetGlobalObject(vm);
9138         auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
9139         if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
9140             return false;
9141         }
9142         auto obj = setCustomProperty->ToObject(vm);
9143         panda::Local<panda::FunctionRef> func = obj;
9144         auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9145         auto nodeId = frameNode->GetId();
9146         auto function = panda::CopyableGlobal(vm, func);
9147         auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
9148         if (customPropertyExisted) {
9149             frameNode->SetCustomPropertyMapFlagByKey(params3[1]->ToString(vm)->ToString(vm));
9150             frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
9151                 CHECK_NULL_VOID(vm);
9152                 panda::LocalScope scope(vm);
9153                 auto global = JSNApi::GetGlobalObject(vm);
9154                 auto removeCustomProperty =
9155                     global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
9156                 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
9157                     return;
9158                 }
9159                 auto obj = removeCustomProperty->ToObject(vm);
9160                 panda::Local<panda::FunctionRef> func = obj;
9161                 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
9162                 auto function = panda::CopyableGlobal(vm, func);
9163                 function->Call(vm, function.ToLocal(), params, 1);
9164             });
9165         }
9166         return true;
9167     };
9168 }
9169 
JsCustomProperty(const JSCallbackInfo & info)9170 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
9171 {
9172     if (info[0]->GetLocalHandle()->IsUndefined()) {
9173         return;
9174     }
9175     auto* vm = info.GetVm();
9176     CHECK_NULL_VOID(vm);
9177     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9178     auto nodeId = frameNode->GetId();
9179     auto getFunc = ParseJsGetFunc(info, nodeId);
9180     auto func = ParseJsFunc(info, nodeId);
9181     frameNode->SetJSCustomProperty(func, getFunc);
9182 }
9183 
JsLinearGradient(const JSCallbackInfo & info)9184 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
9185 {
9186     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
9187     auto jsVal = info[0];
9188     if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
9189         NG::Gradient newGradient;
9190         newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
9191         ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
9192         return;
9193     }
9194     NG::Gradient newGradient;
9195     NewJsLinearGradient(info, newGradient);
9196     ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
9197 }
9198 
JsGestureModifier(const JSCallbackInfo & info)9199 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
9200 {
9201     auto* vm = info.GetExecutionContext().vm_;
9202     CHECK_NULL_VOID(vm);
9203     auto global = JSNApi::GetGlobalObject(vm);
9204     auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
9205     if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
9206         return;
9207     }
9208     auto obj = gestureModifier->ToObject(vm);
9209     panda::Local<panda::FunctionRef> func = obj;
9210     auto thisObj = info.This()->GetLocalHandle();
9211     panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
9212     func->Call(vm, thisObj, params, 1);
9213 }
9214 
JsBackgroundImageResizable(const JSCallbackInfo & info)9215 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
9216 {
9217     auto infoObj = info[0];
9218     ImageResizableSlice sliceResult;
9219     if (!infoObj->IsObject()) {
9220         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9221         return;
9222     }
9223     JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
9224     if (resizableObject->IsEmpty()) {
9225         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9226         return;
9227     }
9228     auto sliceValue = resizableObject->GetProperty("slice");
9229     if (!sliceValue->IsObject()) {
9230         return;
9231     }
9232     JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
9233     if (sliceObj->IsEmpty()) {
9234         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9235         return;
9236     }
9237     for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
9238         auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
9239         CalcDimension sliceDimension;
9240         if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
9241             continue;
9242         }
9243         if (!sliceDimension.IsValid()) {
9244             continue;
9245         }
9246         switch (static_cast<BorderImageDirection>(i)) {
9247             case BorderImageDirection::LEFT:
9248                 sliceResult.left = sliceDimension;
9249                 break;
9250             case BorderImageDirection::RIGHT:
9251                 sliceResult.right = sliceDimension;
9252                 break;
9253             case BorderImageDirection::TOP:
9254                 sliceResult.top = sliceDimension;
9255                 break;
9256             case BorderImageDirection::BOTTOM:
9257                 sliceResult.bottom = sliceDimension;
9258                 break;
9259             default:
9260                 break;
9261         }
9262     }
9263     ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9264 }
9265 
JsOnFocus(const JSCallbackInfo & args)9266 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
9267 {
9268     JSRef<JSVal> arg = args[0];
9269     if (arg->IsUndefined() && IsDisableEventVersion()) {
9270         ViewAbstractModel::GetInstance()->DisableOnFocus();
9271         return;
9272     }
9273     if (!arg->IsFunction()) {
9274         return;
9275     }
9276     RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
9277     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9278     auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
9279         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9280         ACE_SCORING_EVENT("onFocus");
9281         PipelineContext::SetCallBackNode(node);
9282         func->Execute();
9283     };
9284 
9285     ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
9286 }
9287 
JsOnBlur(const JSCallbackInfo & args)9288 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
9289 {
9290     JSRef<JSVal> arg = args[0];
9291     if (arg->IsUndefined() && IsDisableEventVersion()) {
9292         ViewAbstractModel::GetInstance()->DisableOnBlur();
9293         return;
9294     }
9295     if (!arg->IsFunction()) {
9296         return;
9297     }
9298     RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
9299     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9300     auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
9301         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9302         ACE_SCORING_EVENT("onBlur");
9303         PipelineContext::SetCallBackNode(node);
9304         func->Execute();
9305     };
9306 
9307     ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
9308 }
9309 
JsTabIndex(const JSCallbackInfo & info)9310 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
9311 {
9312     JSRef<JSVal> arg = info[0];
9313     if (!arg->IsNumber()) {
9314         return;
9315     }
9316     ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
9317 }
9318 
JsFocusOnTouch(const JSCallbackInfo & info)9319 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
9320 {
9321     JSRef<JSVal> arg = info[0];
9322     if (!arg->IsBoolean()) {
9323         return;
9324     }
9325     auto isFocusOnTouch = arg->ToBoolean();
9326     ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
9327 }
9328 
JsDefaultFocus(const JSCallbackInfo & info)9329 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
9330 {
9331     JSRef<JSVal> arg = info[0];
9332     if (!arg->IsBoolean()) {
9333         return;
9334     }
9335     auto isDefaultFocus = arg->ToBoolean();
9336     ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
9337 }
9338 
JsGroupDefaultFocus(const JSCallbackInfo & info)9339 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
9340 {
9341     JSRef<JSVal> arg = info[0];
9342     if (!arg->IsBoolean()) {
9343         return;
9344     }
9345     auto isGroupDefaultFocus = arg->ToBoolean();
9346     ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
9347 }
9348 
JsKey(const std::string & key)9349 void JSViewAbstract::JsKey(const std::string& key)
9350 {
9351     ViewAbstractModel::GetInstance()->SetInspectorId(key);
9352 }
9353 
JsId(const JSCallbackInfo & info)9354 void JSViewAbstract::JsId(const JSCallbackInfo& info)
9355 {
9356     JSRef<JSVal> arg = info[0];
9357     if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
9358         return;
9359     }
9360     std::string id = arg->ToString();
9361     if (id.empty()) {
9362         return;
9363     }
9364     JsKey(id);
9365 }
9366 
JsRestoreId(int32_t restoreId)9367 void JSViewAbstract::JsRestoreId(int32_t restoreId)
9368 {
9369     ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
9370 }
9371 
JsDebugLine(const JSCallbackInfo & info)9372 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
9373 {
9374     std::string debugLine;
9375     auto length = info.Length();
9376     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
9377 
9378     if (length == 1) { // deprecated version of debug line
9379         auto jsVal = info[0];
9380         if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
9381             return;
9382         }
9383         debugLine = jsVal->ToString();
9384     } else if (length == 2) { // debug line with extra package name
9385         auto line = info[0];
9386         auto packageName = info[1];
9387         if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
9388             !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
9389             return;
9390         }
9391         auto json = JsonUtil::Create(true);
9392         json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
9393         json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
9394         debugLine = json->ToString();
9395     }
9396 
9397     ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
9398 }
9399 
JsOpacityPassThrough(const JSCallbackInfo & info)9400 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
9401 {
9402     double opacity = 1.0;
9403     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
9404         if (ParseJsDouble(info[0], opacity)) {
9405             opacity = std::clamp(opacity, 0.0, 1.0);
9406         }
9407     } else {
9408         if (!ParseJsDouble(info[0], opacity)) {
9409             return;
9410         }
9411         if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
9412             opacity = 1.0;
9413         }
9414     }
9415 
9416     ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
9417 }
9418 
JsTransitionPassThrough(const JSCallbackInfo & info)9419 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
9420 {
9421     if (info.Length() == 0) {
9422         ViewAbstractModel::GetInstance()->SetTransition(
9423             NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
9424         return;
9425     }
9426     if (!info[0]->IsObject()) {
9427         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
9428             ViewAbstractModel::GetInstance()->CleanTransition();
9429             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
9430         }
9431         return;
9432     }
9433     auto obj = JSRef<JSObject>::Cast(info[0]);
9434     if (!obj->GetProperty("successor_")->IsUndefined()) {
9435         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
9436         std::function<void(bool)> finishCallback;
9437         if (info.Length() > 1 && info[1]->IsFunction()) {
9438             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
9439         }
9440         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
9441         return;
9442     }
9443     auto options = ParseJsTransition(obj);
9444     ViewAbstractModel::GetInstance()->SetTransition(options, true);
9445 }
9446 
JsFocusScopeId(const JSCallbackInfo & info)9447 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
9448 {
9449     if (info.Length() == 0) {
9450         return;
9451     }
9452 
9453     std::string focusScopeId;
9454     if (info[0]->IsString()) {
9455         focusScopeId = info[0]->ToString();
9456     }
9457 
9458     bool isGroup = false;
9459     if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
9460         info[1]->IsBoolean()) {
9461         isGroup = info[1]->ToBoolean();
9462     }
9463     bool arrowKeyStepOut = true;
9464     if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() && // 2:args index.
9465         info[2]->IsBoolean()) { // 2:args index.
9466         arrowKeyStepOut = info[2]->ToBoolean(); // 2:args index.
9467     }
9468     ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
9469 }
9470 
JsFocusScopePriority(const JSCallbackInfo & info)9471 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
9472 {
9473     if (info.Length() == 0) {
9474         return;
9475     }
9476 
9477     if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
9478         return;
9479     }
9480     std::string focusScopeId = info[0]->ToString();
9481 
9482     int32_t focusPriority = 0;
9483     if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
9484         info[1]->IsNumber()) {
9485         focusPriority = info[1]->ToNumber<int32_t>();
9486     }
9487     ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
9488 }
9489 
JsBackground(const JSCallbackInfo & info)9490 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
9491 {
9492     // Check the parameters
9493     if (info.Length() <= 0 || !info[0]->IsObject()) {
9494         return;
9495     }
9496     JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
9497     auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
9498     if (!builder->IsFunction()) {
9499         return;
9500     }
9501     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9502     CHECK_NULL_VOID(builderFunc);
9503     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9504     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
9505         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9506         ACE_SCORING_EVENT("BindBackground");
9507         PipelineContext::SetCallBackNode(node);
9508         func->Execute();
9509     };
9510     Alignment alignment = Alignment::CENTER;
9511     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
9512         JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
9513         auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
9514         auto value = align->ToNumber<int32_t>();
9515         alignment = ParseAlignment(value);
9516     }
9517     ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
9518 }
9519 
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)9520 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
9521     std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
9522 {
9523     auto vm = info.GetVm();
9524     auto globalObj = JSNApi::GetGlobalObject(vm);
9525     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
9526     JsiValue jsiValue(globalFunc);
9527     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
9528     if (globalFuncRef->IsFunction()) {
9529         RefPtr<JsFunction> jsFunc =
9530             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
9531         if (!modifierObj->IsObject()) {
9532             symbolApply = nullptr;
9533         } else {
9534             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
9535                                modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
9536                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9537                 auto node = frameNode.Upgrade();
9538                 CHECK_NULL_VOID(node);
9539                 JSRef<JSVal> params[2];
9540                 params[0] = modifierParam;
9541                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
9542                 PipelineContext::SetCallBackNode(node);
9543                 func->ExecuteJS(2, params);
9544             };
9545             symbolApply = onApply;
9546         }
9547     }
9548 }
9549 
ParseJsPropertyId(const JSRef<JSVal> & jsValue)9550 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
9551 {
9552     int32_t resId = 0;
9553     if (jsValue->IsObject()) {
9554         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9555         JSRef<JSVal> tmp = jsObj->GetProperty("id");
9556         if (!tmp->IsNull() && tmp->IsNumber()) {
9557             resId = tmp->ToNumber<int32_t>();
9558         }
9559     }
9560     return resId;
9561 }
9562 
JsVisualEffect(const JSCallbackInfo & info)9563 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
9564 {
9565     if (!info[0]->IsObject()) {
9566         return;
9567     }
9568     auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
9569     ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
9570 }
9571 
JsBackgroundFilter(const JSCallbackInfo & info)9572 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
9573 {
9574     if (!info[0]->IsObject()) {
9575         return;
9576     }
9577     auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
9578     ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
9579 }
9580 
JsForegroundFilter(const JSCallbackInfo & info)9581 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
9582 {
9583     if (!info[0]->IsObject()) {
9584         return;
9585     }
9586     auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
9587     ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
9588 }
9589 
JsCompositingFilter(const JSCallbackInfo & info)9590 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
9591 {
9592     if (!info[0]->IsObject()) {
9593         return;
9594     }
9595     auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
9596     ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
9597 }
9598 
ParseMenuItems(const JSRef<JSArray> & menuItemsArray)9599 std::vector<NG::MenuOptionsParam> JSViewAbstract::ParseMenuItems(const JSRef<JSArray>& menuItemsArray)
9600 {
9601     std::vector<NG::MenuOptionsParam> menuParams;
9602     for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
9603         auto menuItem = menuItemsArray->GetValueAt(i);
9604         if (!menuItem->IsObject()) {
9605             continue;
9606         }
9607         auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
9608         NG::MenuOptionsParam menuOptionsParam;
9609         auto jsContent = menuItemObject->GetProperty("content");
9610         std::string content;
9611         ParseJsString(jsContent, content);
9612         menuOptionsParam.content = content;
9613         auto jsStartIcon = menuItemObject->GetProperty("icon");
9614         std::string icon;
9615         ParseJsMedia(jsStartIcon, icon);
9616         menuOptionsParam.icon = icon;
9617         auto jsTextMenuId = menuItemObject->GetProperty("id");
9618         std::string id;
9619         if (jsTextMenuId->IsObject()) {
9620             auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
9621             auto jsId = textMenuIdObject->GetProperty("id_");
9622             ParseJsString(jsId, id);
9623         }
9624         menuOptionsParam.id = id;
9625         auto jsLabelInfo = menuItemObject->GetProperty("labelInfo");
9626         std::string labelInfo;
9627         ParseJsString(jsLabelInfo, labelInfo);
9628         if (jsLabelInfo->IsString() || jsLabelInfo->IsObject()) {
9629             menuOptionsParam.labelInfo = labelInfo;
9630         }
9631         menuParams.emplace_back(menuOptionsParam);
9632     }
9633     return menuParams;
9634 }
9635 
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)9636 void JSViewAbstract::ParseOnCreateMenu(
9637     const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
9638 {
9639     if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
9640         return;
9641     }
9642     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9643     auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
9644         JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
9645     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
9646                           instanceId = Container::CurrentId(), node = frameNode](
9647                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
9648         ContainerScope scope(instanceId);
9649         std::vector<NG::MenuOptionsParam> menuParams;
9650         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
9651         auto pipelineContext = PipelineContext::GetCurrentContext();
9652         CHECK_NULL_RETURN(pipelineContext, menuParams);
9653         pipelineContext->UpdateCurrentActiveNode(node);
9654         auto modifiedSystemMenuItems = systemMenuItems;
9655         UpdateOptionsLabelInfo(modifiedSystemMenuItems);
9656         auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
9657         if (!menuItem->IsArray()) {
9658             return menuParams;
9659         }
9660         auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
9661         menuParams = ParseMenuItems(menuItemsArray);
9662         return menuParams;
9663     };
9664     onCreateMenuCallback = jsCallback;
9665 }
9666 
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)9667 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
9668 {
9669     JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
9670     uint32_t idx = 0;
9671     for (const auto& item : systemMenuItems) {
9672         systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
9673     }
9674     return systemMenuItemsArray;
9675 }
9676 
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)9677 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
9678     NG::OnMenuItemClickCallback& onMenuItemClick)
9679 {
9680     auto tmpInfo = info[0];
9681     if (info.Length() != 1 || !tmpInfo->IsObject()) {
9682         return false;
9683     }
9684     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9685     auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
9686     auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
9687     ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
9688 
9689     auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
9690     if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
9691         return false;
9692     }
9693     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
9694     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
9695                           onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
9696                           node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
9697         ContainerScope scope(instanceId);
9698         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
9699         auto pipelineContext = PipelineContext::GetCurrentContext();
9700         CHECK_NULL_RETURN(pipelineContext, false);
9701         pipelineContext->UpdateCurrentActiveNode(node);
9702         auto paramArray = onMenuItemCallback(menuOptionsParam);
9703         if (paramArray->Length() != 2) {
9704             return false;
9705         }
9706         JSRef<JSVal> params[2];
9707         params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
9708         params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
9709         auto ret = func->ExecuteJS(2, params);
9710         if (ret->IsBoolean()) {
9711             return ret->ToBoolean();
9712         }
9713         return false;
9714     };
9715     onMenuItemClick = jsCallback;
9716     return true;
9717 }
9718 
CreateJsTextMenuId(const std::string & id)9719 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
9720 {
9721     JSRef<JSObject> empty;
9722     auto engine = EngineHelper::GetCurrentEngine();
9723     CHECK_NULL_RETURN(engine, empty);
9724     NativeEngine* nativeEngine = engine->GetNativeEngine();
9725     CHECK_NULL_RETURN(nativeEngine, empty);
9726     auto env = reinterpret_cast<napi_env>(nativeEngine);
9727 
9728     napi_value global;
9729     napi_status ret = napi_get_global(env, &global);
9730     if (ret != napi_ok) {
9731         return empty;
9732     }
9733     napi_value constructor;
9734     ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
9735     if (ret != napi_ok) {
9736         return empty;
9737     }
9738 
9739     napi_value obj;
9740     napi_value menuId = nullptr;
9741 
9742     ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
9743     if (ret != napi_ok) {
9744         return empty;
9745     }
9746     ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
9747     if (ret != napi_ok) {
9748         return empty;
9749     }
9750 
9751     JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
9752     if (!value->IsObject()) {
9753         return empty;
9754     }
9755 
9756     return JSRef<JSObject>::Cast(value);
9757 }
9758 
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)9759 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
9760 {
9761     JSRef<JSArray> params = JSRef<JSArray>::New();
9762     params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
9763     params->SetValueAt(1, CreateJsTextRange(menuItemParam));
9764     return params;
9765 }
9766 
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)9767 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
9768 {
9769     JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
9770     TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
9771     JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
9772     TextMenuItem->SetPropertyObject("id", obj);
9773     TextMenuItem->SetProperty<std::string>("labelInfo", menuItemParam.menuOptionsParam.labelInfo.value_or(""));
9774     return JSRef<JSVal>::Cast(TextMenuItem);
9775 }
9776 
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)9777 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
9778 {
9779     JSRef<JSObject> textRange = JSRef<JSObject>::New();
9780     textRange->SetProperty<int32_t>("start", menuItemParam.start);
9781     textRange->SetProperty<int32_t>("end", menuItemParam.end);
9782     return JSRef<JSVal>::Cast(textRange);
9783 }
9784 
OHOS_ACE_ParseJsMedia(void * value,void * resource)9785 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
9786 {
9787     napi_value napiValue = reinterpret_cast<napi_value>(value);
9788     ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
9789     if (!napiValue || !res) {
9790         return;
9791     }
9792     JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
9793     std::string src;
9794     std::string bundleName;
9795     std::string moduleName;
9796     JSViewAbstract::ParseJsMedia(jsVal, src);
9797     JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
9798     res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
9799     res->src = src;
9800     res->bundleName = bundleName;
9801     res->moduleName = moduleName;
9802 }
9803 
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)9804 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
9805     std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
9806 {
9807     if (!modifierObj->IsObject()) {
9808         textStyleApply = nullptr;
9809         return;
9810     }
9811     auto vm = info.GetVm();
9812     auto globalObj = JSNApi::GetGlobalObject(vm);
9813     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
9814     JsiValue jsiValue(globalFunc);
9815     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
9816     if (!globalFuncRef->IsFunction()) {
9817         textStyleApply = nullptr;
9818         return;
9819     }
9820     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
9821     auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
9822                     modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
9823         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9824         auto node = frameNode.Upgrade();
9825         CHECK_NULL_VOID(node);
9826         JSRef<JSVal> params[2];
9827         params[0] = modifierParam;
9828         params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
9829         PipelineContext::SetCallBackNode(node);
9830         func->ExecuteJS(2, params);
9831     };
9832     textStyleApply = onApply;
9833 }
9834 
SetPixelRoundMode(const JSCallbackInfo & info)9835 void JSViewAbstract::SetPixelRoundMode(const JSCallbackInfo& info)
9836 {
9837     if (info.Length() < 1) {
9838         return;
9839     }
9840     if (!info[0]->IsNumber()) {
9841         return;
9842     }
9843     auto index = info[0]->ToNumber<uint8_t>();
9844     auto size = sizeof(PixelRoundMode) / sizeof(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
9845     if (index < 0 || index > size) {
9846         return;
9847     }
9848     PixelRoundMode pixelRoundMode = static_cast<PixelRoundMode>(index);
9849     auto pipeline = PipelineBase::GetCurrentContext();
9850     CHECK_NULL_VOID(pipeline);
9851     pipeline->SetPixelRoundMode(pixelRoundMode);
9852 }
9853 
GetPixelRoundMode()9854 uint8_t JSViewAbstract::GetPixelRoundMode()
9855 {
9856     auto pipeline = PipelineBase::GetCurrentContext();
9857     return pipeline ? static_cast<uint8_t>(pipeline->GetPixelRoundMode())
9858                     : static_cast<uint8_t>(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
9859 }
9860 } // namespace OHOS::Ace::Framework
9861